Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Python annotations to have type hints #97

Merged
merged 5 commits into from
Jun 8, 2024
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
2 changes: 2 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,5 @@ repos:
rev: v3.3.1
hooks:
- id: pyupgrade
args:
- "--keep-runtime-typing"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does it?

Copy link
Collaborator Author

@gacarrillor gacarrillor Jun 7, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Without it, pyupgrade changes Optional/Union statements by new syntax "a | b" (Python v3.10+), which won't be completely backwards compatible (namely, there might be issues with runtime operations like isinstance(obj, str | int)).

14 changes: 10 additions & 4 deletions modelbaker/dataobjects/fields.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,18 @@
* *
***************************************************************************/
"""
from __future__ import annotations

from typing import TYPE_CHECKING

from qgis.core import QgsDefaultValue, QgsEditorWidgetSetup

if TYPE_CHECKING:
from modelbaker.dataobjects.layers import Layer


class Field:
def __init__(self, name):
def __init__(self, name: str) -> None:
self.name = name
self.alias = None
self.read_only = False
Expand All @@ -31,18 +37,18 @@ def __init__(self, name):
self.enum_domain = None
self.oid_domain = None

def dump(self):
def dump(self) -> dict:
definition = dict()
if self.alias:
definition["alias"] = self.alias

return definition

def load(self, definition):
def load(self, definition: dict) -> None:
if "alias" in definition:
self.alias = definition["alias"]

def create(self, layer):
def create(self, layer: Layer) -> None:
field_idx = layer.layer.fields().indexOf(self.name)

if self.alias:
Expand Down
148 changes: 84 additions & 64 deletions modelbaker/dataobjects/form.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,24 +16,101 @@
* *
***************************************************************************/
"""
from __future__ import annotations

from typing import TYPE_CHECKING, Optional, Union

from qgis.core import (
Qgis,
QgsAttributeEditorContainer,
QgsAttributeEditorElement,
QgsAttributeEditorField,
QgsAttributeEditorRelation,
QgsEditFormConfig,
QgsVectorLayer,
)

if TYPE_CHECKING:
from modelbaker.dataobjects.layers import Layer
from modelbaker.dataobjects.project import Project
from modelbaker.dataobjects.relations import Relation


class FormFieldWidget:
def __init__(self, name: str, field_name: str) -> None:
self.name = name if name else field_name
self.field_name = field_name

def create(
self, parent: QgsAttributeEditorElement, layer: QgsVectorLayer
) -> QgsAttributeEditorField:
index = layer.fields().indexOf(self.field_name)
widget = QgsAttributeEditorField(self.field_name, index, parent)
return widget


class FormRelationWidget:
def __init__(
self, relation: Relation, nm_relation: Optional[Relation] = None
) -> None:
self.relation = relation
self.nm_relation = nm_relation

def create(
self, parent: QgsAttributeEditorElement, _layer
) -> QgsAttributeEditorRelation:
try:
widget = QgsAttributeEditorRelation(self.relation.id, parent)
except TypeError:
# Feed deprecated API for 3.0.0 and 3.0.1
widget = QgsAttributeEditorRelation(
self.relation.id, self.relation.id, parent
)
if self.nm_relation:
widget.setNmRelationId(self.nm_relation.id)

if Qgis.QGIS_VERSION_INT >= 31800:
widget.setRelationWidgetTypeId("linking_relation_editor")

if not self.nm_relation and self.relation.cardinality_max == "1":
configuration = widget.relationEditorConfiguration()
configuration["one_to_one"] = True
widget.setRelationEditorConfiguration(configuration)

return widget


class FormTab:
def __init__(self, name: str, columns: int = 1) -> None:
self.name = name
self.children = list()
self.columns = columns

def addChild(self, child: Union[FormFieldWidget, FormRelationWidget]) -> None:
self.children.append(child)

def create(
self, parent: QgsAttributeEditorElement, layer: QgsVectorLayer
) -> QgsAttributeEditorContainer:
container = QgsAttributeEditorContainer(self.name, parent)
container.setIsGroupBox(False)
container.setColumnCount(self.columns)

for child in self.children:
container.addChildElement(child.create(container, layer))
return container


class Form:
def __init__(self):
def __init__(self) -> None:
self.__elements = list()

def elements(self):
def elements(self) -> list[Union[FormFieldWidget, FormRelationWidget]]:
return self.__elements

def create(self, layer, qgis_layer, project):
def create(
self, layer: Layer, qgis_layer: QgsVectorLayer, project: Project
) -> QgsEditFormConfig:
edit_form_config = qgis_layer.editFormConfig()
root_container = edit_form_config.invisibleRootContainer()
root_container.clear()
Expand All @@ -58,81 +135,24 @@ def create(self, layer, qgis_layer, project):
break
return edit_form_config

def add_element(self, element):
def add_element(self, element: Union[FormTab, FormFieldWidget]) -> None:
self.__elements.append(element)


class FormTab:
def __init__(self, name, columns=1):
self.name = name
self.children = list()
self.columns = columns

def addChild(self, child):
self.children.append(child)

def create(self, parent, layer):
container = QgsAttributeEditorContainer(self.name, parent)
container.setIsGroupBox(False)
container.setColumnCount(self.columns)

for child in self.children:
container.addChildElement(child.create(container, layer))
return container


class FormGroupBox:
def __init__(self, name, columns=1):
def __init__(self, name: str, columns: int = 1) -> None:
self.name = name
self.children = list()
self.columns = columns

def addChild(self, child):
def addChild(self, child) -> None:
self.children.append(child)

def create(self, parent, layer):
def create(self, _parent, layer) -> QgsAttributeEditorContainer:
container = QgsAttributeEditorContainer(self.name)
container.setIsGroupBox(True)
container.setColumnCount(self.columns)

for child in self.children:
container.addChildElement(child, layer)
return container


class FormFieldWidget:
def __init__(self, name, field_name):
self.name = name if name else field_name
self.field_name = field_name

def create(self, parent, layer):
index = layer.fields().indexOf(self.field_name)
widget = QgsAttributeEditorField(self.field_name, index, parent)
return widget


class FormRelationWidget:
def __init__(self, relation, nm_relation=None):
self.relation = relation
self.nm_relation = nm_relation

def create(self, parent, layer):
try:
widget = QgsAttributeEditorRelation(self.relation.id, parent)
except TypeError:
# Feed deprecated API for 3.0.0 and 3.0.1
widget = QgsAttributeEditorRelation(
self.relation.id, self.relation.id, parent
)
if self.nm_relation:
widget.setNmRelationId(self.nm_relation.id)

if Qgis.QGIS_VERSION_INT >= 31800:
widget.setRelationWidgetTypeId("linking_relation_editor")

if not self.nm_relation and self.relation.cardinality_max == "1":
configuration = widget.relationEditorConfiguration()
configuration["one_to_one"] = True
widget.setRelationEditorConfiguration(configuration)

return widget
Loading
Loading