Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ sqlalchemy2-stubs = {version = "*", allow-prereleases = true}

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
mypy = "^0.812"
mypy = "^0.910"
flake8 = "^3.9.2"
black = {version = "^21.5-beta.1", python = "^3.7"}
mkdocs = "^1.2.1"
Expand DownExpand Up@@ -98,3 +98,7 @@ warn_return_any = true
implicit_reexport = false
strict_equality = true
# --strict end

[[tool.mypy.overrides]]
module = "sqlmodel.sql.expression"
warn_unused_ignores = false
2 changes: 1 addition & 1 deletion sqlmodel/engine/create.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,4 +136,4 @@ def create_engine(
if not isinstance(query_cache_size, _DefaultPlaceholder):
current_kwargs["query_cache_size"] = query_cache_size
current_kwargs.update(kwargs)
return _create_engine(url, **current_kwargs)
return _create_engine(url, **current_kwargs) # type: ignore
8 changes: 4 additions & 4 deletions sqlmodel/engine/result.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ def __iter__(self) -> Iterator[_T]:
return super().__iter__()

def __next__(self) -> _T:
return super().__next__()
return super().__next__() # type: ignore

def first(self) -> Optional[_T]:
return super().first()
Expand All@@ -32,7 +32,7 @@ def one_or_none(self) -> Optional[_T]:
return super().one_or_none()

def one(self) -> _T:
return super().one()
return super().one() # type: ignore


class Result(_Result, Generic[_T]):
Expand DownExpand Up@@ -70,10 +70,10 @@ def scalar_one(self) -> _T:
return super().scalar_one() # type: ignore

def scalar_one_or_none(self) -> Optional[_T]:
return super().scalar_one_or_none() # type: ignore
return super().scalar_one_or_none()

def one(self) -> _T: # type: ignore
return super().one() # type: ignore

def scalar(self) -> Optional[_T]:
return super().scalar() # type: ignore
return super().scalar()
4 changes: 2 additions & 2 deletions sqlmodel/ext/asyncio/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ def __init__(
self,
bind: Optional[Union[AsyncConnection, AsyncEngine]] = None,
binds: Optional[Mapping[object, Union[AsyncConnection, AsyncEngine]]] = None,
**kw,
**kw: Any,
):
# All the same code of the original AsyncSession
kw["future"] = True
Expand DownExpand Up@@ -52,7 +52,7 @@ async def exec(
# util.immutabledict has the union() method. Is this a bug in SQLAlchemy?
execution_options = execution_options.union({"prebuffer_rows": True}) # type: ignore

return await greenlet_spawn( # type: ignore
return await greenlet_spawn(
self.sync_session.exec,
statement,
params=params,
Expand Down
73 changes: 42 additions & 31 deletions sqlmodel/main.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ def __init__(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> None:
Expand All@@ -127,32 +127,32 @@ def Field(
default: Any = Undefined,
*,
default_factory: Optional[NoArgAnyCallable] = None,
alias: str = None,
title: str = None,
description: str = None,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
exclude: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
include: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
const: bool = None,
gt: float = None,
ge: float = None,
lt: float = None,
le: float = None,
multiple_of: float = None,
min_items: int = None,
max_items: int = None,
min_length: int = None,
max_length: int = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
multiple_of: Optional[float] = None,
min_items: Optional[int] = None,
max_items: Optional[int] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
allow_mutation: bool = True,
regex: str = None,
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
schema_extra: Optional[Dict[str, Any]] = None,
Expand DownExpand Up@@ -195,7 +195,7 @@ def Relationship(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> Any:
Expand All@@ -217,19 +217,25 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):

# Replicate SQLAlchemy
def __setattr__(cls, name: str, value: Any) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__setattr__(cls, name, value)
else:
super().__setattr__(name, value)

def __delattr__(cls, name: str) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__delattr__(cls, name)
else:
super().__delattr__(name)

# From Pydantic
def __new__(cls, name, bases, class_dict: dict, **kwargs) -> Any:
def __new__(
cls,
name: str,
bases: Tuple[Type[Any], ...],
class_dict: Dict[str, Any],
**kwargs: Any,
) -> Any:
relationships: Dict[str, RelationshipInfo] = {}
dict_for_pydantic = {}
original_annotations = resolve_annotations(
Expand DownExpand Up@@ -342,7 +348,7 @@ def __init__(
)
relationship_to = temp_field.type_
if isinstance(temp_field.type_, ForwardRef):
relationship_to = temp_field.type_.__forward_arg__ # type: ignore
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
Expand All@@ -360,7 +366,7 @@ def __init__(
rel_args.extend(rel_info.sa_relationship_args)
if rel_info.sa_relationship_kwargs:
rel_kwargs.update(rel_info.sa_relationship_kwargs)
rel_value: RelationshipProperty = relationship(
rel_value: RelationshipProperty = relationship( # type: ignore
relationship_to, *rel_args, **rel_kwargs
)
dict_used[rel_name] = rel_value
Expand DownExpand Up@@ -408,7 +414,7 @@ def get_sqlachemy_type(field: ModelField) -> Any:
return GUID


def get_column_from_field(field: ModelField) -> Column:
def get_column_from_field(field: ModelField) -> Column: # type: ignore
sa_column = getattr(field.field_info, "sa_column", Undefined)
if isinstance(sa_column, Column):
return sa_column
Expand DownExpand Up@@ -440,10 +446,10 @@ def get_column_from_field(field: ModelField) -> Column:
kwargs["default"] = sa_default
sa_column_args = getattr(field.field_info, "sa_column_args", Undefined)
if sa_column_args is not Undefined:
args.extend(list(cast(Sequence, sa_column_args)))
args.extend(list(cast(Sequence[Any], sa_column_args)))
sa_column_kwargs = getattr(field.field_info, "sa_column_kwargs", Undefined)
if sa_column_kwargs is not Undefined:
kwargs.update(cast(dict, sa_column_kwargs))
kwargs.update(cast(Dict[Any, Any], sa_column_kwargs))
return Column(sa_type, *args, **kwargs)


Expand All@@ -452,24 +458,27 @@ def get_column_from_field(field: ModelField) -> Column:
default_registry = registry()


def _value_items_is_true(v) -> bool:
def _value_items_is_true(v: Any) -> bool:
# Re-implement Pydantic's ValueItems.is_true() as it hasn't been released as of
# the current latest, Pydantic 1.8.2
return v is True or v is ...


_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")


class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry):
# SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
__slots__ = ("__weakref__",)
__tablename__: ClassVar[Union[str, Callable[..., str]]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
__name__: ClassVar[str]
metadata: ClassVar[MetaData]

class Config:
orm_mode = True

def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
# SQLAlchemy doesn't call __init__ on the base class
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
Expand DownExpand Up@@ -520,7 +529,9 @@ def __setattr__(self, name: str, value: Any) -> None:
super().__setattr__(name, value)

@classmethod
def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
def from_orm(
cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None
) -> _TSQLModel:
# Duplicated from Pydantic
if not cls.__config__.orm_mode:
raise ConfigError(
Expand All@@ -533,7 +544,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
# End SQLModel support dict
if not getattr(cls.__config__, "table", False):
# If not table, normal Pydantic code
m = cls.__new__(cls)
m: _TSQLModel = cls.__new__(cls)
else:
# If table, create the new instance normally to make SQLAlchemy create
# the _sa_instance_state attribute
Expand All@@ -554,7 +565,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):

@classmethod
def parse_obj(
cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None
cls: Type["SQLModel"], obj: Any, update: Optional[Dict[str, Any]] = None
) -> "SQLModel":
obj = cls._enforce_dict_if_root(obj)
# SQLModel, support update dict
Expand Down
6 changes: 3 additions & 3 deletions sqlmodel/orm/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ def exec(
results = super().execute(
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand All@@ -74,7 +74,7 @@ def execute(
self,
statement: _Executable,
params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None,
execution_options: Mapping[str, Any] = util.EMPTY_DICT,
execution_options: Optional[Mapping[str, Any]] = util.EMPTY_DICT,
bind_arguments: Optional[Mapping[str, Any]] = None,
_parent_execute_state: Optional[Any] = None,
_add_event: Optional[Any] = None,
Expand All@@ -101,7 +101,7 @@ def execute(
return super().execute( # type: ignore
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand Down
4 changes: 1 addition & 3 deletions sqlmodel/sql/base.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,4 @@


class Executable(_Executable, Generic[_T]):
def __init__(self, *args, **kwargs):
self.__dict__["_exec_options"] = kwargs.pop("_exec_options", None)
super(_Executable, self).__init__(*args, **kwargs)
pass
32 changes: 16 additions & 16 deletions sqlmodel/sql/expression.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,10 +45,10 @@ class SelectOfScalar(_Select, Generic[_TSelect]):
class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore
pass

class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

# Cast them for editors to work correctly, from several tricks tried, this works
Expand All@@ -65,9 +65,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_0 = TypeVar(
"_TScalar_0",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -83,9 +83,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_1 = TypeVar(
"_TScalar_1",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -101,9 +101,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_2 = TypeVar(
"_TScalar_2",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -119,9 +119,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_3 = TypeVar(
"_TScalar_3",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand DownExpand Up@@ -446,14 +446,14 @@ def select( # type: ignore
# Generated overloads end


def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]:
def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]: # type: ignore
if len(entities) == 1:
return SelectOfScalar._create(*entities, **kw) # type: ignore
return Select._create(*entities, **kw) # type: ignore


# TODO: add several @overload from Python types to SQLAlchemy equivalents
def col(column_expression: Any) -> ColumnClause:
def col(column_expression: Any) -> ColumnClause: # type: ignore
if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)):
raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
return column_expression
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ sqlalchemy2-stubs = {version = "*", allow-prereleases = true}

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
mypy = "^0.812"
mypy = "^0.910"
flake8 = "^3.9.2"
black = {version = "^21.5-beta.1", python = "^3.7"}
mkdocs = "^1.2.1"
Expand DownExpand Up@@ -98,3 +98,7 @@ warn_return_any = true
implicit_reexport = false
strict_equality = true
# --strict end

[[tool.mypy.overrides]]
module = "sqlmodel.sql.expression"
warn_unused_ignores = false
2 changes: 1 addition & 1 deletion sqlmodel/engine/create.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,4 +136,4 @@ def create_engine(
if not isinstance(query_cache_size, _DefaultPlaceholder):
current_kwargs["query_cache_size"] = query_cache_size
current_kwargs.update(kwargs)
return _create_engine(url, **current_kwargs)
return _create_engine(url, **current_kwargs) # type: ignore
8 changes: 4 additions & 4 deletions sqlmodel/engine/result.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ def __iter__(self) -> Iterator[_T]:
return super().__iter__()

def __next__(self) -> _T:
return super().__next__()
return super().__next__() # type: ignore

def first(self) -> Optional[_T]:
return super().first()
Expand All@@ -32,7 +32,7 @@ def one_or_none(self) -> Optional[_T]:
return super().one_or_none()

def one(self) -> _T:
return super().one()
return super().one() # type: ignore


class Result(_Result, Generic[_T]):
Expand DownExpand Up@@ -70,10 +70,10 @@ def scalar_one(self) -> _T:
return super().scalar_one() # type: ignore

def scalar_one_or_none(self) -> Optional[_T]:
return super().scalar_one_or_none() # type: ignore
return super().scalar_one_or_none()

def one(self) -> _T: # type: ignore
return super().one() # type: ignore

def scalar(self) -> Optional[_T]:
return super().scalar() # type: ignore
return super().scalar()
4 changes: 2 additions & 2 deletions sqlmodel/ext/asyncio/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ def __init__(
self,
bind: Optional[Union[AsyncConnection, AsyncEngine]] = None,
binds: Optional[Mapping[object, Union[AsyncConnection, AsyncEngine]]] = None,
**kw,
**kw: Any,
):
# All the same code of the original AsyncSession
kw["future"] = True
Expand DownExpand Up@@ -52,7 +52,7 @@ async def exec(
# util.immutabledict has the union() method. Is this a bug in SQLAlchemy?
execution_options = execution_options.union({"prebuffer_rows": True}) # type: ignore

return await greenlet_spawn( # type: ignore
return await greenlet_spawn(
self.sync_session.exec,
statement,
params=params,
Expand Down
73 changes: 42 additions & 31 deletions sqlmodel/main.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ def __init__(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> None:
Expand All@@ -127,32 +127,32 @@ def Field(
default: Any = Undefined,
*,
default_factory: Optional[NoArgAnyCallable] = None,
alias: str = None,
title: str = None,
description: str = None,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
exclude: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
include: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
const: bool = None,
gt: float = None,
ge: float = None,
lt: float = None,
le: float = None,
multiple_of: float = None,
min_items: int = None,
max_items: int = None,
min_length: int = None,
max_length: int = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
multiple_of: Optional[float] = None,
min_items: Optional[int] = None,
max_items: Optional[int] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
allow_mutation: bool = True,
regex: str = None,
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
schema_extra: Optional[Dict[str, Any]] = None,
Expand DownExpand Up@@ -195,7 +195,7 @@ def Relationship(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> Any:
Expand All@@ -217,19 +217,25 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):

# Replicate SQLAlchemy
def __setattr__(cls, name: str, value: Any) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__setattr__(cls, name, value)
else:
super().__setattr__(name, value)

def __delattr__(cls, name: str) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__delattr__(cls, name)
else:
super().__delattr__(name)

# From Pydantic
def __new__(cls, name, bases, class_dict: dict, **kwargs) -> Any:
def __new__(
cls,
name: str,
bases: Tuple[Type[Any], ...],
class_dict: Dict[str, Any],
**kwargs: Any,
) -> Any:
relationships: Dict[str, RelationshipInfo] = {}
dict_for_pydantic = {}
original_annotations = resolve_annotations(
Expand DownExpand Up@@ -342,7 +348,7 @@ def __init__(
)
relationship_to = temp_field.type_
if isinstance(temp_field.type_, ForwardRef):
relationship_to = temp_field.type_.__forward_arg__ # type: ignore
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
Expand All@@ -360,7 +366,7 @@ def __init__(
rel_args.extend(rel_info.sa_relationship_args)
if rel_info.sa_relationship_kwargs:
rel_kwargs.update(rel_info.sa_relationship_kwargs)
rel_value: RelationshipProperty = relationship(
rel_value: RelationshipProperty = relationship( # type: ignore
relationship_to, *rel_args, **rel_kwargs
)
dict_used[rel_name] = rel_value
Expand DownExpand Up@@ -408,7 +414,7 @@ def get_sqlachemy_type(field: ModelField) -> Any:
return GUID


def get_column_from_field(field: ModelField) -> Column:
def get_column_from_field(field: ModelField) -> Column: # type: ignore
sa_column = getattr(field.field_info, "sa_column", Undefined)
if isinstance(sa_column, Column):
return sa_column
Expand DownExpand Up@@ -440,10 +446,10 @@ def get_column_from_field(field: ModelField) -> Column:
kwargs["default"] = sa_default
sa_column_args = getattr(field.field_info, "sa_column_args", Undefined)
if sa_column_args is not Undefined:
args.extend(list(cast(Sequence, sa_column_args)))
args.extend(list(cast(Sequence[Any], sa_column_args)))
sa_column_kwargs = getattr(field.field_info, "sa_column_kwargs", Undefined)
if sa_column_kwargs is not Undefined:
kwargs.update(cast(dict, sa_column_kwargs))
kwargs.update(cast(Dict[Any, Any], sa_column_kwargs))
return Column(sa_type, *args, **kwargs)


Expand All@@ -452,24 +458,27 @@ def get_column_from_field(field: ModelField) -> Column:
default_registry = registry()


def _value_items_is_true(v) -> bool:
def _value_items_is_true(v: Any) -> bool:
# Re-implement Pydantic's ValueItems.is_true() as it hasn't been released as of
# the current latest, Pydantic 1.8.2
return v is True or v is ...


_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")


class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry):
# SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
__slots__ = ("__weakref__",)
__tablename__: ClassVar[Union[str, Callable[..., str]]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
__name__: ClassVar[str]
metadata: ClassVar[MetaData]

class Config:
orm_mode = True

def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
# SQLAlchemy doesn't call __init__ on the base class
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
Expand DownExpand Up@@ -520,7 +529,9 @@ def __setattr__(self, name: str, value: Any) -> None:
super().__setattr__(name, value)

@classmethod
def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
def from_orm(
cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None
) -> _TSQLModel:
# Duplicated from Pydantic
if not cls.__config__.orm_mode:
raise ConfigError(
Expand All@@ -533,7 +544,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
# End SQLModel support dict
if not getattr(cls.__config__, "table", False):
# If not table, normal Pydantic code
m = cls.__new__(cls)
m: _TSQLModel = cls.__new__(cls)
else:
# If table, create the new instance normally to make SQLAlchemy create
# the _sa_instance_state attribute
Expand All@@ -554,7 +565,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):

@classmethod
def parse_obj(
cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None
cls: Type["SQLModel"], obj: Any, update: Optional[Dict[str, Any]] = None
) -> "SQLModel":
obj = cls._enforce_dict_if_root(obj)
# SQLModel, support update dict
Expand Down
6 changes: 3 additions & 3 deletions sqlmodel/orm/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ def exec(
results = super().execute(
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand All@@ -74,7 +74,7 @@ def execute(
self,
statement: _Executable,
params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None,
execution_options: Mapping[str, Any] = util.EMPTY_DICT,
execution_options: Optional[Mapping[str, Any]] = util.EMPTY_DICT,
bind_arguments: Optional[Mapping[str, Any]] = None,
_parent_execute_state: Optional[Any] = None,
_add_event: Optional[Any] = None,
Expand All@@ -101,7 +101,7 @@ def execute(
return super().execute( # type: ignore
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand Down
4 changes: 1 addition & 3 deletions sqlmodel/sql/base.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,4 @@


class Executable(_Executable, Generic[_T]):
def __init__(self, *args, **kwargs):
self.__dict__["_exec_options"] = kwargs.pop("_exec_options", None)
super(_Executable, self).__init__(*args, **kwargs)
pass
32 changes: 16 additions & 16 deletions sqlmodel/sql/expression.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,10 +45,10 @@ class SelectOfScalar(_Select, Generic[_TSelect]):
class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore
pass

class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

# Cast them for editors to work correctly, from several tricks tried, this works
Expand All@@ -65,9 +65,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_0 = TypeVar(
"_TScalar_0",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -83,9 +83,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_1 = TypeVar(
"_TScalar_1",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -101,9 +101,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_2 = TypeVar(
"_TScalar_2",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -119,9 +119,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_3 = TypeVar(
"_TScalar_3",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand DownExpand Up@@ -446,14 +446,14 @@ def select( # type: ignore
# Generated overloads end


def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]:
def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]: # type: ignore
if len(entities) == 1:
return SelectOfScalar._create(*entities, **kw) # type: ignore
return Select._create(*entities, **kw) # type: ignore


# TODO: add several @overload from Python types to SQLAlchemy equivalents
def col(column_expression: Any) -> ColumnClause:
def col(column_expression: Any) -> ColumnClause: # type: ignore
if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)):
raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
return column_expression
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ sqlalchemy2-stubs = {version = "*", allow-prereleases = true}

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
mypy = "^0.812"
mypy = "^0.910"
flake8 = "^3.9.2"
black = {version = "^21.5-beta.1", python = "^3.7"}
mkdocs = "^1.2.1"
Expand DownExpand Up@@ -98,3 +98,7 @@ warn_return_any = true
implicit_reexport = false
strict_equality = true
# --strict end

[[tool.mypy.overrides]]
module = "sqlmodel.sql.expression"
warn_unused_ignores = false
2 changes: 1 addition & 1 deletion sqlmodel/engine/create.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,4 +136,4 @@ def create_engine(
if not isinstance(query_cache_size, _DefaultPlaceholder):
current_kwargs["query_cache_size"] = query_cache_size
current_kwargs.update(kwargs)
return _create_engine(url, **current_kwargs)
return _create_engine(url, **current_kwargs) # type: ignore
8 changes: 4 additions & 4 deletions sqlmodel/engine/result.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ def __iter__(self) -> Iterator[_T]:
return super().__iter__()

def __next__(self) -> _T:
return super().__next__()
return super().__next__() # type: ignore

def first(self) -> Optional[_T]:
return super().first()
Expand All@@ -32,7 +32,7 @@ def one_or_none(self) -> Optional[_T]:
return super().one_or_none()

def one(self) -> _T:
return super().one()
return super().one() # type: ignore


class Result(_Result, Generic[_T]):
Expand DownExpand Up@@ -70,10 +70,10 @@ def scalar_one(self) -> _T:
return super().scalar_one() # type: ignore

def scalar_one_or_none(self) -> Optional[_T]:
return super().scalar_one_or_none() # type: ignore
return super().scalar_one_or_none()

def one(self) -> _T: # type: ignore
return super().one() # type: ignore

def scalar(self) -> Optional[_T]:
return super().scalar() # type: ignore
return super().scalar()
4 changes: 2 additions & 2 deletions sqlmodel/ext/asyncio/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ def __init__(
self,
bind: Optional[Union[AsyncConnection, AsyncEngine]] = None,
binds: Optional[Mapping[object, Union[AsyncConnection, AsyncEngine]]] = None,
**kw,
**kw: Any,
):
# All the same code of the original AsyncSession
kw["future"] = True
Expand DownExpand Up@@ -52,7 +52,7 @@ async def exec(
# util.immutabledict has the union() method. Is this a bug in SQLAlchemy?
execution_options = execution_options.union({"prebuffer_rows": True}) # type: ignore

return await greenlet_spawn( # type: ignore
return await greenlet_spawn(
self.sync_session.exec,
statement,
params=params,
Expand Down
73 changes: 42 additions & 31 deletions sqlmodel/main.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ def __init__(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> None:
Expand All@@ -127,32 +127,32 @@ def Field(
default: Any = Undefined,
*,
default_factory: Optional[NoArgAnyCallable] = None,
alias: str = None,
title: str = None,
description: str = None,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
exclude: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
include: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
const: bool = None,
gt: float = None,
ge: float = None,
lt: float = None,
le: float = None,
multiple_of: float = None,
min_items: int = None,
max_items: int = None,
min_length: int = None,
max_length: int = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
multiple_of: Optional[float] = None,
min_items: Optional[int] = None,
max_items: Optional[int] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
allow_mutation: bool = True,
regex: str = None,
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
schema_extra: Optional[Dict[str, Any]] = None,
Expand DownExpand Up@@ -195,7 +195,7 @@ def Relationship(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> Any:
Expand All@@ -217,19 +217,25 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):

# Replicate SQLAlchemy
def __setattr__(cls, name: str, value: Any) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__setattr__(cls, name, value)
else:
super().__setattr__(name, value)

def __delattr__(cls, name: str) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__delattr__(cls, name)
else:
super().__delattr__(name)

# From Pydantic
def __new__(cls, name, bases, class_dict: dict, **kwargs) -> Any:
def __new__(
cls,
name: str,
bases: Tuple[Type[Any], ...],
class_dict: Dict[str, Any],
**kwargs: Any,
) -> Any:
relationships: Dict[str, RelationshipInfo] = {}
dict_for_pydantic = {}
original_annotations = resolve_annotations(
Expand DownExpand Up@@ -342,7 +348,7 @@ def __init__(
)
relationship_to = temp_field.type_
if isinstance(temp_field.type_, ForwardRef):
relationship_to = temp_field.type_.__forward_arg__ # type: ignore
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
Expand All@@ -360,7 +366,7 @@ def __init__(
rel_args.extend(rel_info.sa_relationship_args)
if rel_info.sa_relationship_kwargs:
rel_kwargs.update(rel_info.sa_relationship_kwargs)
rel_value: RelationshipProperty = relationship(
rel_value: RelationshipProperty = relationship( # type: ignore
relationship_to, *rel_args, **rel_kwargs
)
dict_used[rel_name] = rel_value
Expand DownExpand Up@@ -408,7 +414,7 @@ def get_sqlachemy_type(field: ModelField) -> Any:
return GUID


def get_column_from_field(field: ModelField) -> Column:
def get_column_from_field(field: ModelField) -> Column: # type: ignore
sa_column = getattr(field.field_info, "sa_column", Undefined)
if isinstance(sa_column, Column):
return sa_column
Expand DownExpand Up@@ -440,10 +446,10 @@ def get_column_from_field(field: ModelField) -> Column:
kwargs["default"] = sa_default
sa_column_args = getattr(field.field_info, "sa_column_args", Undefined)
if sa_column_args is not Undefined:
args.extend(list(cast(Sequence, sa_column_args)))
args.extend(list(cast(Sequence[Any], sa_column_args)))
sa_column_kwargs = getattr(field.field_info, "sa_column_kwargs", Undefined)
if sa_column_kwargs is not Undefined:
kwargs.update(cast(dict, sa_column_kwargs))
kwargs.update(cast(Dict[Any, Any], sa_column_kwargs))
return Column(sa_type, *args, **kwargs)


Expand All@@ -452,24 +458,27 @@ def get_column_from_field(field: ModelField) -> Column:
default_registry = registry()


def _value_items_is_true(v) -> bool:
def _value_items_is_true(v: Any) -> bool:
# Re-implement Pydantic's ValueItems.is_true() as it hasn't been released as of
# the current latest, Pydantic 1.8.2
return v is True or v is ...


_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")


class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry):
# SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
__slots__ = ("__weakref__",)
__tablename__: ClassVar[Union[str, Callable[..., str]]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
__name__: ClassVar[str]
metadata: ClassVar[MetaData]

class Config:
orm_mode = True

def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
# SQLAlchemy doesn't call __init__ on the base class
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
Expand DownExpand Up@@ -520,7 +529,9 @@ def __setattr__(self, name: str, value: Any) -> None:
super().__setattr__(name, value)

@classmethod
def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
def from_orm(
cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None
) -> _TSQLModel:
# Duplicated from Pydantic
if not cls.__config__.orm_mode:
raise ConfigError(
Expand All@@ -533,7 +544,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
# End SQLModel support dict
if not getattr(cls.__config__, "table", False):
# If not table, normal Pydantic code
m = cls.__new__(cls)
m: _TSQLModel = cls.__new__(cls)
else:
# If table, create the new instance normally to make SQLAlchemy create
# the _sa_instance_state attribute
Expand All@@ -554,7 +565,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):

@classmethod
def parse_obj(
cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None
cls: Type["SQLModel"], obj: Any, update: Optional[Dict[str, Any]] = None
) -> "SQLModel":
obj = cls._enforce_dict_if_root(obj)
# SQLModel, support update dict
Expand Down
6 changes: 3 additions & 3 deletions sqlmodel/orm/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ def exec(
results = super().execute(
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand All@@ -74,7 +74,7 @@ def execute(
self,
statement: _Executable,
params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None,
execution_options: Mapping[str, Any] = util.EMPTY_DICT,
execution_options: Optional[Mapping[str, Any]] = util.EMPTY_DICT,
bind_arguments: Optional[Mapping[str, Any]] = None,
_parent_execute_state: Optional[Any] = None,
_add_event: Optional[Any] = None,
Expand All@@ -101,7 +101,7 @@ def execute(
return super().execute( # type: ignore
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand Down
4 changes: 1 addition & 3 deletions sqlmodel/sql/base.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,4 @@


class Executable(_Executable, Generic[_T]):
def __init__(self, *args, **kwargs):
self.__dict__["_exec_options"] = kwargs.pop("_exec_options", None)
super(_Executable, self).__init__(*args, **kwargs)
pass
32 changes: 16 additions & 16 deletions sqlmodel/sql/expression.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,10 +45,10 @@ class SelectOfScalar(_Select, Generic[_TSelect]):
class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore
pass

class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

# Cast them for editors to work correctly, from several tricks tried, this works
Expand All@@ -65,9 +65,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_0 = TypeVar(
"_TScalar_0",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -83,9 +83,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_1 = TypeVar(
"_TScalar_1",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -101,9 +101,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_2 = TypeVar(
"_TScalar_2",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -119,9 +119,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_3 = TypeVar(
"_TScalar_3",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand DownExpand Up@@ -446,14 +446,14 @@ def select( # type: ignore
# Generated overloads end


def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]:
def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]: # type: ignore
if len(entities) == 1:
return SelectOfScalar._create(*entities, **kw) # type: ignore
return Select._create(*entities, **kw) # type: ignore


# TODO: add several @overload from Python types to SQLAlchemy equivalents
def col(column_expression: Any) -> ColumnClause:
def col(column_expression: Any) -> ColumnClause: # type: ignore
if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)):
raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
return column_expression
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ sqlalchemy2-stubs = {version = "*", allow-prereleases = true}

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
mypy = "^0.812"
mypy = "^0.910"
flake8 = "^3.9.2"
black = {version = "^21.5-beta.1", python = "^3.7"}
mkdocs = "^1.2.1"
Expand DownExpand Up@@ -98,3 +98,7 @@ warn_return_any = true
implicit_reexport = false
strict_equality = true
# --strict end

[[tool.mypy.overrides]]
module = "sqlmodel.sql.expression"
warn_unused_ignores = false
2 changes: 1 addition & 1 deletion sqlmodel/engine/create.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,4 +136,4 @@ def create_engine(
if not isinstance(query_cache_size, _DefaultPlaceholder):
current_kwargs["query_cache_size"] = query_cache_size
current_kwargs.update(kwargs)
return _create_engine(url, **current_kwargs)
return _create_engine(url, **current_kwargs) # type: ignore
8 changes: 4 additions & 4 deletions sqlmodel/engine/result.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ def __iter__(self) -> Iterator[_T]:
return super().__iter__()

def __next__(self) -> _T:
return super().__next__()
return super().__next__() # type: ignore

def first(self) -> Optional[_T]:
return super().first()
Expand All@@ -32,7 +32,7 @@ def one_or_none(self) -> Optional[_T]:
return super().one_or_none()

def one(self) -> _T:
return super().one()
return super().one() # type: ignore


class Result(_Result, Generic[_T]):
Expand DownExpand Up@@ -70,10 +70,10 @@ def scalar_one(self) -> _T:
return super().scalar_one() # type: ignore

def scalar_one_or_none(self) -> Optional[_T]:
return super().scalar_one_or_none() # type: ignore
return super().scalar_one_or_none()

def one(self) -> _T: # type: ignore
return super().one() # type: ignore

def scalar(self) -> Optional[_T]:
return super().scalar() # type: ignore
return super().scalar()
4 changes: 2 additions & 2 deletions sqlmodel/ext/asyncio/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ def __init__(
self,
bind: Optional[Union[AsyncConnection, AsyncEngine]] = None,
binds: Optional[Mapping[object, Union[AsyncConnection, AsyncEngine]]] = None,
**kw,
**kw: Any,
):
# All the same code of the original AsyncSession
kw["future"] = True
Expand DownExpand Up@@ -52,7 +52,7 @@ async def exec(
# util.immutabledict has the union() method. Is this a bug in SQLAlchemy?
execution_options = execution_options.union({"prebuffer_rows": True}) # type: ignore

return await greenlet_spawn( # type: ignore
return await greenlet_spawn(
self.sync_session.exec,
statement,
params=params,
Expand Down
73 changes: 42 additions & 31 deletions sqlmodel/main.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ def __init__(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> None:
Expand All@@ -127,32 +127,32 @@ def Field(
default: Any = Undefined,
*,
default_factory: Optional[NoArgAnyCallable] = None,
alias: str = None,
title: str = None,
description: str = None,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
exclude: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
include: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
const: bool = None,
gt: float = None,
ge: float = None,
lt: float = None,
le: float = None,
multiple_of: float = None,
min_items: int = None,
max_items: int = None,
min_length: int = None,
max_length: int = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
multiple_of: Optional[float] = None,
min_items: Optional[int] = None,
max_items: Optional[int] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
allow_mutation: bool = True,
regex: str = None,
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
schema_extra: Optional[Dict[str, Any]] = None,
Expand DownExpand Up@@ -195,7 +195,7 @@ def Relationship(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> Any:
Expand All@@ -217,19 +217,25 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):

# Replicate SQLAlchemy
def __setattr__(cls, name: str, value: Any) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__setattr__(cls, name, value)
else:
super().__setattr__(name, value)

def __delattr__(cls, name: str) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__delattr__(cls, name)
else:
super().__delattr__(name)

# From Pydantic
def __new__(cls, name, bases, class_dict: dict, **kwargs) -> Any:
def __new__(
cls,
name: str,
bases: Tuple[Type[Any], ...],
class_dict: Dict[str, Any],
**kwargs: Any,
) -> Any:
relationships: Dict[str, RelationshipInfo] = {}
dict_for_pydantic = {}
original_annotations = resolve_annotations(
Expand DownExpand Up@@ -342,7 +348,7 @@ def __init__(
)
relationship_to = temp_field.type_
if isinstance(temp_field.type_, ForwardRef):
relationship_to = temp_field.type_.__forward_arg__ # type: ignore
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
Expand All@@ -360,7 +366,7 @@ def __init__(
rel_args.extend(rel_info.sa_relationship_args)
if rel_info.sa_relationship_kwargs:
rel_kwargs.update(rel_info.sa_relationship_kwargs)
rel_value: RelationshipProperty = relationship(
rel_value: RelationshipProperty = relationship( # type: ignore
relationship_to, *rel_args, **rel_kwargs
)
dict_used[rel_name] = rel_value
Expand DownExpand Up@@ -408,7 +414,7 @@ def get_sqlachemy_type(field: ModelField) -> Any:
return GUID


def get_column_from_field(field: ModelField) -> Column:
def get_column_from_field(field: ModelField) -> Column: # type: ignore
sa_column = getattr(field.field_info, "sa_column", Undefined)
if isinstance(sa_column, Column):
return sa_column
Expand DownExpand Up@@ -440,10 +446,10 @@ def get_column_from_field(field: ModelField) -> Column:
kwargs["default"] = sa_default
sa_column_args = getattr(field.field_info, "sa_column_args", Undefined)
if sa_column_args is not Undefined:
args.extend(list(cast(Sequence, sa_column_args)))
args.extend(list(cast(Sequence[Any], sa_column_args)))
sa_column_kwargs = getattr(field.field_info, "sa_column_kwargs", Undefined)
if sa_column_kwargs is not Undefined:
kwargs.update(cast(dict, sa_column_kwargs))
kwargs.update(cast(Dict[Any, Any], sa_column_kwargs))
return Column(sa_type, *args, **kwargs)


Expand All@@ -452,24 +458,27 @@ def get_column_from_field(field: ModelField) -> Column:
default_registry = registry()


def _value_items_is_true(v) -> bool:
def _value_items_is_true(v: Any) -> bool:
# Re-implement Pydantic's ValueItems.is_true() as it hasn't been released as of
# the current latest, Pydantic 1.8.2
return v is True or v is ...


_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")


class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry):
# SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
__slots__ = ("__weakref__",)
__tablename__: ClassVar[Union[str, Callable[..., str]]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
__name__: ClassVar[str]
metadata: ClassVar[MetaData]

class Config:
orm_mode = True

def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
# SQLAlchemy doesn't call __init__ on the base class
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
Expand DownExpand Up@@ -520,7 +529,9 @@ def __setattr__(self, name: str, value: Any) -> None:
super().__setattr__(name, value)

@classmethod
def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
def from_orm(
cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None
) -> _TSQLModel:
# Duplicated from Pydantic
if not cls.__config__.orm_mode:
raise ConfigError(
Expand All@@ -533,7 +544,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
# End SQLModel support dict
if not getattr(cls.__config__, "table", False):
# If not table, normal Pydantic code
m = cls.__new__(cls)
m: _TSQLModel = cls.__new__(cls)
else:
# If table, create the new instance normally to make SQLAlchemy create
# the _sa_instance_state attribute
Expand All@@ -554,7 +565,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):

@classmethod
def parse_obj(
cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None
cls: Type["SQLModel"], obj: Any, update: Optional[Dict[str, Any]] = None
) -> "SQLModel":
obj = cls._enforce_dict_if_root(obj)
# SQLModel, support update dict
Expand Down
6 changes: 3 additions & 3 deletions sqlmodel/orm/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ def exec(
results = super().execute(
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand All@@ -74,7 +74,7 @@ def execute(
self,
statement: _Executable,
params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None,
execution_options: Mapping[str, Any] = util.EMPTY_DICT,
execution_options: Optional[Mapping[str, Any]] = util.EMPTY_DICT,
bind_arguments: Optional[Mapping[str, Any]] = None,
_parent_execute_state: Optional[Any] = None,
_add_event: Optional[Any] = None,
Expand All@@ -101,7 +101,7 @@ def execute(
return super().execute( # type: ignore
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand Down
4 changes: 1 addition & 3 deletions sqlmodel/sql/base.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,4 @@


class Executable(_Executable, Generic[_T]):
def __init__(self, *args, **kwargs):
self.__dict__["_exec_options"] = kwargs.pop("_exec_options", None)
super(_Executable, self).__init__(*args, **kwargs)
pass
32 changes: 16 additions & 16 deletions sqlmodel/sql/expression.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,10 +45,10 @@ class SelectOfScalar(_Select, Generic[_TSelect]):
class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore
pass

class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

# Cast them for editors to work correctly, from several tricks tried, this works
Expand All@@ -65,9 +65,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_0 = TypeVar(
"_TScalar_0",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -83,9 +83,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_1 = TypeVar(
"_TScalar_1",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -101,9 +101,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_2 = TypeVar(
"_TScalar_2",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -119,9 +119,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_3 = TypeVar(
"_TScalar_3",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand DownExpand Up@@ -446,14 +446,14 @@ def select( # type: ignore
# Generated overloads end


def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]:
def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]: # type: ignore
if len(entities) == 1:
return SelectOfScalar._create(*entities, **kw) # type: ignore
return Select._create(*entities, **kw) # type: ignore


# TODO: add several @overload from Python types to SQLAlchemy equivalents
def col(column_expression: Any) -> ColumnClause:
def col(column_expression: Any) -> ColumnClause: # type: ignore
if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)):
raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
return column_expression
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ sqlalchemy2-stubs = {version = "*", allow-prereleases = true}

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
mypy = "^0.812"
mypy = "^0.910"
flake8 = "^3.9.2"
black = {version = "^21.5-beta.1", python = "^3.7"}
mkdocs = "^1.2.1"
Expand DownExpand Up@@ -98,3 +98,7 @@ warn_return_any = true
implicit_reexport = false
strict_equality = true
# --strict end

[[tool.mypy.overrides]]
module = "sqlmodel.sql.expression"
warn_unused_ignores = false
2 changes: 1 addition & 1 deletion sqlmodel/engine/create.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,4 +136,4 @@ def create_engine(
if not isinstance(query_cache_size, _DefaultPlaceholder):
current_kwargs["query_cache_size"] = query_cache_size
current_kwargs.update(kwargs)
return _create_engine(url, **current_kwargs)
return _create_engine(url, **current_kwargs) # type: ignore
8 changes: 4 additions & 4 deletions sqlmodel/engine/result.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ def __iter__(self) -> Iterator[_T]:
return super().__iter__()

def __next__(self) -> _T:
return super().__next__()
return super().__next__() # type: ignore

def first(self) -> Optional[_T]:
return super().first()
Expand All@@ -32,7 +32,7 @@ def one_or_none(self) -> Optional[_T]:
return super().one_or_none()

def one(self) -> _T:
return super().one()
return super().one() # type: ignore


class Result(_Result, Generic[_T]):
Expand DownExpand Up@@ -70,10 +70,10 @@ def scalar_one(self) -> _T:
return super().scalar_one() # type: ignore

def scalar_one_or_none(self) -> Optional[_T]:
return super().scalar_one_or_none() # type: ignore
return super().scalar_one_or_none()

def one(self) -> _T: # type: ignore
return super().one() # type: ignore

def scalar(self) -> Optional[_T]:
return super().scalar() # type: ignore
return super().scalar()
4 changes: 2 additions & 2 deletions sqlmodel/ext/asyncio/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ def __init__(
self,
bind: Optional[Union[AsyncConnection, AsyncEngine]] = None,
binds: Optional[Mapping[object, Union[AsyncConnection, AsyncEngine]]] = None,
**kw,
**kw: Any,
):
# All the same code of the original AsyncSession
kw["future"] = True
Expand DownExpand Up@@ -52,7 +52,7 @@ async def exec(
# util.immutabledict has the union() method. Is this a bug in SQLAlchemy?
execution_options = execution_options.union({"prebuffer_rows": True}) # type: ignore

return await greenlet_spawn( # type: ignore
return await greenlet_spawn(
self.sync_session.exec,
statement,
params=params,
Expand Down
73 changes: 42 additions & 31 deletions sqlmodel/main.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ def __init__(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> None:
Expand All@@ -127,32 +127,32 @@ def Field(
default: Any = Undefined,
*,
default_factory: Optional[NoArgAnyCallable] = None,
alias: str = None,
title: str = None,
description: str = None,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
exclude: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
include: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
const: bool = None,
gt: float = None,
ge: float = None,
lt: float = None,
le: float = None,
multiple_of: float = None,
min_items: int = None,
max_items: int = None,
min_length: int = None,
max_length: int = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
multiple_of: Optional[float] = None,
min_items: Optional[int] = None,
max_items: Optional[int] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
allow_mutation: bool = True,
regex: str = None,
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
schema_extra: Optional[Dict[str, Any]] = None,
Expand DownExpand Up@@ -195,7 +195,7 @@ def Relationship(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> Any:
Expand All@@ -217,19 +217,25 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):

# Replicate SQLAlchemy
def __setattr__(cls, name: str, value: Any) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__setattr__(cls, name, value)
else:
super().__setattr__(name, value)

def __delattr__(cls, name: str) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__delattr__(cls, name)
else:
super().__delattr__(name)

# From Pydantic
def __new__(cls, name, bases, class_dict: dict, **kwargs) -> Any:
def __new__(
cls,
name: str,
bases: Tuple[Type[Any], ...],
class_dict: Dict[str, Any],
**kwargs: Any,
) -> Any:
relationships: Dict[str, RelationshipInfo] = {}
dict_for_pydantic = {}
original_annotations = resolve_annotations(
Expand DownExpand Up@@ -342,7 +348,7 @@ def __init__(
)
relationship_to = temp_field.type_
if isinstance(temp_field.type_, ForwardRef):
relationship_to = temp_field.type_.__forward_arg__ # type: ignore
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
Expand All@@ -360,7 +366,7 @@ def __init__(
rel_args.extend(rel_info.sa_relationship_args)
if rel_info.sa_relationship_kwargs:
rel_kwargs.update(rel_info.sa_relationship_kwargs)
rel_value: RelationshipProperty = relationship(
rel_value: RelationshipProperty = relationship( # type: ignore
relationship_to, *rel_args, **rel_kwargs
)
dict_used[rel_name] = rel_value
Expand DownExpand Up@@ -408,7 +414,7 @@ def get_sqlachemy_type(field: ModelField) -> Any:
return GUID


def get_column_from_field(field: ModelField) -> Column:
def get_column_from_field(field: ModelField) -> Column: # type: ignore
sa_column = getattr(field.field_info, "sa_column", Undefined)
if isinstance(sa_column, Column):
return sa_column
Expand DownExpand Up@@ -440,10 +446,10 @@ def get_column_from_field(field: ModelField) -> Column:
kwargs["default"] = sa_default
sa_column_args = getattr(field.field_info, "sa_column_args", Undefined)
if sa_column_args is not Undefined:
args.extend(list(cast(Sequence, sa_column_args)))
args.extend(list(cast(Sequence[Any], sa_column_args)))
sa_column_kwargs = getattr(field.field_info, "sa_column_kwargs", Undefined)
if sa_column_kwargs is not Undefined:
kwargs.update(cast(dict, sa_column_kwargs))
kwargs.update(cast(Dict[Any, Any], sa_column_kwargs))
return Column(sa_type, *args, **kwargs)


Expand All@@ -452,24 +458,27 @@ def get_column_from_field(field: ModelField) -> Column:
default_registry = registry()


def _value_items_is_true(v) -> bool:
def _value_items_is_true(v: Any) -> bool:
# Re-implement Pydantic's ValueItems.is_true() as it hasn't been released as of
# the current latest, Pydantic 1.8.2
return v is True or v is ...


_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")


class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry):
# SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
__slots__ = ("__weakref__",)
__tablename__: ClassVar[Union[str, Callable[..., str]]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
__name__: ClassVar[str]
metadata: ClassVar[MetaData]

class Config:
orm_mode = True

def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
# SQLAlchemy doesn't call __init__ on the base class
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
Expand DownExpand Up@@ -520,7 +529,9 @@ def __setattr__(self, name: str, value: Any) -> None:
super().__setattr__(name, value)

@classmethod
def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
def from_orm(
cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None
) -> _TSQLModel:
# Duplicated from Pydantic
if not cls.__config__.orm_mode:
raise ConfigError(
Expand All@@ -533,7 +544,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
# End SQLModel support dict
if not getattr(cls.__config__, "table", False):
# If not table, normal Pydantic code
m = cls.__new__(cls)
m: _TSQLModel = cls.__new__(cls)
else:
# If table, create the new instance normally to make SQLAlchemy create
# the _sa_instance_state attribute
Expand All@@ -554,7 +565,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):

@classmethod
def parse_obj(
cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None
cls: Type["SQLModel"], obj: Any, update: Optional[Dict[str, Any]] = None
) -> "SQLModel":
obj = cls._enforce_dict_if_root(obj)
# SQLModel, support update dict
Expand Down
6 changes: 3 additions & 3 deletions sqlmodel/orm/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ def exec(
results = super().execute(
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand All@@ -74,7 +74,7 @@ def execute(
self,
statement: _Executable,
params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None,
execution_options: Mapping[str, Any] = util.EMPTY_DICT,
execution_options: Optional[Mapping[str, Any]] = util.EMPTY_DICT,
bind_arguments: Optional[Mapping[str, Any]] = None,
_parent_execute_state: Optional[Any] = None,
_add_event: Optional[Any] = None,
Expand All@@ -101,7 +101,7 @@ def execute(
return super().execute( # type: ignore
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand Down
4 changes: 1 addition & 3 deletions sqlmodel/sql/base.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,4 @@


class Executable(_Executable, Generic[_T]):
def __init__(self, *args, **kwargs):
self.__dict__["_exec_options"] = kwargs.pop("_exec_options", None)
super(_Executable, self).__init__(*args, **kwargs)
pass
32 changes: 16 additions & 16 deletions sqlmodel/sql/expression.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,10 +45,10 @@ class SelectOfScalar(_Select, Generic[_TSelect]):
class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore
pass

class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

# Cast them for editors to work correctly, from several tricks tried, this works
Expand All@@ -65,9 +65,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_0 = TypeVar(
"_TScalar_0",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -83,9 +83,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_1 = TypeVar(
"_TScalar_1",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -101,9 +101,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_2 = TypeVar(
"_TScalar_2",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -119,9 +119,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_3 = TypeVar(
"_TScalar_3",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand DownExpand Up@@ -446,14 +446,14 @@ def select( # type: ignore
# Generated overloads end


def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]:
def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]: # type: ignore
if len(entities) == 1:
return SelectOfScalar._create(*entities, **kw) # type: ignore
return Select._create(*entities, **kw) # type: ignore


# TODO: add several @overload from Python types to SQLAlchemy equivalents
def col(column_expression: Any) -> ColumnClause:
def col(column_expression: Any) -> ColumnClause: # type: ignore
if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)):
raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
return column_expression
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ sqlalchemy2-stubs = {version = "*", allow-prereleases = true}

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
mypy = "^0.812"
mypy = "^0.910"
flake8 = "^3.9.2"
black = {version = "^21.5-beta.1", python = "^3.7"}
mkdocs = "^1.2.1"
Expand DownExpand Up@@ -98,3 +98,7 @@ warn_return_any = true
implicit_reexport = false
strict_equality = true
# --strict end

[[tool.mypy.overrides]]
module = "sqlmodel.sql.expression"
warn_unused_ignores = false
2 changes: 1 addition & 1 deletion sqlmodel/engine/create.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,4 +136,4 @@ def create_engine(
if not isinstance(query_cache_size, _DefaultPlaceholder):
current_kwargs["query_cache_size"] = query_cache_size
current_kwargs.update(kwargs)
return _create_engine(url, **current_kwargs)
return _create_engine(url, **current_kwargs) # type: ignore
8 changes: 4 additions & 4 deletions sqlmodel/engine/result.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ def __iter__(self) -> Iterator[_T]:
return super().__iter__()

def __next__(self) -> _T:
return super().__next__()
return super().__next__() # type: ignore

def first(self) -> Optional[_T]:
return super().first()
Expand All@@ -32,7 +32,7 @@ def one_or_none(self) -> Optional[_T]:
return super().one_or_none()

def one(self) -> _T:
return super().one()
return super().one() # type: ignore


class Result(_Result, Generic[_T]):
Expand DownExpand Up@@ -70,10 +70,10 @@ def scalar_one(self) -> _T:
return super().scalar_one() # type: ignore

def scalar_one_or_none(self) -> Optional[_T]:
return super().scalar_one_or_none() # type: ignore
return super().scalar_one_or_none()

def one(self) -> _T: # type: ignore
return super().one() # type: ignore

def scalar(self) -> Optional[_T]:
return super().scalar() # type: ignore
return super().scalar()
4 changes: 2 additions & 2 deletions sqlmodel/ext/asyncio/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ def __init__(
self,
bind: Optional[Union[AsyncConnection, AsyncEngine]] = None,
binds: Optional[Mapping[object, Union[AsyncConnection, AsyncEngine]]] = None,
**kw,
**kw: Any,
):
# All the same code of the original AsyncSession
kw["future"] = True
Expand DownExpand Up@@ -52,7 +52,7 @@ async def exec(
# util.immutabledict has the union() method. Is this a bug in SQLAlchemy?
execution_options = execution_options.union({"prebuffer_rows": True}) # type: ignore

return await greenlet_spawn( # type: ignore
return await greenlet_spawn(
self.sync_session.exec,
statement,
params=params,
Expand Down
73 changes: 42 additions & 31 deletions sqlmodel/main.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ def __init__(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> None:
Expand All@@ -127,32 +127,32 @@ def Field(
default: Any = Undefined,
*,
default_factory: Optional[NoArgAnyCallable] = None,
alias: str = None,
title: str = None,
description: str = None,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
exclude: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
include: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
const: bool = None,
gt: float = None,
ge: float = None,
lt: float = None,
le: float = None,
multiple_of: float = None,
min_items: int = None,
max_items: int = None,
min_length: int = None,
max_length: int = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
multiple_of: Optional[float] = None,
min_items: Optional[int] = None,
max_items: Optional[int] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
allow_mutation: bool = True,
regex: str = None,
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
schema_extra: Optional[Dict[str, Any]] = None,
Expand DownExpand Up@@ -195,7 +195,7 @@ def Relationship(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> Any:
Expand All@@ -217,19 +217,25 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):

# Replicate SQLAlchemy
def __setattr__(cls, name: str, value: Any) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__setattr__(cls, name, value)
else:
super().__setattr__(name, value)

def __delattr__(cls, name: str) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__delattr__(cls, name)
else:
super().__delattr__(name)

# From Pydantic
def __new__(cls, name, bases, class_dict: dict, **kwargs) -> Any:
def __new__(
cls,
name: str,
bases: Tuple[Type[Any], ...],
class_dict: Dict[str, Any],
**kwargs: Any,
) -> Any:
relationships: Dict[str, RelationshipInfo] = {}
dict_for_pydantic = {}
original_annotations = resolve_annotations(
Expand DownExpand Up@@ -342,7 +348,7 @@ def __init__(
)
relationship_to = temp_field.type_
if isinstance(temp_field.type_, ForwardRef):
relationship_to = temp_field.type_.__forward_arg__ # type: ignore
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
Expand All@@ -360,7 +366,7 @@ def __init__(
rel_args.extend(rel_info.sa_relationship_args)
if rel_info.sa_relationship_kwargs:
rel_kwargs.update(rel_info.sa_relationship_kwargs)
rel_value: RelationshipProperty = relationship(
rel_value: RelationshipProperty = relationship( # type: ignore
relationship_to, *rel_args, **rel_kwargs
)
dict_used[rel_name] = rel_value
Expand DownExpand Up@@ -408,7 +414,7 @@ def get_sqlachemy_type(field: ModelField) -> Any:
return GUID


def get_column_from_field(field: ModelField) -> Column:
def get_column_from_field(field: ModelField) -> Column: # type: ignore
sa_column = getattr(field.field_info, "sa_column", Undefined)
if isinstance(sa_column, Column):
return sa_column
Expand DownExpand Up@@ -440,10 +446,10 @@ def get_column_from_field(field: ModelField) -> Column:
kwargs["default"] = sa_default
sa_column_args = getattr(field.field_info, "sa_column_args", Undefined)
if sa_column_args is not Undefined:
args.extend(list(cast(Sequence, sa_column_args)))
args.extend(list(cast(Sequence[Any], sa_column_args)))
sa_column_kwargs = getattr(field.field_info, "sa_column_kwargs", Undefined)
if sa_column_kwargs is not Undefined:
kwargs.update(cast(dict, sa_column_kwargs))
kwargs.update(cast(Dict[Any, Any], sa_column_kwargs))
return Column(sa_type, *args, **kwargs)


Expand All@@ -452,24 +458,27 @@ def get_column_from_field(field: ModelField) -> Column:
default_registry = registry()


def _value_items_is_true(v) -> bool:
def _value_items_is_true(v: Any) -> bool:
# Re-implement Pydantic's ValueItems.is_true() as it hasn't been released as of
# the current latest, Pydantic 1.8.2
return v is True or v is ...


_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")


class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry):
# SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
__slots__ = ("__weakref__",)
__tablename__: ClassVar[Union[str, Callable[..., str]]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
__name__: ClassVar[str]
metadata: ClassVar[MetaData]

class Config:
orm_mode = True

def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
# SQLAlchemy doesn't call __init__ on the base class
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
Expand DownExpand Up@@ -520,7 +529,9 @@ def __setattr__(self, name: str, value: Any) -> None:
super().__setattr__(name, value)

@classmethod
def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
def from_orm(
cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None
) -> _TSQLModel:
# Duplicated from Pydantic
if not cls.__config__.orm_mode:
raise ConfigError(
Expand All@@ -533,7 +544,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
# End SQLModel support dict
if not getattr(cls.__config__, "table", False):
# If not table, normal Pydantic code
m = cls.__new__(cls)
m: _TSQLModel = cls.__new__(cls)
else:
# If table, create the new instance normally to make SQLAlchemy create
# the _sa_instance_state attribute
Expand All@@ -554,7 +565,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):

@classmethod
def parse_obj(
cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None
cls: Type["SQLModel"], obj: Any, update: Optional[Dict[str, Any]] = None
) -> "SQLModel":
obj = cls._enforce_dict_if_root(obj)
# SQLModel, support update dict
Expand Down
6 changes: 3 additions & 3 deletions sqlmodel/orm/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ def exec(
results = super().execute(
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand All@@ -74,7 +74,7 @@ def execute(
self,
statement: _Executable,
params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None,
execution_options: Mapping[str, Any] = util.EMPTY_DICT,
execution_options: Optional[Mapping[str, Any]] = util.EMPTY_DICT,
bind_arguments: Optional[Mapping[str, Any]] = None,
_parent_execute_state: Optional[Any] = None,
_add_event: Optional[Any] = None,
Expand All@@ -101,7 +101,7 @@ def execute(
return super().execute( # type: ignore
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand Down
4 changes: 1 addition & 3 deletions sqlmodel/sql/base.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,4 @@


class Executable(_Executable, Generic[_T]):
def __init__(self, *args, **kwargs):
self.__dict__["_exec_options"] = kwargs.pop("_exec_options", None)
super(_Executable, self).__init__(*args, **kwargs)
pass
32 changes: 16 additions & 16 deletions sqlmodel/sql/expression.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,10 +45,10 @@ class SelectOfScalar(_Select, Generic[_TSelect]):
class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore
pass

class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

# Cast them for editors to work correctly, from several tricks tried, this works
Expand All@@ -65,9 +65,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_0 = TypeVar(
"_TScalar_0",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -83,9 +83,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_1 = TypeVar(
"_TScalar_1",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -101,9 +101,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_2 = TypeVar(
"_TScalar_2",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -119,9 +119,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_3 = TypeVar(
"_TScalar_3",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand DownExpand Up@@ -446,14 +446,14 @@ def select( # type: ignore
# Generated overloads end


def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]:
def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]: # type: ignore
if len(entities) == 1:
return SelectOfScalar._create(*entities, **kw) # type: ignore
return Select._create(*entities, **kw) # type: ignore


# TODO: add several @overload from Python types to SQLAlchemy equivalents
def col(column_expression: Any) -> ColumnClause:
def col(column_expression: Any) -> ColumnClause: # type: ignore
if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)):
raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
return column_expression
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ sqlalchemy2-stubs = {version = "*", allow-prereleases = true}

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
mypy = "^0.812"
mypy = "^0.910"
flake8 = "^3.9.2"
black = {version = "^21.5-beta.1", python = "^3.7"}
mkdocs = "^1.2.1"
Expand DownExpand Up@@ -98,3 +98,7 @@ warn_return_any = true
implicit_reexport = false
strict_equality = true
# --strict end

[[tool.mypy.overrides]]
module = "sqlmodel.sql.expression"
warn_unused_ignores = false
2 changes: 1 addition & 1 deletion sqlmodel/engine/create.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,4 +136,4 @@ def create_engine(
if not isinstance(query_cache_size, _DefaultPlaceholder):
current_kwargs["query_cache_size"] = query_cache_size
current_kwargs.update(kwargs)
return _create_engine(url, **current_kwargs)
return _create_engine(url, **current_kwargs) # type: ignore
8 changes: 4 additions & 4 deletions sqlmodel/engine/result.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ def __iter__(self) -> Iterator[_T]:
return super().__iter__()

def __next__(self) -> _T:
return super().__next__()
return super().__next__() # type: ignore

def first(self) -> Optional[_T]:
return super().first()
Expand All@@ -32,7 +32,7 @@ def one_or_none(self) -> Optional[_T]:
return super().one_or_none()

def one(self) -> _T:
return super().one()
return super().one() # type: ignore


class Result(_Result, Generic[_T]):
Expand DownExpand Up@@ -70,10 +70,10 @@ def scalar_one(self) -> _T:
return super().scalar_one() # type: ignore

def scalar_one_or_none(self) -> Optional[_T]:
return super().scalar_one_or_none() # type: ignore
return super().scalar_one_or_none()

def one(self) -> _T: # type: ignore
return super().one() # type: ignore

def scalar(self) -> Optional[_T]:
return super().scalar() # type: ignore
return super().scalar()
4 changes: 2 additions & 2 deletions sqlmodel/ext/asyncio/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ def __init__(
self,
bind: Optional[Union[AsyncConnection, AsyncEngine]] = None,
binds: Optional[Mapping[object, Union[AsyncConnection, AsyncEngine]]] = None,
**kw,
**kw: Any,
):
# All the same code of the original AsyncSession
kw["future"] = True
Expand DownExpand Up@@ -52,7 +52,7 @@ async def exec(
# util.immutabledict has the union() method. Is this a bug in SQLAlchemy?
execution_options = execution_options.union({"prebuffer_rows": True}) # type: ignore

return await greenlet_spawn( # type: ignore
return await greenlet_spawn(
self.sync_session.exec,
statement,
params=params,
Expand Down
73 changes: 42 additions & 31 deletions sqlmodel/main.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ def __init__(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> None:
Expand All@@ -127,32 +127,32 @@ def Field(
default: Any = Undefined,
*,
default_factory: Optional[NoArgAnyCallable] = None,
alias: str = None,
title: str = None,
description: str = None,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
exclude: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
include: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
const: bool = None,
gt: float = None,
ge: float = None,
lt: float = None,
le: float = None,
multiple_of: float = None,
min_items: int = None,
max_items: int = None,
min_length: int = None,
max_length: int = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
multiple_of: Optional[float] = None,
min_items: Optional[int] = None,
max_items: Optional[int] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
allow_mutation: bool = True,
regex: str = None,
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
schema_extra: Optional[Dict[str, Any]] = None,
Expand DownExpand Up@@ -195,7 +195,7 @@ def Relationship(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> Any:
Expand All@@ -217,19 +217,25 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):

# Replicate SQLAlchemy
def __setattr__(cls, name: str, value: Any) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__setattr__(cls, name, value)
else:
super().__setattr__(name, value)

def __delattr__(cls, name: str) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__delattr__(cls, name)
else:
super().__delattr__(name)

# From Pydantic
def __new__(cls, name, bases, class_dict: dict, **kwargs) -> Any:
def __new__(
cls,
name: str,
bases: Tuple[Type[Any], ...],
class_dict: Dict[str, Any],
**kwargs: Any,
) -> Any:
relationships: Dict[str, RelationshipInfo] = {}
dict_for_pydantic = {}
original_annotations = resolve_annotations(
Expand DownExpand Up@@ -342,7 +348,7 @@ def __init__(
)
relationship_to = temp_field.type_
if isinstance(temp_field.type_, ForwardRef):
relationship_to = temp_field.type_.__forward_arg__ # type: ignore
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
Expand All@@ -360,7 +366,7 @@ def __init__(
rel_args.extend(rel_info.sa_relationship_args)
if rel_info.sa_relationship_kwargs:
rel_kwargs.update(rel_info.sa_relationship_kwargs)
rel_value: RelationshipProperty = relationship(
rel_value: RelationshipProperty = relationship( # type: ignore
relationship_to, *rel_args, **rel_kwargs
)
dict_used[rel_name] = rel_value
Expand DownExpand Up@@ -408,7 +414,7 @@ def get_sqlachemy_type(field: ModelField) -> Any:
return GUID


def get_column_from_field(field: ModelField) -> Column:
def get_column_from_field(field: ModelField) -> Column: # type: ignore
sa_column = getattr(field.field_info, "sa_column", Undefined)
if isinstance(sa_column, Column):
return sa_column
Expand DownExpand Up@@ -440,10 +446,10 @@ def get_column_from_field(field: ModelField) -> Column:
kwargs["default"] = sa_default
sa_column_args = getattr(field.field_info, "sa_column_args", Undefined)
if sa_column_args is not Undefined:
args.extend(list(cast(Sequence, sa_column_args)))
args.extend(list(cast(Sequence[Any], sa_column_args)))
sa_column_kwargs = getattr(field.field_info, "sa_column_kwargs", Undefined)
if sa_column_kwargs is not Undefined:
kwargs.update(cast(dict, sa_column_kwargs))
kwargs.update(cast(Dict[Any, Any], sa_column_kwargs))
return Column(sa_type, *args, **kwargs)


Expand All@@ -452,24 +458,27 @@ def get_column_from_field(field: ModelField) -> Column:
default_registry = registry()


def _value_items_is_true(v) -> bool:
def _value_items_is_true(v: Any) -> bool:
# Re-implement Pydantic's ValueItems.is_true() as it hasn't been released as of
# the current latest, Pydantic 1.8.2
return v is True or v is ...


_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")


class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry):
# SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
__slots__ = ("__weakref__",)
__tablename__: ClassVar[Union[str, Callable[..., str]]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
__name__: ClassVar[str]
metadata: ClassVar[MetaData]

class Config:
orm_mode = True

def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
# SQLAlchemy doesn't call __init__ on the base class
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
Expand DownExpand Up@@ -520,7 +529,9 @@ def __setattr__(self, name: str, value: Any) -> None:
super().__setattr__(name, value)

@classmethod
def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
def from_orm(
cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None
) -> _TSQLModel:
# Duplicated from Pydantic
if not cls.__config__.orm_mode:
raise ConfigError(
Expand All@@ -533,7 +544,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
# End SQLModel support dict
if not getattr(cls.__config__, "table", False):
# If not table, normal Pydantic code
m = cls.__new__(cls)
m: _TSQLModel = cls.__new__(cls)
else:
# If table, create the new instance normally to make SQLAlchemy create
# the _sa_instance_state attribute
Expand All@@ -554,7 +565,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):

@classmethod
def parse_obj(
cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None
cls: Type["SQLModel"], obj: Any, update: Optional[Dict[str, Any]] = None
) -> "SQLModel":
obj = cls._enforce_dict_if_root(obj)
# SQLModel, support update dict
Expand Down
6 changes: 3 additions & 3 deletions sqlmodel/orm/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ def exec(
results = super().execute(
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand All@@ -74,7 +74,7 @@ def execute(
self,
statement: _Executable,
params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None,
execution_options: Mapping[str, Any] = util.EMPTY_DICT,
execution_options: Optional[Mapping[str, Any]] = util.EMPTY_DICT,
bind_arguments: Optional[Mapping[str, Any]] = None,
_parent_execute_state: Optional[Any] = None,
_add_event: Optional[Any] = None,
Expand All@@ -101,7 +101,7 @@ def execute(
return super().execute( # type: ignore
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand Down
4 changes: 1 addition & 3 deletions sqlmodel/sql/base.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,4 @@


class Executable(_Executable, Generic[_T]):
def __init__(self, *args, **kwargs):
self.__dict__["_exec_options"] = kwargs.pop("_exec_options", None)
super(_Executable, self).__init__(*args, **kwargs)
pass
32 changes: 16 additions & 16 deletions sqlmodel/sql/expression.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,10 +45,10 @@ class SelectOfScalar(_Select, Generic[_TSelect]):
class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore
pass

class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

# Cast them for editors to work correctly, from several tricks tried, this works
Expand All@@ -65,9 +65,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_0 = TypeVar(
"_TScalar_0",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -83,9 +83,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_1 = TypeVar(
"_TScalar_1",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -101,9 +101,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_2 = TypeVar(
"_TScalar_2",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -119,9 +119,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_3 = TypeVar(
"_TScalar_3",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand DownExpand Up@@ -446,14 +446,14 @@ def select( # type: ignore
# Generated overloads end


def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]:
def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]: # type: ignore
if len(entities) == 1:
return SelectOfScalar._create(*entities, **kw) # type: ignore
return Select._create(*entities, **kw) # type: ignore


# TODO: add several @overload from Python types to SQLAlchemy equivalents
def col(column_expression: Any) -> ColumnClause:
def col(column_expression: Any) -> ColumnClause: # type: ignore
if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)):
raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
return column_expression
Loading
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -37,7 +37,7 @@ sqlalchemy2-stubs = {version = "*", allow-prereleases = true}

[tool.poetry.dev-dependencies]
pytest = "^6.2.4"
mypy = "^0.812"
mypy = "^0.910"
flake8 = "^3.9.2"
black = {version = "^21.5-beta.1", python = "^3.7"}
mkdocs = "^1.2.1"
Expand DownExpand Up@@ -98,3 +98,7 @@ warn_return_any = true
implicit_reexport = false
strict_equality = true
# --strict end

[[tool.mypy.overrides]]
module = "sqlmodel.sql.expression"
warn_unused_ignores = false
2 changes: 1 addition & 1 deletion sqlmodel/engine/create.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -136,4 +136,4 @@ def create_engine(
if not isinstance(query_cache_size, _DefaultPlaceholder):
current_kwargs["query_cache_size"] = query_cache_size
current_kwargs.update(kwargs)
return _create_engine(url, **current_kwargs)
return _create_engine(url, **current_kwargs) # type: ignore
8 changes: 4 additions & 4 deletions sqlmodel/engine/result.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,7 +23,7 @@ def __iter__(self) -> Iterator[_T]:
return super().__iter__()

def __next__(self) -> _T:
return super().__next__()
return super().__next__() # type: ignore

def first(self) -> Optional[_T]:
return super().first()
Expand All@@ -32,7 +32,7 @@ def one_or_none(self) -> Optional[_T]:
return super().one_or_none()

def one(self) -> _T:
return super().one()
return super().one() # type: ignore


class Result(_Result, Generic[_T]):
Expand DownExpand Up@@ -70,10 +70,10 @@ def scalar_one(self) -> _T:
return super().scalar_one() # type: ignore

def scalar_one_or_none(self) -> Optional[_T]:
return super().scalar_one_or_none() # type: ignore
return super().scalar_one_or_none()

def one(self) -> _T: # type: ignore
return super().one() # type: ignore

def scalar(self) -> Optional[_T]:
return super().scalar() # type: ignore
return super().scalar()
4 changes: 2 additions & 2 deletions sqlmodel/ext/asyncio/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -21,7 +21,7 @@ def __init__(
self,
bind: Optional[Union[AsyncConnection, AsyncEngine]] = None,
binds: Optional[Mapping[object, Union[AsyncConnection, AsyncEngine]]] = None,
**kw,
**kw: Any,
):
# All the same code of the original AsyncSession
kw["future"] = True
Expand DownExpand Up@@ -52,7 +52,7 @@ async def exec(
# util.immutabledict has the union() method. Is this a bug in SQLAlchemy?
execution_options = execution_options.union({"prebuffer_rows": True}) # type: ignore

return await greenlet_spawn( # type: ignore
return await greenlet_spawn(
self.sync_session.exec,
statement,
params=params,
Expand Down
73 changes: 42 additions & 31 deletions sqlmodel/main.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -101,7 +101,7 @@ def __init__(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> None:
Expand All@@ -127,32 +127,32 @@ def Field(
default: Any = Undefined,
*,
default_factory: Optional[NoArgAnyCallable] = None,
alias: str = None,
title: str = None,
description: str = None,
alias: Optional[str] = None,
title: Optional[str] = None,
description: Optional[str] = None,
exclude: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
include: Union[
AbstractSet[Union[int, str]], Mapping[Union[int, str], Any], Any
] = None,
const: bool = None,
gt: float = None,
ge: float = None,
lt: float = None,
le: float = None,
multiple_of: float = None,
min_items: int = None,
max_items: int = None,
min_length: int = None,
max_length: int = None,
const: Optional[bool] = None,
gt: Optional[float] = None,
ge: Optional[float] = None,
lt: Optional[float] = None,
le: Optional[float] = None,
multiple_of: Optional[float] = None,
min_items: Optional[int] = None,
max_items: Optional[int] = None,
min_length: Optional[int] = None,
max_length: Optional[int] = None,
allow_mutation: bool = True,
regex: str = None,
regex: Optional[str] = None,
primary_key: bool = False,
foreign_key: Optional[Any] = None,
nullable: Union[bool, UndefinedType] = Undefined,
index: Union[bool, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined,
sa_column: Union[Column, UndefinedType] = Undefined, # type: ignore
sa_column_args: Union[Sequence[Any], UndefinedType] = Undefined,
sa_column_kwargs: Union[Mapping[str, Any], UndefinedType] = Undefined,
schema_extra: Optional[Dict[str, Any]] = None,
Expand DownExpand Up@@ -195,7 +195,7 @@ def Relationship(
*,
back_populates: Optional[str] = None,
link_model: Optional[Any] = None,
sa_relationship: Optional[RelationshipProperty] = None,
sa_relationship: Optional[RelationshipProperty] = None, # type: ignore
sa_relationship_args: Optional[Sequence[Any]] = None,
sa_relationship_kwargs: Optional[Mapping[str, Any]] = None,
) -> Any:
Expand All@@ -217,19 +217,25 @@ class SQLModelMetaclass(ModelMetaclass, DeclarativeMeta):

# Replicate SQLAlchemy
def __setattr__(cls, name: str, value: Any) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__setattr__(cls, name, value)
else:
super().__setattr__(name, value)

def __delattr__(cls, name: str) -> None:
if getattr(cls.__config__, "table", False): # type: ignore
if getattr(cls.__config__, "table", False):
DeclarativeMeta.__delattr__(cls, name)
else:
super().__delattr__(name)

# From Pydantic
def __new__(cls, name, bases, class_dict: dict, **kwargs) -> Any:
def __new__(
cls,
name: str,
bases: Tuple[Type[Any], ...],
class_dict: Dict[str, Any],
**kwargs: Any,
) -> Any:
relationships: Dict[str, RelationshipInfo] = {}
dict_for_pydantic = {}
original_annotations = resolve_annotations(
Expand DownExpand Up@@ -342,7 +348,7 @@ def __init__(
)
relationship_to = temp_field.type_
if isinstance(temp_field.type_, ForwardRef):
relationship_to = temp_field.type_.__forward_arg__ # type: ignore
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
Expand All@@ -360,7 +366,7 @@ def __init__(
rel_args.extend(rel_info.sa_relationship_args)
if rel_info.sa_relationship_kwargs:
rel_kwargs.update(rel_info.sa_relationship_kwargs)
rel_value: RelationshipProperty = relationship(
rel_value: RelationshipProperty = relationship( # type: ignore
relationship_to, *rel_args, **rel_kwargs
)
dict_used[rel_name] = rel_value
Expand DownExpand Up@@ -408,7 +414,7 @@ def get_sqlachemy_type(field: ModelField) -> Any:
return GUID


def get_column_from_field(field: ModelField) -> Column:
def get_column_from_field(field: ModelField) -> Column: # type: ignore
sa_column = getattr(field.field_info, "sa_column", Undefined)
if isinstance(sa_column, Column):
return sa_column
Expand DownExpand Up@@ -440,10 +446,10 @@ def get_column_from_field(field: ModelField) -> Column:
kwargs["default"] = sa_default
sa_column_args = getattr(field.field_info, "sa_column_args", Undefined)
if sa_column_args is not Undefined:
args.extend(list(cast(Sequence, sa_column_args)))
args.extend(list(cast(Sequence[Any], sa_column_args)))
sa_column_kwargs = getattr(field.field_info, "sa_column_kwargs", Undefined)
if sa_column_kwargs is not Undefined:
kwargs.update(cast(dict, sa_column_kwargs))
kwargs.update(cast(Dict[Any, Any], sa_column_kwargs))
return Column(sa_type, *args, **kwargs)


Expand All@@ -452,24 +458,27 @@ def get_column_from_field(field: ModelField) -> Column:
default_registry = registry()


def _value_items_is_true(v) -> bool:
def _value_items_is_true(v: Any) -> bool:
# Re-implement Pydantic's ValueItems.is_true() as it hasn't been released as of
# the current latest, Pydantic 1.8.2
return v is True or v is ...


_TSQLModel = TypeVar("_TSQLModel", bound="SQLModel")


class SQLModel(BaseModel, metaclass=SQLModelMetaclass, registry=default_registry):
# SQLAlchemy needs to set weakref(s), Pydantic will set the other slots values
__slots__ = ("__weakref__",)
__tablename__: ClassVar[Union[str, Callable[..., str]]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]]
__sqlmodel_relationships__: ClassVar[Dict[str, RelationshipProperty]] # type: ignore
__name__: ClassVar[str]
metadata: ClassVar[MetaData]

class Config:
orm_mode = True

def __new__(cls, *args, **kwargs) -> Any:
def __new__(cls, *args: Any, **kwargs: Any) -> Any:
new_object = super().__new__(cls)
# SQLAlchemy doesn't call __init__ on the base class
# Ref: https://docs.sqlalchemy.org/en/14/orm/constructors.html
Expand DownExpand Up@@ -520,7 +529,9 @@ def __setattr__(self, name: str, value: Any) -> None:
super().__setattr__(name, value)

@classmethod
def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
def from_orm(
cls: Type[_TSQLModel], obj: Any, update: Optional[Dict[str, Any]] = None
) -> _TSQLModel:
# Duplicated from Pydantic
if not cls.__config__.orm_mode:
raise ConfigError(
Expand All@@ -533,7 +544,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):
# End SQLModel support dict
if not getattr(cls.__config__, "table", False):
# If not table, normal Pydantic code
m = cls.__new__(cls)
m: _TSQLModel = cls.__new__(cls)
else:
# If table, create the new instance normally to make SQLAlchemy create
# the _sa_instance_state attribute
Expand All@@ -554,7 +565,7 @@ def from_orm(cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None):

@classmethod
def parse_obj(
cls: Type["SQLModel"], obj: Any, update: Dict[str, Any] = None
cls: Type["SQLModel"], obj: Any, update: Optional[Dict[str, Any]] = None
) -> "SQLModel":
obj = cls._enforce_dict_if_root(obj)
# SQLModel, support update dict
Expand Down
6 changes: 3 additions & 3 deletions sqlmodel/orm/session.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -60,7 +60,7 @@ def exec(
results = super().execute(
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand All@@ -74,7 +74,7 @@ def execute(
self,
statement: _Executable,
params: Optional[Union[Mapping[str, Any], Sequence[Mapping[str, Any]]]] = None,
execution_options: Mapping[str, Any] = util.EMPTY_DICT,
execution_options: Optional[Mapping[str, Any]] = util.EMPTY_DICT,
bind_arguments: Optional[Mapping[str, Any]] = None,
_parent_execute_state: Optional[Any] = None,
_add_event: Optional[Any] = None,
Expand All@@ -101,7 +101,7 @@ def execute(
return super().execute( # type: ignore
statement,
params=params,
execution_options=execution_options, # type: ignore
execution_options=execution_options,
bind_arguments=bind_arguments,
_parent_execute_state=_parent_execute_state,
_add_event=_add_event,
Expand Down
4 changes: 1 addition & 3 deletions sqlmodel/sql/base.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,4 @@


class Executable(_Executable, Generic[_T]):
def __init__(self, *args, **kwargs):
self.__dict__["_exec_options"] = kwargs.pop("_exec_options", None)
super(_Executable, self).__init__(*args, **kwargs)
pass
32 changes: 16 additions & 16 deletions sqlmodel/sql/expression.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -45,10 +45,10 @@ class SelectOfScalar(_Select, Generic[_TSelect]):
class GenericSelectMeta(GenericMeta, _Select.__class__): # type: ignore
pass

class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36Select(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta): # type: ignore
class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMeta):
pass

# Cast them for editors to work correctly, from several tricks tried, this works
Expand All@@ -65,9 +65,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_0 = TypeVar(
"_TScalar_0",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -83,9 +83,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_1 = TypeVar(
"_TScalar_1",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -101,9 +101,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_2 = TypeVar(
"_TScalar_2",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand All@@ -119,9 +119,9 @@ class _Py36SelectOfScalar(_Select, Generic[_TSelect], metaclass=GenericSelectMet

_TScalar_3 = TypeVar(
"_TScalar_3",
Column,
Sequence,
Mapping,
Column, # type: ignore
Sequence, # type: ignore
Mapping, # type: ignore
UUID,
datetime,
float,
Expand DownExpand Up@@ -446,14 +446,14 @@ def select( # type: ignore
# Generated overloads end


def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]:
def select(*entities: Any, **kw: Any) -> Union[Select, SelectOfScalar]: # type: ignore
if len(entities) == 1:
return SelectOfScalar._create(*entities, **kw) # type: ignore
return Select._create(*entities, **kw) # type: ignore


# TODO: add several @overload from Python types to SQLAlchemy equivalents
def col(column_expression: Any) -> ColumnClause:
def col(column_expression: Any) -> ColumnClause: # type: ignore
if not isinstance(column_expression, (ColumnClause, Column, InstrumentedAttribute)):
raise RuntimeError(f"Not a SQLAlchemy column: {column_expression}")
return column_expression
Loading