From 6ee19ca3c1e1540e023ee8e1a40cfea8c44d24b9 Mon Sep 17 00:00:00 2001 From: huangsong Date: Sun, 29 Jan 2023 14:31:41 +0800 Subject: [PATCH 1/6] fix typo --- ormar/fields/foreign_key.py | 4 ++-- ormar/models/metaclass.py | 47 ++++++++++++++++++++++--------------- ormar/signals/signal.py | 2 +- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/ormar/fields/foreign_key.py b/ormar/fields/foreign_key.py index cfa2205ba..295bdaf93 100644 --- a/ormar/fields/foreign_key.py +++ b/ormar/fields/foreign_key.py @@ -298,8 +298,8 @@ def ForeignKey( # type: ignore # noqa CFQ002 skip_field=skip_field, ) - Field = type("ForeignKey", (ForeignKeyField, BaseField), {}) - return Field(**namespace) + field_class = type("ForeignKey", (ForeignKeyField, BaseField), {}) + return field_class(**namespace) class ForeignKeyField(BaseField): diff --git a/ormar/models/metaclass.py b/ormar/models/metaclass.py index 36a3e7488..aed13ce4a 100644 --- a/ormar/models/metaclass.py +++ b/ormar/models/metaclass.py @@ -67,7 +67,7 @@ class ModelMeta: """ Class used for type hinting. - Users can subclass this one for convenience but it's not required. + Users can subclass this one for convenience, but it's not required. The only requirement is that ormar.Model has to have inner class with name Meta. """ @@ -142,7 +142,7 @@ def add_property_fields(new_model: Type["Model"], attrs: Dict) -> None: # noqa: def register_signals(new_model: Type["Model"]) -> None: # noqa: CCR001 """ - Registers on model's SignalEmmiter and sets pre defined signals. + Registers on model's SignalEmitter and sets pre_defined signals. Predefined signals are (pre/post) + (save/update/delete). Signals are emitted in both model own methods and in selected queryset ones. @@ -201,11 +201,11 @@ def get_constraint_copy( constraint: ColumnCollectionConstraint, ) -> Union[UniqueColumns, IndexColumns, CheckColumns]: """ - Copy the constraint and unpacking it's values + Copy the constraint and unpacking its values :raises ValueError: if non subclass of ColumnCollectionConstraint - :param value: an instance of the ColumnCollectionConstraint class - :type value: Instance of ColumnCollectionConstraint child + :param constraint: an instance of the ColumnCollectionConstraint class + :type constraint: Instance of ColumnCollectionConstraint child :return: copy ColumnCollectionConstraint ormar constraints :rtype: Union[UniqueColumns, IndexColumns, CheckColumns] """ @@ -258,6 +258,23 @@ def update_attrs_from_base_meta( # noqa: CCR001 setattr(attrs["Meta"], param, parent_value) +def _get_copy_field( + field: Union[ManyToManyField, ForeignKeyField], table_name: str, + copy_field_type: Union[BaseField, ForeignKeyField, ManyToManyField] +) -> Union[ForeignKeyField, ManyToManyField]: + """ + Copy field by field and table_name. + """ + + field_class: Type[copy_field_type] = type( # type: ignore + field.__class__.__name__, (copy_field_type, BaseField), {} + ) + copy_field = field_class(**dict(field.__dict__)) + related_name = field.related_name + "_" + table_name + copy_field.related_name = related_name # type: ignore + return copy_field + + def copy_and_replace_m2m_through_model( # noqa: CFQ002 field: ManyToManyField, field_name: str, @@ -294,12 +311,8 @@ def copy_and_replace_m2m_through_model( # noqa: CFQ002 :param meta: metaclass of currently created model :type meta: ModelMeta """ - Field: Type[BaseField] = type( # type: ignore - field.__class__.__name__, (ManyToManyField, BaseField), {} - ) - copy_field = Field(**dict(field.__dict__)) - related_name = field.related_name + "_" + table_name - copy_field.related_name = related_name # type: ignore + + copy_field: ManyToManyField = _get_copy_field(field, table_name, ManyToManyField) through_class = field.through if not through_class: @@ -402,12 +415,8 @@ def copy_data_from_parent_model( # noqa: CCR001 ) elif field.is_relation and field.related_name: - Field = type( # type: ignore - field.__class__.__name__, (ForeignKeyField, BaseField), {} - ) - copy_field = Field(**dict(field.__dict__)) - related_name = field.related_name + "_" + table_name - copy_field.related_name = related_name # type: ignore + copy_field: ForeignKeyField = _get_copy_field( + field, table_name, ForeignKeyField) parent_fields[field_name] = copy_field else: parent_fields[field_name] = field @@ -433,7 +442,7 @@ def extract_from_parents_definition( # noqa: CCR001 If the class is parsed first time annotations and field definition is parsed from the class.__dict__. - If the class is a ormar.Model it is skipped. + If the class is an ormar.Model it is skipped. :param base_class: one of the parent classes :type base_class: Model or model parent class @@ -537,7 +546,7 @@ def add_field_descriptor( :param field: model field to add descriptor for :type field: BaseField :param new_model: model with fields - :type new_model: Type["Model] + :type new_model: Type["Model"] """ if field.is_relation: setattr(new_model, name, RelationDescriptor(name=name)) diff --git a/ormar/signals/signal.py b/ormar/signals/signal.py index 868b494ec..dcbf85efa 100644 --- a/ormar/signals/signal.py +++ b/ormar/signals/signal.py @@ -99,7 +99,7 @@ async def send(self, sender: Type["Model"], **kwargs: Any) -> None: class SignalEmitter(dict): """ Emitter that registers the signals in internal dictionary. - If signal with given name does not exist it's auto added on access. + If signal with given name does not exist its auto added on access. """ def __getattr__(self, item: str) -> Signal: From 5b7eec4ea75b3ae68caab15e7b463eb0fcad11f5 Mon Sep 17 00:00:00 2001 From: huangsong Date: Sun, 29 Jan 2023 14:41:31 +0800 Subject: [PATCH 2/6] fix the doc: issue-967 --- ormar/queryset/queryset.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/ormar/queryset/queryset.py b/ormar/queryset/queryset.py index ae2f04039..e7d417241 100644 --- a/ormar/queryset/queryset.py +++ b/ormar/queryset/queryset.py @@ -893,8 +893,6 @@ async def first(self, *args: Any, **kwargs: Any) -> "T": """ Gets the first row from the db ordered by primary key column ascending. - :raises NoMatch: if no rows are returned - :raises MultipleMatches: if more than 1 row is returned. :param kwargs: fields names and proper value types :type kwargs: Any :return: returned model From a64939eda958cb311c93ff611faadba733613885 Mon Sep 17 00:00:00 2001 From: huangsong Date: Sun, 29 Jan 2023 15:34:02 +0800 Subject: [PATCH 3/6] add cache: the result is static, don't need cal again --- ormar/queryset/utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ormar/queryset/utils.py b/ormar/queryset/utils.py index 4ebe07c7f..e45dd0e36 100644 --- a/ormar/queryset/utils.py +++ b/ormar/queryset/utils.py @@ -12,6 +12,7 @@ Type, Union, ) +from functools import lru_cache if TYPE_CHECKING: # pragma no cover from ormar import Model, BaseField @@ -41,6 +42,7 @@ def check_node_not_dict_or_not_last_node( ) +@lru_cache(maxsize=128) def translate_list_to_dict( # noqa: CCR001 list_to_trans: Union[List, Set], is_order: bool = False ) -> Dict: From b501ca9d84616fb2c71b00f1090fbff3396c7b5b Mon Sep 17 00:00:00 2001 From: huangsong Date: Sun, 29 Jan 2023 15:46:44 +0800 Subject: [PATCH 4/6] fix hash-type --- ormar/queryset/utils.py | 49 ++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 23 deletions(-) diff --git a/ormar/queryset/utils.py b/ormar/queryset/utils.py index e45dd0e36..9e1848ab9 100644 --- a/ormar/queryset/utils.py +++ b/ormar/queryset/utils.py @@ -42,7 +42,6 @@ def check_node_not_dict_or_not_last_node( ) -@lru_cache(maxsize=128) def translate_list_to_dict( # noqa: CCR001 list_to_trans: Union[List, Set], is_order: bool = False ) -> Dict: @@ -61,28 +60,32 @@ def translate_list_to_dict( # noqa: CCR001 :return: converted to dictionary input list :rtype: Dict """ - new_dict: Dict = dict() - for path in list_to_trans: - current_level = new_dict - parts = path.split("__") - def_val: Any = ... - if is_order: - if parts[0][0] == "-": - def_val = "desc" - parts[0] = parts[0][1:] - else: - def_val = "asc" - - for ind, part in enumerate(parts): - is_last = ind == len(parts) - 1 - if check_node_not_dict_or_not_last_node( - part=part, is_last=is_last, current_level=current_level - ): - current_level[part] = dict() - elif part not in current_level: - current_level[part] = def_val - current_level = current_level[part] - return new_dict + @lru_cache(maxsize=128) + def _translate(translate_set: str): + new_dict: Dict = dict() + for path in translate_set.split(":"): + current_level = new_dict + parts = path.split("__") + def_val: Any = ... + if is_order: + if parts[0][0] == "-": + def_val = "desc" + parts[0] = parts[0][1:] + else: + def_val = "asc" + + for ind, part in enumerate(parts): + is_last = ind == len(parts) - 1 + if check_node_not_dict_or_not_last_node( + part=part, is_last=is_last, current_level=current_level + ): + current_level[part] = dict() + elif part not in current_level: + current_level[part] = def_val + current_level = current_level[part] + return new_dict + + return dict() if not list_to_trans else _translate(":".join(sorted(list_to_trans))) def convert_set_to_required_dict(set_to_convert: set) -> Dict: From 4229d5416cebf983a65d47e21ea6eef7c2347372 Mon Sep 17 00:00:00 2001 From: huangsong Date: Sun, 29 Jan 2023 15:57:04 +0800 Subject: [PATCH 5/6] fix typo word --- ormar/models/metaclass.py | 41 +++++++++++++++------------------------ 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/ormar/models/metaclass.py b/ormar/models/metaclass.py index aed13ce4a..a3ca8d00b 100644 --- a/ormar/models/metaclass.py +++ b/ormar/models/metaclass.py @@ -67,7 +67,7 @@ class ModelMeta: """ Class used for type hinting. - Users can subclass this one for convenience, but it's not required. + Users can subclass this one for convenience but it's not required. The only requirement is that ormar.Model has to have inner class with name Meta. """ @@ -142,7 +142,7 @@ def add_property_fields(new_model: Type["Model"], attrs: Dict) -> None: # noqa: def register_signals(new_model: Type["Model"]) -> None: # noqa: CCR001 """ - Registers on model's SignalEmitter and sets pre_defined signals. + Registers on model's SignalEmmiter and sets pre defined signals. Predefined signals are (pre/post) + (save/update/delete). Signals are emitted in both model own methods and in selected queryset ones. @@ -204,8 +204,8 @@ def get_constraint_copy( Copy the constraint and unpacking its values :raises ValueError: if non subclass of ColumnCollectionConstraint - :param constraint: an instance of the ColumnCollectionConstraint class - :type constraint: Instance of ColumnCollectionConstraint child + :param value: an instance of the ColumnCollectionConstraint class + :type value: Instance of ColumnCollectionConstraint child :return: copy ColumnCollectionConstraint ormar constraints :rtype: Union[UniqueColumns, IndexColumns, CheckColumns] """ @@ -258,23 +258,6 @@ def update_attrs_from_base_meta( # noqa: CCR001 setattr(attrs["Meta"], param, parent_value) -def _get_copy_field( - field: Union[ManyToManyField, ForeignKeyField], table_name: str, - copy_field_type: Union[BaseField, ForeignKeyField, ManyToManyField] -) -> Union[ForeignKeyField, ManyToManyField]: - """ - Copy field by field and table_name. - """ - - field_class: Type[copy_field_type] = type( # type: ignore - field.__class__.__name__, (copy_field_type, BaseField), {} - ) - copy_field = field_class(**dict(field.__dict__)) - related_name = field.related_name + "_" + table_name - copy_field.related_name = related_name # type: ignore - return copy_field - - def copy_and_replace_m2m_through_model( # noqa: CFQ002 field: ManyToManyField, field_name: str, @@ -311,8 +294,12 @@ def copy_and_replace_m2m_through_model( # noqa: CFQ002 :param meta: metaclass of currently created model :type meta: ModelMeta """ - - copy_field: ManyToManyField = _get_copy_field(field, table_name, ManyToManyField) + Field: Type[BaseField] = type( # type: ignore + field.__class__.__name__, (ManyToManyField, BaseField), {} + ) + copy_field = Field(**dict(field.__dict__)) + related_name = field.related_name + "_" + table_name + copy_field.related_name = related_name # type: ignore through_class = field.through if not through_class: @@ -415,8 +402,12 @@ def copy_data_from_parent_model( # noqa: CCR001 ) elif field.is_relation and field.related_name: - copy_field: ForeignKeyField = _get_copy_field( - field, table_name, ForeignKeyField) + Field = type( # type: ignore + field.__class__.__name__, (ForeignKeyField, BaseField), {} + ) + copy_field = Field(**dict(field.__dict__)) + related_name = field.related_name + "_" + table_name + copy_field.related_name = related_name # type: ignore parent_fields[field_name] = copy_field else: parent_fields[field_name] = field From c7e0d9cc94d007236c54ee8f8e5e8709f3b14401 Mon Sep 17 00:00:00 2001 From: huangsong Date: Sun, 29 Jan 2023 15:57:32 +0800 Subject: [PATCH 6/6] add fn return annotation --- ormar/queryset/utils.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ormar/queryset/utils.py b/ormar/queryset/utils.py index 9e1848ab9..31c39da32 100644 --- a/ormar/queryset/utils.py +++ b/ormar/queryset/utils.py @@ -61,7 +61,7 @@ def translate_list_to_dict( # noqa: CCR001 :rtype: Dict """ @lru_cache(maxsize=128) - def _translate(translate_set: str): + def _translate(translate_set: str) -> Dict: new_dict: Dict = dict() for path in translate_set.split(":"): current_level = new_dict