diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 3559874..82402f5 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -3,6 +3,12 @@ on: push: pull_request: types: [opened, synchronize] + workflow_dispatch: + inputs: + debug_enabled: + description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' + required: false + default: false jobs: build-docs: runs-on: ubuntu-20.04 @@ -16,32 +22,39 @@ jobs: uses: actions/setup-python@v2 with: python-version: "3.7" + # Allow debugging with tmate + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} + with: + limit-access-to-actor: true - uses: actions/cache@v2 id: cache with: path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-docs + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-root-docs - name: Install poetry if: steps.cache.outputs.cache-hit != 'true' + # TODO: remove python -m pip install --force git+https://github.com/python-poetry/poetry-core.git@ad33bc2 + # once there's a release of Poetry 1.2.x including poetry-core > 1.1.0a6 + # Ref: https://github.com/python-poetry/poetry-core/pull/188 run: | python -m pip install --upgrade pip - python -m pip install "poetry>=1.2.0a1" - python -m poetry plugin add poetry-version-plugin + python -m pip install --force git+https://github.com/python-poetry/poetry-core.git@ad33bc2 + python -m pip install "poetry==1.2.0a2" + python -m poetry plugin add poetry-version-plugin - name: Configure poetry - run: python -m poetry config virtualenvs.in-project true - - name: Ensure cache is healthy - if: steps.cache.outputs.cache-hit == 'true' - run: python -m poetry run pip --version >/dev/null 2>&1 || rm -rf .venv + run: python -m poetry config virtualenvs.create false - name: Install Dependencies if: steps.cache.outputs.cache-hit != 'true' run: python -m poetry install - name: Install Material for MkDocs Insiders if: github.event.pull_request.head.repo.fork == false && steps.cache.outputs.cache-hit != 'true' - run: pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git + run: python -m poetry run pip install git+https://${{ secrets.ACTIONS_TOKEN }}@github.com/squidfunk/mkdocs-material-insiders.git - name: Build Docs - run: python3.7 -m mkdocs build + run: python -m poetry run mkdocs build - name: Zip docs - run: bash ./scripts/zip-docs.sh + run: python -m poetry run bash ./scripts/zip-docs.sh - uses: actions/upload-artifact@v2 with: name: docs-zip diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index c75ecc0..105dbdd 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -4,6 +4,12 @@ on: release: types: - created + workflow_dispatch: + inputs: + debug_enabled: + description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' + required: false + default: false jobs: publish: @@ -14,22 +20,29 @@ jobs: uses: actions/setup-python@v2 with: python-version: "3.7" + # Allow debugging with tmate + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} + with: + limit-access-to-actor: true - uses: actions/cache@v2 id: cache with: path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-root - name: Install poetry if: steps.cache.outputs.cache-hit != 'true' + # TODO: remove python -m pip install --force git+https://github.com/python-poetry/poetry-core.git@ad33bc2 + # once there's a release of Poetry 1.2.x including poetry-core > 1.1.0a6 + # Ref: https://github.com/python-poetry/poetry-core/pull/188 run: | python -m pip install --upgrade pip - python -m pip install "poetry>=1.2.0a1" - python -m poetry plugin add poetry-version-plugin + python -m pip install --force git+https://github.com/python-poetry/poetry-core.git@ad33bc2 + python -m pip install "poetry==1.2.0a2" + python -m poetry plugin add poetry-version-plugin - name: Configure poetry - run: python -m poetry config virtualenvs.in-project true - - name: Ensure cache is healthy - if: steps.cache.outputs.cache-hit == 'true' - run: python -m poetry run pip --version >/dev/null 2>&1 || rm -rf .venv + run: python -m poetry config virtualenvs.create false - name: Install Dependencies if: steps.cache.outputs.cache-hit != 'true' run: python -m poetry install diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index aa60d7f..6e15a7d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,6 +4,12 @@ on: push: pull_request: types: [opened, synchronize] + workflow_dispatch: + inputs: + debug_enabled: + description: 'Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)' + required: false + default: false jobs: test: @@ -19,26 +25,36 @@ jobs: uses: actions/setup-python@v2 with: python-version: ${{ matrix.python-version }} + # Allow debugging with tmate + - name: Setup tmate session + uses: mxschmitt/action-tmate@v3 + if: ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.debug_enabled }} + with: + limit-access-to-actor: true - uses: actions/cache@v2 id: cache with: path: ${{ env.pythonLocation }} - key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-test + key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-root - name: Install poetry if: steps.cache.outputs.cache-hit != 'true' + # TODO: remove python -m pip install --force git+https://github.com/python-poetry/poetry-core.git@ad33bc2 + # once there's a release of Poetry 1.2.x including poetry-core > 1.1.0a6 + # Ref: https://github.com/python-poetry/poetry-core/pull/188 run: | python -m pip install --upgrade pip - python -m pip install "poetry>=1.2.0a1" - python -m poetry plugin add poetry-version-plugin + python -m pip install --force git+https://github.com/python-poetry/poetry-core.git@ad33bc2 + python -m pip install "poetry==1.2.0a2" + python -m poetry plugin add poetry-version-plugin - name: Configure poetry - run: python -m poetry config virtualenvs.in-project true - - name: Ensure cache is healthy - if: steps.cache.outputs.cache-hit == 'true' - run: python -m poetry run pip --version >/dev/null 2>&1 || rm -rf .venv + run: python -m poetry config virtualenvs.create false - name: Install Dependencies if: steps.cache.outputs.cache-hit != 'true' run: python -m poetry install + - name: Lint + if: ${{ matrix.python-version != '3.6' }} + run: python -m poetry run bash scripts/lint.sh - name: Test - run: bash scripts/test.sh + run: python -m poetry run bash scripts/test.sh - name: Upload coverage uses: codecov/codecov-action@v1 diff --git a/pyproject.toml b/pyproject.toml index c4599b5..e4d7a0e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -47,6 +47,9 @@ coverage = {extras = ["toml"], version = "^5.5"} fastapi = "^0.68.0" requests = "^2.26.0" autoflake = "^1.4" +isort = "^5.9.3" +async_generator = {version = "*", python = "~3.6"} +async-exit-stack = {version = "*", python = "~3.6"} [build-system] requires = ["poetry-core"] diff --git a/scripts/test.sh b/scripts/test.sh index 139c1fb..7fce865 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -6,3 +6,4 @@ set -x coverage run -m pytest tests coverage combine coverage report --show-missing +coverage xml diff --git a/scripts/zip-docs.sh b/scripts/zip-docs.sh new file mode 100644 index 0000000..f2b7ba3 --- /dev/null +++ b/scripts/zip-docs.sh @@ -0,0 +1,9 @@ +#! /usr/bin/env bash + +set -x +set -e + +if [ -f docs.zip ]; then + rm -rf docs.zip +fi +zip -r docs.zip ./site diff --git a/sqlmodel/main.py b/sqlmodel/main.py index dd38dd2..661276b 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -12,7 +12,6 @@ from typing import ( Callable, ClassVar, Dict, - ForwardRef, List, Mapping, Optional, @@ -30,7 +29,7 @@ from pydantic.errors import ConfigError, DictError from pydantic.fields import FieldInfo as PydanticFieldInfo from pydantic.fields import ModelField, Undefined, UndefinedType from pydantic.main import BaseConfig, ModelMetaclass, validate_model -from pydantic.typing import NoArgAnyCallable, resolve_annotations +from pydantic.typing import ForwardRef, NoArgAnyCallable, resolve_annotations from pydantic.utils import ROOT_KEY, Representation from sqlalchemy import ( Boolean, @@ -343,7 +342,7 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta): ) relationship_to = temp_field.type_ if isinstance(temp_field.type_, ForwardRef): - relationship_to = temp_field.type_.__forward_arg__ + relationship_to = temp_field.type_.__forward_arg__ # type: ignore rel_kwargs: Dict[str, Any] = {} if rel_info.back_populates: rel_kwargs["back_populates"] = rel_info.back_populates diff --git a/sqlmodel/orm/session.py b/sqlmodel/orm/session.py index a96544e..d708f1e 100644 --- a/sqlmodel/orm/session.py +++ b/sqlmodel/orm/session.py @@ -1,4 +1,4 @@ -from typing import Any, Mapping, Optional, Sequence, TypeVar, Union, overload +from typing import Any, Mapping, Optional, Sequence, Type, TypeVar, Union, overload from sqlalchemy import util from sqlalchemy.orm import Query as _Query @@ -118,13 +118,13 @@ class Session(_Session): def get( self, - entity: _T, + entity: Type[_T], ident: Any, options: Optional[Sequence[Any]] = None, populate_existing: bool = False, with_for_update: Optional[Union[Literal[True], Mapping[str, Any]]] = None, identity_token: Optional[Any] = None, - ) -> _T: + ) -> Optional[_T]: return super().get( entity, ident, diff --git a/sqlmodel/sql/expression.py b/sqlmodel/sql/expression.py index e8a922e..66063bf 100644 --- a/sqlmodel/sql/expression.py +++ b/sqlmodel/sql/expression.py @@ -45,10 +45,10 @@ else: class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore pass - class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): + class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore pass - class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): + class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore pass # Cast them for editors to work correctly, from several tricks tried, this works