From 1146032c1be2a529eea71a5e6473a526a5516c52 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 10:26:48 +0200 Subject: [PATCH 01/11] Try fixing ci job by updating to newer poetry version --- .github/workflows/build-docs.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 640069153..5f47c58ef 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -42,8 +42,7 @@ jobs: # Ref: https://github.com/python-poetry/poetry-core/pull/188 run: | python -m pip install --upgrade pip - 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 pip install "poetry==1.5.1" python -m poetry plugin add poetry-version-plugin - name: Configure poetry run: python -m poetry config virtualenvs.create false From 0035f60c4e1439cba18d26c1fa973d314d8b8c79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 10:35:36 +0200 Subject: [PATCH 02/11] Use newer plugin installation syntax --- .github/workflows/build-docs.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 5f47c58ef..3005e27bb 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -43,7 +43,7 @@ jobs: run: | python -m pip install --upgrade pip python -m pip install "poetry==1.5.1" - python -m poetry plugin add poetry-version-plugin + python -m poetry self add poetry-version-plugin - name: Configure poetry run: python -m poetry config virtualenvs.create false - name: Install Dependencies From 068c871d1eb6130b6b975e58b95b3de060e710d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 21:41:51 +0200 Subject: [PATCH 03/11] Remove use of version plugin --- .github/workflows/build-docs.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml index 3005e27bb..56bc2eaa4 100644 --- a/.github/workflows/build-docs.yml +++ b/.github/workflows/build-docs.yml @@ -37,13 +37,9 @@ jobs: 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.5.1" - python -m poetry self add poetry-version-plugin - name: Configure poetry run: python -m poetry config virtualenvs.create false - name: Install Dependencies From 3ac39b2b9a650d15031cdc37a5b653ef1cc1760e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 22:09:34 +0200 Subject: [PATCH 04/11] Remove dependency on poetry-version-plugin --- .github/workflows/publish.yml | 4 +--- .github/workflows/test.yml | 4 +--- pyproject.toml | 15 +++------------ 3 files changed, 5 insertions(+), 18 deletions(-) diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index f3c1e980a..864d833c5 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -38,9 +38,7 @@ jobs: # Ref: https://github.com/python-poetry/poetry-core/pull/188 run: | python -m pip install --upgrade pip - 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 + python -m pip install "poetry==1.5.1" - name: Configure poetry run: python -m poetry config virtualenvs.create false - name: Install Dependencies diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 585ffc045..0893faea7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -45,9 +45,7 @@ jobs: # Ref: https://github.com/python-poetry/poetry-core/pull/188 run: | python -m pip install --upgrade pip - 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 + python -m pip install "poetry==1.5.1" - name: Configure poetry run: python -m poetry config virtualenvs.create false - name: Install Dependencies diff --git a/pyproject.toml b/pyproject.toml index e3b1d3c27..f34ec4c15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "sqlmodel" -version = "0" +version = "0.0.8" description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." authors = ["Sebastián Ramírez "] readme = "README.md" @@ -57,16 +57,9 @@ async-exit-stack = {version = "*", python = "~3.6"} requires = ["poetry-core"] build-backend = "poetry.core.masonry.api" -[tool.poetry-version-plugin] -source = "init" - [tool.coverage.run] parallel = true -source = [ - "docs_src", - "tests", - "sqlmodel" -] +source = ["docs_src", "tests", "sqlmodel"] context = '${CONTEXT}' [tool.coverage.report] @@ -80,9 +73,7 @@ exclude_lines = [ [tool.isort] profile = "black" known_third_party = ["sqlmodel"] -skip_glob = [ - "sqlmodel/__init__.py", - ] +skip_glob = ["sqlmodel/__init__.py"] [tool.mypy] From a72e2842a9fd1962d89dd5c91117b2f11cdda446 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 22:25:43 +0200 Subject: [PATCH 05/11] Remove support for python 3.6 (eol) --- .github/workflows/test.yml | 3 +-- README.md | 2 +- docs/contributing.md | 2 +- docs/features.md | 2 +- docs/index.md | 2 +- docs/tutorial/index.md | 3 +-- pyproject.toml | 3 +-- sqlmodel/sql/expression.py | 35 ++++++++--------------------------- 8 files changed, 15 insertions(+), 37 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 0893faea7..fc40c6938 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -18,7 +18,7 @@ jobs: runs-on: ubuntu-20.04 strategy: matrix: - python-version: ["3.6.15", "3.7", "3.8", "3.9", "3.10"] + python-version: ["3.7", "3.8", "3.9", "3.10"] fail-fast: false steps: @@ -52,7 +52,6 @@ jobs: if: steps.cache.outputs.cache-hit != 'true' run: python -m poetry install - name: Lint - if: ${{ matrix.python-version != '3.6.15' }} run: python -m poetry run bash scripts/lint.sh - run: mkdir coverage - name: Test diff --git a/README.md b/README.md index 5721f1cdb..df1e3906b 100644 --- a/README.md +++ b/README.md @@ -50,7 +50,7 @@ It combines SQLAlchemy and Pydantic and tries to simplify the code you write as ## Requirements -A recent and currently supported version of Python (right now, Python supports versions 3.6 and above). +A recent and currently supported version of Python (right now, Python supports versions 3.7 and above). As **SQLModel** is based on **Pydantic** and **SQLAlchemy**, it requires them. They will be automatically installed when you install SQLModel. diff --git a/docs/contributing.md b/docs/contributing.md index f2964fba9..90babf15b 100644 --- a/docs/contributing.md +++ b/docs/contributing.md @@ -8,7 +8,7 @@ If you already cloned the repository and you know that you need to deep dive in ### Python -SQLModel supports Python 3.6 and above, but for development you should have at least **Python 3.7**. +SQLModel supports Python 3.7 and above, but for development you should have at least **Python 3.7**. ### Poetry diff --git a/docs/features.md b/docs/features.md index 09de0c17f..2d5e11d84 100644 --- a/docs/features.md +++ b/docs/features.md @@ -12,7 +12,7 @@ Nevertheless, SQLModel is completely **independent** of FastAPI and can be used ## Just Modern Python -It's all based on standard modern **Python** type annotations. No new syntax to learn. Just standard modern Python. +It's all based on standard modern **Python** type annotations. No new syntax to learn. Just standard modern Python. If you need a 2 minute refresher of how to use Python types (even if you don't use SQLModel or FastAPI), check the FastAPI tutorial section: Python types intro. diff --git a/docs/index.md b/docs/index.md index 5721f1cdb..df1e3906b 100644 --- a/docs/index.md +++ b/docs/index.md @@ -50,7 +50,7 @@ It combines SQLAlchemy and Pydantic and tries to simplify the code you write as ## Requirements -A recent and currently supported version of Python (right now, Python supports versions 3.6 and above). +A recent and currently supported version of Python (right now, Python supports versions 3.7 and above). As **SQLModel** is based on **Pydantic** and **SQLAlchemy**, it requires them. They will be automatically installed when you install SQLModel. diff --git a/docs/tutorial/index.md b/docs/tutorial/index.md index 33cf6226c..ea03a4533 100644 --- a/docs/tutorial/index.md +++ b/docs/tutorial/index.md @@ -64,7 +64,7 @@ $ cd sqlmodel-tutorial Make sure you have an officially supported version of Python. -Currently it is **Python 3.6** and above (Python 3.5 was already deprecated). +Currently it is **Python 3.7** and above. You can check which version you have with: @@ -85,7 +85,6 @@ You might want to try with the specific versions, for example with: * `python3.9` * `python3.8` * `python3.7` -* `python3.6` The code would look like this: diff --git a/pyproject.toml b/pyproject.toml index f34ec4c15..d32b4828f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,7 +17,6 @@ classifiers = [ "Intended Audience :: System Administrators", "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.6", "Programming Language :: Python :: 3.7", "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", @@ -30,7 +29,7 @@ classifiers = [ ] [tool.poetry.dependencies] -python = "^3.6.1" +python = "^3.7.0" SQLAlchemy = ">=1.4.17,<=1.4.41" pydantic = "^1.8.2" sqlalchemy2-stubs = {version = "*", allow-prereleases = true} diff --git a/sqlmodel/sql/expression.py b/sqlmodel/sql/expression.py index 31c0bc1a1..ac77e8571 100644 --- a/sqlmodel/sql/expression.py +++ b/sqlmodel/sql/expression.py @@ -24,36 +24,17 @@ _TSelect = TypeVar("_TSelect") -# Workaround Generics incompatibility in Python 3.6 -# Ref: https://github.com/python/typing/issues/449#issuecomment-316061322 -if sys.version_info.minor >= 7: - class Select(_Select, Generic[_TSelect]): - inherit_cache = True +class Select(_Select, Generic[_TSelect]): + inherit_cache = True - # This is not comparable to sqlalchemy.sql.selectable.ScalarSelect, that has a different - # purpose. This is the same as a normal SQLAlchemy Select class where there's only one - # entity, so the result will be converted to a scalar by default. This way writing - # for loops on the results will feel natural. - class SelectOfScalar(_Select, Generic[_TSelect]): - inherit_cache = True -else: - from typing import GenericMeta # type: ignore - - class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore - pass - - class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): - inherit_cache = True - - class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): - inherit_cache = True - - # Cast them for editors to work correctly, from several tricks tried, this works - # for both VS Code and PyCharm - Select = cast("Select", _Py36Select) # type: ignore - SelectOfScalar = cast("SelectOfScalar", _Py36SelectOfScalar) # type: ignore +# This is not comparable to sqlalchemy.sql.selectable.ScalarSelect, that has a different +# purpose. This is the same as a normal SQLAlchemy Select class where there's only one +# entity, so the result will be converted to a scalar by default. This way writing +# for loops on the results will feel natural. +class SelectOfScalar(_Select, Generic[_TSelect]): + inherit_cache = True if TYPE_CHECKING: # pragma: no cover From 30965e1a30ac4f6bae1423c64c4416856ad09921 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 22:34:26 +0200 Subject: [PATCH 06/11] Move as specified in comment --- scripts/lint.sh | 2 -- scripts/test.sh | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/lint.sh b/scripts/lint.sh index 02568cda6..4191d90f1 100755 --- a/scripts/lint.sh +++ b/scripts/lint.sh @@ -7,5 +7,3 @@ mypy sqlmodel flake8 sqlmodel tests docs_src black sqlmodel tests docs_src --check isort sqlmodel tests docs_src scripts --check-only -# TODO: move this to test.sh after deprecating Python 3.6 -CHECK_JINJA=1 python scripts/generate_select.py diff --git a/scripts/test.sh b/scripts/test.sh index 9b758bdbd..a80fd9045 100755 --- a/scripts/test.sh +++ b/scripts/test.sh @@ -7,3 +7,5 @@ coverage run -m pytest tests coverage combine coverage report --show-missing coverage html + +CHECK_JINJA=1 python scripts/generate_select.py From 06deba8275fd8069c07c36330c15d7966e0e6c9e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 22:35:04 +0200 Subject: [PATCH 07/11] Remove 3.6 support --- pyproject.toml | 2 -- sqlmodel/sql/expression.py.jinja2 | 40 +++++++------------------------ 2 files changed, 9 insertions(+), 33 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index d32b4828f..d9af8355d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -49,8 +49,6 @@ fastapi = "^0.68.1" 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/sqlmodel/sql/expression.py.jinja2 b/sqlmodel/sql/expression.py.jinja2 index 51f04a215..b06c24f28 100644 --- a/sqlmodel/sql/expression.py.jinja2 +++ b/sqlmodel/sql/expression.py.jinja2 @@ -22,37 +22,15 @@ from sqlalchemy.sql.expression import Select as _Select _TSelect = TypeVar("_TSelect") -# Workaround Generics incompatibility in Python 3.6 -# Ref: https://github.com/python/typing/issues/449#issuecomment-316061322 -if sys.version_info.minor >= 7: - - class Select(_Select, Generic[_TSelect]): - inherit_cache = True - - # This is not comparable to sqlalchemy.sql.selectable.ScalarSelect, that has a different - # purpose. This is the same as a normal SQLAlchemy Select class where there's only one - # entity, so the result will be converted to a scalar by default. This way writing - # for loops on the results will feel natural. - class SelectOfScalar(_Select, Generic[_TSelect]): - inherit_cache = True - -else: - from typing import GenericMeta # type: ignore - - class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore - pass - - class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): - inherit_cache = True - - class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): - inherit_cache = True - - # Cast them for editors to work correctly, from several tricks tried, this works - # for both VS Code and PyCharm - Select = cast("Select", _Py36Select) # type: ignore - SelectOfScalar = cast("SelectOfScalar", _Py36SelectOfScalar) # type: ignore - +class Select(_Select, Generic[_TSelect]): + inherit_cache = True + +# This is not comparable to sqlalchemy.sql.selectable.ScalarSelect, that has a different +# purpose. This is the same as a normal SQLAlchemy Select class where there's only one +# entity, so the result will be converted to a scalar by default. This way writing +# for loops on the results will feel natural. +class SelectOfScalar(_Select, Generic[_TSelect]): + inherit_cache = True if TYPE_CHECKING: # pragma: no cover from ..main import SQLModel From a708162911cae81b8296cb8dc27af1294cee5a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 22:39:40 +0200 Subject: [PATCH 08/11] Try to fix mypy error --- sqlmodel/main.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/sqlmodel/main.py b/sqlmodel/main.py index d95c49850..cc6542e15 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -29,7 +29,7 @@ from pydantic.fields import FieldInfo as PydanticFieldInfo from pydantic.fields import ModelField, Undefined, UndefinedType from pydantic.main import ModelMetaclass, validate_model -from pydantic.typing import ForwardRef, NoArgAnyCallable, resolve_annotations +from pydantic.typing import NoArgAnyCallable, resolve_annotations from pydantic.utils import ROOT_KEY, Representation from sqlalchemy import Boolean, Column, Date, DateTime from sqlalchemy import Enum as sa_Enum @@ -342,8 +342,6 @@ def __init__( config=BaseConfig, ) relationship_to = temp_field.type_ - if isinstance(temp_field.type_, ForwardRef): - relationship_to = temp_field.type_.__forward_arg__ rel_kwargs: Dict[str, Any] = {} if rel_info.back_populates: rel_kwargs["back_populates"] = rel_info.back_populates From 79069b550ac84f9ce9353aed4517849fecd17e2d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 22:44:29 +0200 Subject: [PATCH 09/11] Remove unused import --- sqlmodel/sql/expression.py | 2 -- sqlmodel/sql/expression.py.jinja2 | 2 -- 2 files changed, 4 deletions(-) diff --git a/sqlmodel/sql/expression.py b/sqlmodel/sql/expression.py index ac77e8571..264e39cba 100644 --- a/sqlmodel/sql/expression.py +++ b/sqlmodel/sql/expression.py @@ -1,6 +1,5 @@ # WARNING: do not modify this code, it is generated by expression.py.jinja2 -import sys from datetime import datetime from typing import ( TYPE_CHECKING, @@ -12,7 +11,6 @@ Type, TypeVar, Union, - cast, overload, ) from uuid import UUID diff --git a/sqlmodel/sql/expression.py.jinja2 b/sqlmodel/sql/expression.py.jinja2 index b06c24f28..26d12a039 100644 --- a/sqlmodel/sql/expression.py.jinja2 +++ b/sqlmodel/sql/expression.py.jinja2 @@ -1,4 +1,3 @@ -import sys from datetime import datetime from typing import ( TYPE_CHECKING, @@ -10,7 +9,6 @@ from typing import ( Type, TypeVar, Union, - cast, overload, ) from uuid import UUID From 9f7eb8f3a7af239117d2075f8ded0b3c8e381849 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 22:54:08 +0200 Subject: [PATCH 10/11] Revert "Try to fix mypy error" This reverts commit a708162911cae81b8296cb8dc27af1294cee5a57. --- sqlmodel/main.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/sqlmodel/main.py b/sqlmodel/main.py index cc6542e15..d95c49850 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -29,7 +29,7 @@ from pydantic.fields import FieldInfo as PydanticFieldInfo from pydantic.fields import ModelField, Undefined, UndefinedType from pydantic.main import 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, Column, Date, DateTime from sqlalchemy import Enum as sa_Enum @@ -342,6 +342,8 @@ def __init__( config=BaseConfig, ) relationship_to = temp_field.type_ + if isinstance(temp_field.type_, ForwardRef): + relationship_to = temp_field.type_.__forward_arg__ rel_kwargs: Dict[str, Any] = {} if rel_info.back_populates: rel_kwargs["back_populates"] = rel_info.back_populates From 4c3afc7e2dfe1b67103e3e48c62e6d138009884d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Wei=C3=9F?= Date: Wed, 31 May 2023 23:03:54 +0200 Subject: [PATCH 11/11] Fix import --- sqlmodel/main.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/sqlmodel/main.py b/sqlmodel/main.py index d95c49850..5b5950a81 100644 --- a/sqlmodel/main.py +++ b/sqlmodel/main.py @@ -11,6 +11,7 @@ Callable, ClassVar, Dict, + ForwardRef, List, Mapping, Optional, @@ -29,7 +30,7 @@ from pydantic.fields import FieldInfo as PydanticFieldInfo from pydantic.fields import ModelField, Undefined, UndefinedType from pydantic.main import ModelMetaclass, validate_model -from pydantic.typing import ForwardRef, NoArgAnyCallable, resolve_annotations +from pydantic.typing import NoArgAnyCallable, resolve_annotations from pydantic.utils import ROOT_KEY, Representation from sqlalchemy import Boolean, Column, Date, DateTime from sqlalchemy import Enum as sa_Enum