diff --git a/.bandit.yaml b/.bandit.yaml
deleted file mode 100644
index a04a4bb1dca..00000000000
--- a/.bandit.yaml
+++ /dev/null
@@ -1,31 +0,0 @@
-profile:
- sql:
- exclude:
- - /commons/c2cgeoportal_commons/alembic/main/
- - /commons/c2cgeoportal_commons/alembic/static/
- tests:
- - B608 # Possible SQL injection vector through string-based query construction.
- subprocess:
- exclude:
- - /commons/c2cgeoportal_commons/testing/
- - /commons/tests/
- - /geoportal/tests/
- - /geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py
- - /admin/tests/
- tests:
- - B603 # subprocess call - check for execution of untrusted input.
- - B607 # Starting a process with a partial executable path
- - B404 # Consider possible security implications associated with call module.
- tmp:
- exclude:
- - /geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py
- tests:
- - B108 # Probable insecure usage of temp file/directory.
-skips:
- - B101 # Test for use of assert
- - B603 # subprocess call - check for execution of untrusted input.
- - B607 # Starting a process with a partial executable path
- - B608 # Possible SQL injection vector through string-based query construction.
- - B108 # Probable insecure usage of temp file/directory.
- - B404 # Consider possible security implications associated with call module.
- - B113 # Requests call without timeout. Done by c2cwsgiutils
diff --git a/.github/workflows/main.yaml b/.github/workflows/main.yaml
index 0688a4e1c0a..58ef79b7329 100644
--- a/.github/workflows/main.yaml
+++ b/.github/workflows/main.yaml
@@ -34,7 +34,7 @@ jobs:
# When we upgrade this we should also upgrade the requirements
# in the documentation: doc/integrator/requirements.rst
# and the first pyupgrade pre-commit hook in .pre-commit-config.yaml
- MIN_PYTHON_VERSION: '3.8'
+ MIN_PYTHON_VERSION: '3.10'
steps:
- run: '! ls BACKPORT_TODO'
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
index 3be1489d3b7..274d5b640eb 100644
--- a/.pre-commit-config.yaml
+++ b/.pre-commit-config.yaml
@@ -104,64 +104,28 @@ repos:
docker/config/haproxy_dev/localhost\.pem
|geoportal/c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter\.project}}/mapserver/data/TM_EUROPE_BORDERS-0.3\.sql
)$
- - repo: https://github.com/asottile/pyupgrade
- rev: v3.19.0
+ - repo: https://github.com/astral-sh/ruff-pre-commit
+ rev: v0.8.1
hooks:
- # The script that will run on the project host
- - id: pyupgrade
+ - id: ruff-format
args:
- - --py38-plus
- files: |-
- (?x)^(
- geoportal/c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter\.project}}/(build
- |scripts/.*)
- |scripts/(get-version
- |upgrade)
- )$
- # All other
- - id: pyupgrade
- args:
- - --py310-plus
- # geoportal/c2cgeoportal_geoportal/views/theme\.py is present because of issue:
- # https://bugs.launchpad.net/lxml/+bug/2079018
- exclude: |-
- (?x)^(
- geoportal/c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter\.project}}/(build
- |scripts/.*)
- |scripts/(get-version
- |upgrade)
- |geoportal/c2cgeoportal_geoportal/views/theme\.py
- )$
- - repo: https://github.com/PyCQA/autoflake
- rev: v2.3.1
- hooks:
- - id: autoflake
- - repo: https://github.com/PyCQA/isort
- rev: 5.13.2
- hooks:
- - id: isort
- - repo: https://github.com/psf/black
- rev: 24.10.0
- hooks:
- - id: black
+ - --line-length=110
exclude: |-
(?x)^(
- commons/c2cgeoportal_commons/alembic/script\.py\.mako
- |.*\.rst
- |.*\.rst\.tmpl
- |geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__\.py
+ geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/__init__\.py
)$
- repo: https://github.com/PyCQA/prospector
rev: v1.13.3
hooks:
- id: prospector
args:
- - --tool=pydocstyle
+ - --tool=ruff
- --die-on-tool-error
- --output-format=pylint
additional_dependencies:
- - prospector-profile-duplicated==1.8.0 # pypi
+ - prospector-profile-duplicated==1.8.1 # pypi
- prospector-profile-utils==1.13.0 # pypi
+ - ruff==0.8.1 # pypi
- repo: https://github.com/sbrunner/jsonschema-validator
rev: 0.3.2
hooks:
diff --git a/.prospector.yaml b/.prospector.yaml
index 95964a60c7a..c6b2c654c5d 100644
--- a/.prospector.yaml
+++ b/.prospector.yaml
@@ -3,6 +3,8 @@ inherits:
- utils:base
- utils:fix
- utils:no-design-checks
+ - utils:unsafe
+ - utils:c2cwsgiutils
ignore-paths:
- commons/setup.py
@@ -10,28 +12,14 @@ ignore-paths:
- admin/setup.py
- geoportal/c2cgeoportal_geoportal/scaffolds
- docker/qgisserver
+ - commons/c2cgeoportal_commons/alembic/main
+ - commons/c2cgeoportal_commons/alembic/static
-pycodestyle:
- disable:
- # Buggy checks with Python 3.12
- - W604 # backticks are deprecated, use 'repr()'
- - W603 # '<>' is deprecated, use '!='
- - E702 # multiple statements on one line (semicolon)
- - E713 # test for membership should be 'not in'
+mypy:
+ options:
+ python_version: '3.10'
-pydocstyle:
+ruff:
disable:
- D102 # Missing docstring in public method
- - D104 # Missing docstring in public package
- - D105 # Missing docstring in magic method
- - D107 # Missing docstring in __init__
- - D200 # One-line docstring should fit on one line with quotes
- - D202 # No blank lines allowed after function docstring (found 1)
- - D203 # 1 blank line required before class docstring (found 0)
- - D212 # Multi-line docstring summary should start at the first line
- - D407 # Missing dashed underline after section ('Arguments')
- - D412 # No blank lines allowed between a section header and its content ('Arguments')
-
-bandit:
- options:
- config: .bandit.yaml
+ - D107 # Missing docstring in `__init__`
diff --git a/admin/c2cgeoportal_admin/__init__.py b/admin/c2cgeoportal_admin/__init__.py
index 4d4227d3880..2747e3c5a7a 100644
--- a/admin/c2cgeoportal_admin/__init__.py
+++ b/admin/c2cgeoportal_admin/__init__.py
@@ -93,7 +93,9 @@ def get_tm_session(
)
# Add fake user as we do not have authentication from geoportal
- from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.static import ( # pylint: disable=import-outside-toplevel
+ User,
+ )
config.add_request_method(
lambda request: User(
diff --git a/admin/c2cgeoportal_admin/lib/ogcserver_synchronizer.py b/admin/c2cgeoportal_admin/lib/ogcserver_synchronizer.py
index 64905a6f478..3ca3f034449 100644
--- a/admin/c2cgeoportal_admin/lib/ogcserver_synchronizer.py
+++ b/admin/c2cgeoportal_admin/lib/ogcserver_synchronizer.py
@@ -29,16 +29,15 @@
import functools
import logging
from io import StringIO
-from typing import Any, Optional, cast
+from typing import Any, cast
from xml.etree.ElementTree import Element # nosec
import pyramid.request
import requests
-from defusedxml import ElementTree
-from sqlalchemy.orm.session import Session
-
from c2cgeoportal_commons.lib.url import get_url2
from c2cgeoportal_commons.models import main
+from defusedxml import ElementTree
+from sqlalchemy.orm.session import Session
class dry_run_transaction: # noqa ignore=N801: class names should use CapWords convention
@@ -238,7 +237,7 @@ def get_theme(self, el: ElementTree) -> main.Theme:
name = name_el.text
theme = cast(
- Optional[main.Theme],
+ main.Theme | None,
self._request.dbsession.query(main.Theme).filter(main.Theme.name == name).one_or_none(),
)
@@ -263,7 +262,7 @@ def get_layer_group(self, el: Element, parent: main.TreeGroup) -> main.LayerGrou
assert name is not None
group = cast(
- Optional[main.LayerGroup],
+ main.LayerGroup | None,
(
self._request.dbsession.query(main.LayerGroup)
.filter(main.LayerGroup.name == name)
@@ -294,7 +293,7 @@ def get_layer_wms(self, el: Element, parent: main.TreeGroup | None = None) -> ma
assert name is not None
layer = cast(
- Optional[main.LayerWMS],
+ main.LayerWMS | None,
self._request.dbsession.query(main.LayerWMS).filter(main.LayerWMS.name == name).one_or_none(),
)
@@ -358,7 +357,7 @@ def get_layer_wms(self, el: Element, parent: main.TreeGroup | None = None) -> ma
return layer
- @functools.lru_cache(maxsize=10)
+ @functools.lru_cache(maxsize=10) # noqa: B019
def wms_capabilities(self) -> bytes:
errors: set[str] = set()
url = get_url2(
diff --git a/admin/c2cgeoportal_admin/schemas/dimensions.py b/admin/c2cgeoportal_admin/schemas/dimensions.py
index 3326057d167..4a9fb0c27e0 100644
--- a/admin/c2cgeoportal_admin/schemas/dimensions.py
+++ b/admin/c2cgeoportal_admin/schemas/dimensions.py
@@ -30,11 +30,10 @@
import colander
from c2cgeoform.schema import GeoFormSchemaNode
+from c2cgeoportal_commons.models.main import Dimension
from deform.widget import MappingWidget, SequenceWidget
from sqlalchemy.orm.attributes import InstrumentedAttribute
-from c2cgeoportal_commons.models.main import Dimension
-
def dimensions_schema_node(
prop: InstrumentedAttribute[Any], # pylint: disable=unsubscriptable-object
diff --git a/admin/c2cgeoportal_admin/schemas/functionalities.py b/admin/c2cgeoportal_admin/schemas/functionalities.py
index 327aa56b56a..a05d5440328 100644
--- a/admin/c2cgeoportal_admin/schemas/functionalities.py
+++ b/admin/c2cgeoportal_admin/schemas/functionalities.py
@@ -31,12 +31,11 @@
import colander
from c2cgeoform.ext.deform_ext import RelationCheckBoxListWidget
from c2cgeoform.schema import GeoFormManyToManySchemaNode, manytomany_validator
+from c2cgeoportal_commons.models.main import Functionality
from sqlalchemy import inspect, select
from sqlalchemy.orm.attributes import InstrumentedAttribute
from sqlalchemy.sql.functions import concat
-from c2cgeoportal_commons.models.main import Functionality
-
def available_functionalities_for(settings: dict[str, Any], model: type[Any]) -> list[dict[str, Any]]:
"""Return filtered list of functionality definitions."""
@@ -81,7 +80,6 @@ def functionalities_schema_node(
prop: InstrumentedAttribute[Any], model: type[Any]
) -> colander.SequenceSchema:
"""Get the schema of the functionalities."""
-
return colander.SequenceSchema(
GeoFormManyToManySchemaNode(Functionality, None),
name=prop.key,
diff --git a/admin/c2cgeoportal_admin/schemas/interfaces.py b/admin/c2cgeoportal_admin/schemas/interfaces.py
index 212aefc3c13..2bf697e42ab 100644
--- a/admin/c2cgeoportal_admin/schemas/interfaces.py
+++ b/admin/c2cgeoportal_admin/schemas/interfaces.py
@@ -31,9 +31,8 @@
import colander
from c2cgeoform.ext.deform_ext import RelationCheckBoxListWidget
from c2cgeoform.schema import GeoFormManyToManySchemaNode, manytomany_validator
-from sqlalchemy.orm.attributes import InstrumentedAttribute
-
from c2cgeoportal_commons.models.main import Interface
+from sqlalchemy.orm.attributes import InstrumentedAttribute
def interfaces_schema_node(
diff --git a/admin/c2cgeoportal_admin/schemas/metadata.py b/admin/c2cgeoportal_admin/schemas/metadata.py
index 4fa216ff611..cb0c7383923 100644
--- a/admin/c2cgeoportal_admin/schemas/metadata.py
+++ b/admin/c2cgeoportal_admin/schemas/metadata.py
@@ -31,14 +31,14 @@
import colander
import pyramid.request
from c2cgeoform.schema import GeoFormSchemaNode
+from c2cgeoportal_commons.lib.validators import url
+from c2cgeoportal_commons.models.main import Metadata
from deform.widget import MappingWidget, SelectWidget, SequenceWidget, TextAreaWidget
from sqlalchemy import inspect
from sqlalchemy.orm.attributes import InstrumentedAttribute
from sqlalchemy.orm.mapper import Mapper
from c2cgeoportal_admin import _
-from c2cgeoportal_commons.lib.validators import url
-from c2cgeoportal_commons.models.main import Metadata
def get_relevant_for(model: type[Any] | Mapper[Any]) -> set[str]:
@@ -202,7 +202,6 @@ def _translate_available_metadata(
def metadata_schema_node(prop: InstrumentedAttribute[Any], model: type[Any]) -> colander.SequenceSchema:
"""Get the schema of a collection of metadata."""
-
# Deferred which returns a dictionary with metadata name as key and metadata definition as value.
# Needed to get the metadata types on UI side.
metadata_definitions_dict = colander.deferred(
diff --git a/admin/c2cgeoportal_admin/schemas/restriction_areas.py b/admin/c2cgeoportal_admin/schemas/restriction_areas.py
index d13e70b3de6..cd22bd6ea24 100644
--- a/admin/c2cgeoportal_admin/schemas/restriction_areas.py
+++ b/admin/c2cgeoportal_admin/schemas/restriction_areas.py
@@ -31,9 +31,8 @@
import colander
from c2cgeoform.ext.deform_ext import RelationCheckBoxListWidget
from c2cgeoform.schema import GeoFormManyToManySchemaNode, manytomany_validator
-from sqlalchemy.orm.attributes import InstrumentedAttribute
-
from c2cgeoportal_commons.models.main import RestrictionArea
+from sqlalchemy.orm.attributes import InstrumentedAttribute
def restrictionareas_schema_node(
diff --git a/admin/c2cgeoportal_admin/schemas/roles.py b/admin/c2cgeoportal_admin/schemas/roles.py
index 308a322b43d..8ec1357ee3e 100644
--- a/admin/c2cgeoportal_admin/schemas/roles.py
+++ b/admin/c2cgeoportal_admin/schemas/roles.py
@@ -31,9 +31,8 @@
import colander
from c2cgeoform.ext.deform_ext import RelationCheckBoxListWidget
from c2cgeoform.schema import GeoFormManyToManySchemaNode, manytomany_validator
-from sqlalchemy.orm.attributes import InstrumentedAttribute
-
from c2cgeoportal_commons.models.main import Role
+from sqlalchemy.orm.attributes import InstrumentedAttribute
def roles_schema_node(
diff --git a/admin/c2cgeoportal_admin/schemas/treegroup.py b/admin/c2cgeoportal_admin/schemas/treegroup.py
index ea47cb501d5..187fb37f294 100644
--- a/admin/c2cgeoportal_admin/schemas/treegroup.py
+++ b/admin/c2cgeoportal_admin/schemas/treegroup.py
@@ -34,13 +34,13 @@
import pyramid.request
import sqlalchemy
from c2cgeoform.schema import GeoFormSchemaNode
+from c2cgeoportal_commons.lib.literal import Literal
+from c2cgeoportal_commons.models.main import LayergroupTreeitem, TreeGroup, TreeItem
from sqlalchemy.orm import aliased
from sqlalchemy.sql.expression import case, func
from c2cgeoportal_admin import _
from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget
-from c2cgeoportal_commons.lib.literal import Literal
-from c2cgeoportal_commons.models.main import LayergroupTreeitem, TreeGroup, TreeItem
_LOG = logging.getLogger(__name__)
@@ -74,7 +74,8 @@ def treeitems(
assert isinstance(dbsession, sqlalchemy.orm.Session)
group = case(
- (func.count(LayergroupTreeitem.id) == 0, "Unlinked"), else_="Others" # pylint: disable=not-callable
+ (func.count(LayergroupTreeitem.id) == 0, "Unlinked"), # pylint: disable=not-callable
+ else_="Others",
)
query = (
@@ -123,7 +124,7 @@ def treeitems(
def children_validator(node, cstruct):
"""Get the validator on the children nodes."""
for dict_ in cstruct:
- if not dict_["treeitem_id"] in [item["id"] for item in node.candidates]:
+ if dict_["treeitem_id"] not in [item["id"] for item in node.candidates]:
raise colander.Invalid(
node,
_("Value {} does not exist in table {} or is not allowed to avoid cycles").format(
diff --git a/admin/c2cgeoportal_admin/views/__init__.py b/admin/c2cgeoportal_admin/views/__init__.py
index 611546b28bd..189e9351845 100644
--- a/admin/c2cgeoportal_admin/views/__init__.py
+++ b/admin/c2cgeoportal_admin/views/__init__.py
@@ -4,9 +4,7 @@
class IsAdminPredicate:
- """
- A custom predicate that checks if the request is for the admin interface.
- """
+ """A custom predicate that checks if the request is for the admin interface."""
def __init__(self, val, info):
del info
diff --git a/admin/c2cgeoportal_admin/views/dimension_layers.py b/admin/c2cgeoportal_admin/views/dimension_layers.py
index 169627eb40d..51209e88914 100644
--- a/admin/c2cgeoportal_admin/views/dimension_layers.py
+++ b/admin/c2cgeoportal_admin/views/dimension_layers.py
@@ -32,10 +32,10 @@
import sqlalchemy.orm.query
from c2cgeoform.views.abstract_views import ListField
+from c2cgeoportal_commons.models.main import DimensionLayer
from sqlalchemy.orm import subqueryload
from c2cgeoportal_admin.views.layers import LayerViews
-from c2cgeoportal_commons.models.main import DimensionLayer
_list_field = partial(ListField, DimensionLayer)
diff --git a/admin/c2cgeoportal_admin/views/functionalities.py b/admin/c2cgeoportal_admin/views/functionalities.py
index 71de35fcfc8..ea4ab57a41e 100644
--- a/admin/c2cgeoportal_admin/views/functionalities.py
+++ b/admin/c2cgeoportal_admin/views/functionalities.py
@@ -40,12 +40,12 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.main import Functionality
from deform.widget import FormWidget
from pyramid.view import view_config, view_defaults
from c2cgeoportal_admin import _
from c2cgeoportal_admin.views.logged_views import LoggedViews
-from c2cgeoportal_commons.models.main import Functionality
_list_field = partial(ListField, Functionality)
@@ -103,7 +103,9 @@ def delete(self) -> DeleteResponse:
return super().delete()
@view_config(
- route_name="c2cgeoform_item_duplicate", request_method="GET", renderer="../templates/edit.jinja2" # type: ignore[misc]
+ route_name="c2cgeoform_item_duplicate",
+ request_method="GET",
+ renderer="../templates/edit.jinja2", # type: ignore[misc]
)
def duplicate(self) -> ObjectResponse:
return super().duplicate()
diff --git a/admin/c2cgeoportal_admin/views/interfaces.py b/admin/c2cgeoportal_admin/views/interfaces.py
index 806534cc6a2..2a8b6406ae2 100644
--- a/admin/c2cgeoportal_admin/views/interfaces.py
+++ b/admin/c2cgeoportal_admin/views/interfaces.py
@@ -37,10 +37,10 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.main import Interface
from pyramid.view import view_config, view_defaults
from c2cgeoportal_admin.views.logged_views import LoggedViews
-from c2cgeoportal_commons.models.main import Interface
_list_field = partial(ListField, Interface)
diff --git a/admin/c2cgeoportal_admin/views/layer_groups.py b/admin/c2cgeoportal_admin/views/layer_groups.py
index fc5a61d93ae..ae68c2f2f5c 100644
--- a/admin/c2cgeoportal_admin/views/layer_groups.py
+++ b/admin/c2cgeoportal_admin/views/layer_groups.py
@@ -39,6 +39,7 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.main import LayerGroup, TreeGroup
from deform.widget import FormWidget
from pyramid.view import view_config, view_defaults
@@ -46,7 +47,6 @@
from c2cgeoportal_admin.schemas.treegroup import children_schema_node
from c2cgeoportal_admin.schemas.treeitem import parent_id_node
from c2cgeoportal_admin.views.treeitems import TreeItemViews
-from c2cgeoportal_commons.models.main import LayerGroup, TreeGroup
_list_field = partial(ListField, LayerGroup)
diff --git a/admin/c2cgeoportal_admin/views/layers.py b/admin/c2cgeoportal_admin/views/layers.py
index 038472b15fb..b2b47521bd5 100644
--- a/admin/c2cgeoportal_admin/views/layers.py
+++ b/admin/c2cgeoportal_admin/views/layers.py
@@ -32,10 +32,10 @@
import sqlalchemy
import sqlalchemy.orm.query
from c2cgeoform.views.abstract_views import ListField
+from c2cgeoportal_commons.models.main import Interface, Layer
from sqlalchemy.orm import subqueryload
from c2cgeoportal_admin.views.treeitems import TreeItemViews
-from c2cgeoportal_commons.models.main import Interface, Layer
_list_field = partial(ListField, Layer)
diff --git a/admin/c2cgeoportal_admin/views/layers_cog.py b/admin/c2cgeoportal_admin/views/layers_cog.py
index 7ba329eba93..f655304baf5 100644
--- a/admin/c2cgeoportal_admin/views/layers_cog.py
+++ b/admin/c2cgeoportal_admin/views/layers_cog.py
@@ -40,6 +40,8 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.lib.literal import Literal
+from c2cgeoportal_commons.models.main import LayerCOG, LayerGroup
from deform.widget import FormWidget
from pyramid.httpexceptions import HTTPNotFound
from pyramid.view import view_config, view_defaults
@@ -50,8 +52,6 @@
from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node
from c2cgeoportal_admin.schemas.treeitem import parent_id_node
from c2cgeoportal_admin.views.layers import LayerViews
-from c2cgeoportal_commons.lib.literal import Literal
-from c2cgeoportal_commons.models.main import LayerCOG, LayerGroup
_list_field = partial(ListField, LayerCOG)
diff --git a/admin/c2cgeoportal_admin/views/layers_vectortiles.py b/admin/c2cgeoportal_admin/views/layers_vectortiles.py
index c451da41288..6648c9ddf80 100644
--- a/admin/c2cgeoportal_admin/views/layers_vectortiles.py
+++ b/admin/c2cgeoportal_admin/views/layers_vectortiles.py
@@ -40,6 +40,8 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.lib.literal import Literal
+from c2cgeoportal_commons.models.main import LayerGroup, LayerVectorTiles
from deform.widget import FormWidget
from pyramid.httpexceptions import HTTPNotFound
from pyramid.view import view_config, view_defaults
@@ -50,8 +52,6 @@
from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node
from c2cgeoportal_admin.schemas.treeitem import parent_id_node
from c2cgeoportal_admin.views.dimension_layers import DimensionLayerViews
-from c2cgeoportal_commons.lib.literal import Literal
-from c2cgeoportal_commons.models.main import LayerGroup, LayerVectorTiles
_list_field = partial(ListField, LayerVectorTiles)
diff --git a/admin/c2cgeoportal_admin/views/layers_wms.py b/admin/c2cgeoportal_admin/views/layers_wms.py
index 8acd8bab2be..520fd2ffd8f 100644
--- a/admin/c2cgeoportal_admin/views/layers_wms.py
+++ b/admin/c2cgeoportal_admin/views/layers_wms.py
@@ -40,6 +40,14 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.main import (
+ LayerGroup,
+ LayerWMS,
+ LayerWMTS,
+ LogAction,
+ OGCServer,
+ TreeItem,
+)
from deform.widget import FormWidget
from pyramid.view import view_config, view_defaults
from sqlalchemy import delete, insert, inspect, update
@@ -52,7 +60,6 @@
from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node
from c2cgeoportal_admin.schemas.treeitem import parent_id_node
from c2cgeoportal_admin.views.dimension_layers import DimensionLayerViews
-from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS, LogAction, OGCServer, TreeItem
_list_field = partial(ListField, LayerWMS)
diff --git a/admin/c2cgeoportal_admin/views/layers_wmts.py b/admin/c2cgeoportal_admin/views/layers_wmts.py
index 1798d6317c6..cdbf4416ba3 100644
--- a/admin/c2cgeoportal_admin/views/layers_wmts.py
+++ b/admin/c2cgeoportal_admin/views/layers_wmts.py
@@ -40,6 +40,14 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.main import (
+ LayerGroup,
+ LayerWMS,
+ LayerWMTS,
+ LogAction,
+ OGCServer,
+ TreeItem,
+)
from deform.widget import FormWidget
from pyramid.view import view_config, view_defaults
from sqlalchemy import delete, insert, inspect, update
@@ -52,7 +60,6 @@
from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node
from c2cgeoportal_admin.schemas.treeitem import parent_id_node
from c2cgeoportal_admin.views.dimension_layers import DimensionLayerViews
-from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS, LogAction, OGCServer, TreeItem
_list_field = partial(ListField, LayerWMTS)
diff --git a/admin/c2cgeoportal_admin/views/layertree.py b/admin/c2cgeoportal_admin/views/layertree.py
index c9a1b5ebabf..e229418c340 100644
--- a/admin/c2cgeoportal_admin/views/layertree.py
+++ b/admin/c2cgeoportal_admin/views/layertree.py
@@ -30,12 +30,18 @@
import pyramid.request
from c2cgeoform.views.abstract_views import DeleteResponse, ItemAction
+from c2cgeoportal_commons.models.main import (
+ Interface,
+ Layer,
+ LayergroupTreeitem,
+ Theme,
+ TreeItem,
+)
from pyramid.httpexceptions import HTTPNotFound
from pyramid.view import view_config, view_defaults
from translationstring import TranslationStringFactory
from c2cgeoportal_admin import _
-from c2cgeoportal_commons.models.main import Interface, Layer, LayergroupTreeitem, Theme, TreeItem
itemtypes_tables = {
"theme": "themes",
diff --git a/admin/c2cgeoportal_admin/views/logged_views.py b/admin/c2cgeoportal_admin/views/logged_views.py
index 85f287ecbea..da1464c16f5 100644
--- a/admin/c2cgeoportal_admin/views/logged_views.py
+++ b/admin/c2cgeoportal_admin/views/logged_views.py
@@ -29,10 +29,9 @@
from typing import Generic, TypeVar
from c2cgeoform.views.abstract_views import AbstractViews, DeleteResponse, SaveResponse
-from pyramid.httpexceptions import HTTPFound
-
from c2cgeoportal_commons.models import Base
from c2cgeoportal_commons.models.main import Log, LogAction
+from pyramid.httpexceptions import HTTPFound
_T = TypeVar("_T", bound=Log)
diff --git a/admin/c2cgeoportal_admin/views/logs.py b/admin/c2cgeoportal_admin/views/logs.py
index 922df76cb0d..0e20869e1cb 100644
--- a/admin/c2cgeoportal_admin/views/logs.py
+++ b/admin/c2cgeoportal_admin/views/logs.py
@@ -28,11 +28,16 @@
from functools import partial
from c2cgeoform import JSONDict
-from c2cgeoform.views.abstract_views import AbstractViews, GridResponse, IndexResponse, ItemAction, ListField
-from pyramid.view import view_config, view_defaults
-
+from c2cgeoform.views.abstract_views import (
+ AbstractViews,
+ GridResponse,
+ IndexResponse,
+ ItemAction,
+ ListField,
+)
from c2cgeoportal_commons.models import _
from c2cgeoportal_commons.models.main import AbstractLog
+from pyramid.view import view_config, view_defaults
_list_field = partial(ListField, AbstractLog)
diff --git a/admin/c2cgeoportal_admin/views/oauth2_clients.py b/admin/c2cgeoportal_admin/views/oauth2_clients.py
index e30d5618a55..44297b2b491 100644
--- a/admin/c2cgeoportal_admin/views/oauth2_clients.py
+++ b/admin/c2cgeoportal_admin/views/oauth2_clients.py
@@ -37,10 +37,10 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.static import Log, OAuth2Client
from pyramid.view import view_config, view_defaults
from c2cgeoportal_admin.views.logged_views import LoggedViews
-from c2cgeoportal_commons.models.static import Log, OAuth2Client
_list_field = partial(ListField, OAuth2Client)
diff --git a/admin/c2cgeoportal_admin/views/ogc_servers.py b/admin/c2cgeoportal_admin/views/ogc_servers.py
index 92e97c6b445..a1599cf0edf 100644
--- a/admin/c2cgeoportal_admin/views/ogc_servers.py
+++ b/admin/c2cgeoportal_admin/views/ogc_servers.py
@@ -45,6 +45,9 @@
SaveResponse,
UserMessage,
)
+from c2cgeoportal_commons.lib.literal import Literal
+from c2cgeoportal_commons.models import cache_invalidate_cb
+from c2cgeoportal_commons.models.main import LogAction, OGCServer
from deform.widget import FormWidget
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config, view_defaults
@@ -53,9 +56,6 @@
from c2cgeoportal_admin import _
from c2cgeoportal_admin.lib.ogcserver_synchronizer import OGCServerSynchronizer
from c2cgeoportal_admin.views.logged_views import LoggedViews
-from c2cgeoportal_commons.lib.literal import Literal
-from c2cgeoportal_commons.models import cache_invalidate_cb
-from c2cgeoportal_commons.models.main import LogAction, OGCServer
_list_field = partial(ListField, OGCServer)
diff --git a/admin/c2cgeoportal_admin/views/restriction_areas.py b/admin/c2cgeoportal_admin/views/restriction_areas.py
index 17b63d499f7..3edcb63f3fe 100644
--- a/admin/c2cgeoportal_admin/views/restriction_areas.py
+++ b/admin/c2cgeoportal_admin/views/restriction_areas.py
@@ -39,6 +39,7 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.main import Layer, RestrictionArea
from deform.widget import FormWidget
from pyramid.view import view_config, view_defaults
from sqlalchemy.orm import subqueryload
@@ -47,7 +48,6 @@
from c2cgeoportal_admin.schemas.treegroup import treeitem_edit_url
from c2cgeoportal_admin.views.logged_views import LoggedViews
from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget
-from c2cgeoportal_commons.models.main import Layer, RestrictionArea
_list_field = partial(ListField, RestrictionArea)
diff --git a/admin/c2cgeoportal_admin/views/roles.py b/admin/c2cgeoportal_admin/views/roles.py
index ec8ee1706dd..f26e1572d50 100644
--- a/admin/c2cgeoportal_admin/views/roles.py
+++ b/admin/c2cgeoportal_admin/views/roles.py
@@ -39,6 +39,8 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.main import Role
+from c2cgeoportal_commons.models.static import User
from deform.widget import FormWidget
from pyramid.view import view_config, view_defaults
from sqlalchemy.orm import subqueryload
@@ -47,8 +49,6 @@
from c2cgeoportal_admin.schemas.restriction_areas import restrictionareas_schema_node
from c2cgeoportal_admin.views.logged_views import LoggedViews
from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget
-from c2cgeoportal_commons.models.main import Role
-from c2cgeoportal_commons.models.static import User
_list_field = partial(ListField, Role)
diff --git a/admin/c2cgeoportal_admin/views/themes.py b/admin/c2cgeoportal_admin/views/themes.py
index 15fc45980d4..79149888840 100644
--- a/admin/c2cgeoportal_admin/views/themes.py
+++ b/admin/c2cgeoportal_admin/views/themes.py
@@ -39,6 +39,7 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.models.main import Functionality, Interface, Role, Theme
from deform.widget import FormWidget
from pyramid.view import view_config, view_defaults
from sqlalchemy.orm import subqueryload
@@ -50,7 +51,6 @@
from c2cgeoportal_admin.schemas.roles import roles_schema_node
from c2cgeoportal_admin.schemas.treegroup import children_schema_node
from c2cgeoportal_admin.views.treeitems import TreeItemViews
-from c2cgeoportal_commons.models.main import Functionality, Interface, Role, Theme
_list_field = partial(ListField, Theme)
diff --git a/admin/c2cgeoportal_admin/views/themes_ordering.py b/admin/c2cgeoportal_admin/views/themes_ordering.py
index c9faa7175a8..80f46150396 100644
--- a/admin/c2cgeoportal_admin/views/themes_ordering.py
+++ b/admin/c2cgeoportal_admin/views/themes_ordering.py
@@ -29,6 +29,7 @@
import colander
from c2cgeoform.schema import GeoFormSchemaNode
from c2cgeoform.views.abstract_views import AbstractViews, ObjectResponse, SaveResponse
+from c2cgeoportal_commons.models.main import Theme, TreeItem
from deform import ValidationFailure
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config
@@ -36,7 +37,6 @@
from c2cgeoportal_admin import _
from c2cgeoportal_admin.schemas.treegroup import treeitem_edit_url
from c2cgeoportal_admin.widgets import ChildrenWidget, ChildWidget
-from c2cgeoportal_commons.models.main import Theme, TreeItem
class ThemeOrderSchema(GeoFormSchemaNode): # pylint: disable=abstract-method
@@ -61,7 +61,7 @@ def themes(node, kw): # pylint: disable=unused-argument
def themes_validator(node, cstruct):
"""Validate the theme."""
for dict_ in cstruct:
- if not dict_["id"] in [item["id"] for item in node.candidates]:
+ if dict_["id"] not in [item["id"] for item in node.candidates]:
raise colander.Invalid(
node,
_("Value {} does not exist in table {}").format(dict_["id"], Theme.__tablename__),
@@ -126,7 +126,7 @@ def save(self) -> SaveResponse:
self._request.dbsession.flush()
return HTTPFound(self._request.route_url("layertree"))
except ValidationFailure as e:
- # FIXME see https://github.com/Pylons/deform/pull/243
+ # FIXME see https://github.com/Pylons/deform/pull/243 # pylint: disable=fixme
self._populate_widgets(form.schema)
return {
"title": form.title,
diff --git a/admin/c2cgeoportal_admin/views/treeitems.py b/admin/c2cgeoportal_admin/views/treeitems.py
index f762d9f22bd..0c3d2a5196d 100644
--- a/admin/c2cgeoportal_admin/views/treeitems.py
+++ b/admin/c2cgeoportal_admin/views/treeitems.py
@@ -31,12 +31,17 @@
import sqlalchemy
from c2cgeoform.views.abstract_views import ListField, SaveResponse
+from c2cgeoportal_commons.models.main import (
+ LayergroupTreeitem,
+ Metadata,
+ TreeGroup,
+ TreeItem,
+)
from pyramid.view import view_config
from sqlalchemy.orm import subqueryload
from sqlalchemy.sql.functions import concat
from c2cgeoportal_admin.views.logged_views import LoggedViews
-from c2cgeoportal_commons.models.main import LayergroupTreeitem, Metadata, TreeGroup, TreeItem
_list_field = partial(ListField, TreeItem)
diff --git a/admin/c2cgeoportal_admin/views/users.py b/admin/c2cgeoportal_admin/views/users.py
index 769de9aa640..f42c4943a99 100644
--- a/admin/c2cgeoportal_admin/views/users.py
+++ b/admin/c2cgeoportal_admin/views/users.py
@@ -38,6 +38,9 @@
ObjectResponse,
SaveResponse,
)
+from c2cgeoportal_commons.lib.email_ import send_email_config
+from c2cgeoportal_commons.models.main import Role
+from c2cgeoportal_commons.models.static import Log, User
from deform.widget import FormWidget
from passwordgenerator import pwgenerator
from pyramid.httpexceptions import HTTPFound
@@ -46,9 +49,6 @@
from c2cgeoportal_admin.schemas.roles import roles_schema_node
from c2cgeoportal_admin.views.logged_views import LoggedViews
-from c2cgeoportal_commons.lib.email_ import send_email_config
-from c2cgeoportal_commons.models.main import Role
-from c2cgeoportal_commons.models.static import Log, User
_list_field = partial(ListField, User)
diff --git a/admin/c2cgeoportal_admin/widgets.py b/admin/c2cgeoportal_admin/widgets.py
index bce6599c963..57c8e1a07a2 100644
--- a/admin/c2cgeoportal_admin/widgets.py
+++ b/admin/c2cgeoportal_admin/widgets.py
@@ -29,12 +29,11 @@
import colander
import pyramid.request
+from c2cgeoportal_commons.models.main import TreeItem
from colander import Mapping, SchemaNode
from deform import widget
from deform.widget import MappingWidget, SequenceWidget
-from c2cgeoportal_commons.models.main import TreeItem
-
registry = widget.default_resource_registry
registry.set_js_resources(
"magicsuggest", None, "c2cgeoportal_admin:node_modules/magicsuggest-alpine/magicsuggest-min.js"
diff --git a/admin/tests/__init__.py b/admin/tests/__init__.py
index 2fdfcf47c81..efcfac140ed 100644
--- a/admin/tests/__init__.py
+++ b/admin/tests/__init__.py
@@ -9,7 +9,12 @@
def get_test_default_layers(dbsession, default_ogc_server):
- from c2cgeoportal_commons.models.main import LayerCOG, LayerVectorTiles, LayerWMS, LayerWMTS
+ from c2cgeoportal_commons.models.main import (
+ LayerCOG,
+ LayerVectorTiles,
+ LayerWMS,
+ LayerWMTS,
+ )
default_wms = None
if default_ogc_server:
@@ -122,9 +127,9 @@ def check_grid_headers(self, resp, expected_col_headers, new="New"):
"\n\n{}\n\n differs from \n\n{}", pp.pformat(expected_col_headers), pp.pformat(effective_cols)
)
actions = resp.html.select_one('th[data-field="actions"]')
- assert "false" == actions.attrs["data-sortable"]
+ assert actions.attrs["data-sortable"] == "false"
if new is not False:
- assert 1 == len(list(filter(lambda x: next(x.stripped_strings) == new, resp.html.findAll("a"))))
+ assert len(list(filter(lambda x: next(x.stripped_strings) == new, resp.html.findAll("a")))) == 1
def check_search(self, test_app, search="", offset=0, limit=10, sort="", order="", total=None):
json = test_app.post(
@@ -184,7 +189,7 @@ def set_first_field_named(self, form, name, value):
def _check_sequence(self, sequence, expected):
seq_items = sequence.select(".deform-seq-item")
assert len(expected) == len(seq_items)
- for seq_item, exp in zip(seq_items, expected):
+ for seq_item, exp in zip(seq_items, expected, strict=False):
self._check_mapping(seq_item, exp)
def _check_mapping(self, mapping_item, expected):
@@ -203,13 +208,13 @@ def _check_mapping(self, mapping_item, expected):
else:
assert (exp["value"] or "") == input_tag.attrs.get("value", "")
if exp.get("hidden", False):
- assert "hidden" == input_tag["type"]
+ assert input_tag["type"] == "hidden"
if "label" in exp:
label_tag = mapping_item.select_one('label[for="{}"]'.format(input_tag["id"]))
assert exp["label"] == label_tag.getText().strip()
def _check_select(self, select, expected):
- for exp, option in zip(expected, select.find_all("option")):
+ for exp, option in zip(expected, select.find_all("option"), strict=False):
if "text" in exp:
assert exp["text"] == option.text
if "value" in exp:
@@ -219,11 +224,11 @@ def _check_select(self, select, expected):
def _check_submission_problem(self, resp, expected_msg):
assert (
- "There was a problem with your submission"
- == resp.html.select_one('div[class="error-msg-lbl"]').text
+ resp.html.select_one('div[class="error-msg-lbl"]').text
+ == "There was a problem with your submission"
)
assert (
- "Errors have been highlighted below" == resp.html.select_one('div[class="error-msg-detail"]').text
+ resp.html.select_one('div[class="error-msg-detail"]').text == "Errors have been highlighted below"
)
assert (
expected_msg
diff --git a/admin/tests/conftest.py b/admin/tests/conftest.py
index dc32b465aa7..e35b3a56790 100644
--- a/admin/tests/conftest.py
+++ b/admin/tests/conftest.py
@@ -4,6 +4,13 @@
import pytest
import sqlalchemy.exc
import transaction
+from c2cgeoportal_commons.testing import (
+ generate_mappers,
+ get_engine,
+ get_session_factory,
+ get_tm_session,
+)
+from c2cgeoportal_commons.testing.initializedb import truncate_tables
from pyramid import testing
from pyramid.paster import bootstrap
from pyramid.router import Router
@@ -12,9 +19,6 @@
from sqlalchemy.orm import Session, SessionTransaction
from webtest import TestApp as WebTestApp # Avoid warning with pytest
-from c2cgeoportal_commons.testing import generate_mappers, get_engine, get_session_factory, get_tm_session
-from c2cgeoportal_commons.testing.initializedb import truncate_tables
-
@pytest.fixture(scope="session")
@pytest.mark.usefixtures("settings")
diff --git a/admin/tests/lib/test_ogcserver_synchronizer.py b/admin/tests/lib/test_ogcserver_synchronizer.py
index c193facbb54..c5278d4031a 100644
--- a/admin/tests/lib/test_ogcserver_synchronizer.py
+++ b/admin/tests/lib/test_ogcserver_synchronizer.py
@@ -29,18 +29,16 @@
def wms_capabilities(content=DEFAULT_CONTENT):
- return """
+ return f"""
OGC:WMS
- {}
+ {content}
-""".format(
- content
- )
+"""
@pytest.fixture(scope="function")
@@ -443,9 +441,7 @@ def test_synchronize_clean(self, cap_mock, web_request, dbsession):
)
def test_get_layer_wms_defaut(self, web_request, dbsession):
- """
- We should copy properties from default LayerWMS.
- """
+ """We should copy properties from default LayerWMS."""
from c2cgeoportal_commons.models import main
synchronizer = self.synchronizer(web_request)
@@ -490,9 +486,7 @@ def test_get_layer_wms_defaut(self, web_request, dbsession):
assert layer.style == "default_style"
def test_get_layer_wms_defaut_style_not_exists(self, web_request, dbsession):
- """
- We should not copy style from default LayerWMS if does not exist in capabilities.
- """
+ """We should not copy style from default LayerWMS if does not exist in capabilities."""
from c2cgeoportal_commons.models import main
synchronizer = self.synchronizer(web_request)
diff --git a/admin/tests/schemas/test_metadata.py b/admin/tests/schemas/test_metadata.py
index 39318727479..8e05e4ac65e 100644
--- a/admin/tests/schemas/test_metadata.py
+++ b/admin/tests/schemas/test_metadata.py
@@ -11,7 +11,9 @@ def test_get_relevant_for():
def test_metadata_definitions():
- from c2cgeoportal_admin.schemas.metadata import get_relevant_for, metadata_definitions
+ from c2cgeoportal_admin.schemas.metadata import (
+ metadata_definitions,
+ )
from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS
settings = {
diff --git a/admin/tests/test_edit_url.py b/admin/tests/test_edit_url.py
index 24e20f0c2b8..bf8f96af60a 100644
--- a/admin/tests/test_edit_url.py
+++ b/admin/tests/test_edit_url.py
@@ -45,7 +45,7 @@ def edit_url_test_data(dbsession, transact):
layer_wmts.restrictionareas = [restrictionareas[i % 5], restrictionareas[(i + 2) % 5]]
if i % 10 != 1:
layer_wmts.interfaces = [interfaces[i % 4], interfaces[(i + 2) % 4]]
- layer_wmts.public = 1 == i % 2
+ layer_wmts.public = i % 2 == 1
layer_wmts.image_type = "image/jpeg"
dbsession.add(layer_wmts)
layers_wmts.append(layer_wmts)
diff --git a/admin/tests/test_functionalities.py b/admin/tests/test_functionalities.py
index 5331d3dcad8..a907b6a66a9 100644
--- a/admin/tests/test_functionalities.py
+++ b/admin/tests/test_functionalities.py
@@ -66,7 +66,7 @@ def test_submit_new(self, dbsession, test_app):
assert functionality.name == "new_name"
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "functionality"
assert log.element_id == functionality.id
@@ -80,14 +80,14 @@ def test_edit(self, test_app, functionality_test_data, dbsession):
resp = test_app.get(f"/admin/functionalities/{functionality.id}", status=200)
form = resp.form
assert str(functionality.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert functionality.name == form["name"].value
form["description"] = "new_description"
assert form.submit().status_int == 302
assert functionality.description == "new_description"
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "functionality"
assert log.element_id == functionality.id
@@ -103,7 +103,7 @@ def test_delete(self, test_app, functionality_test_data, dbsession):
assert dbsession.query(Functionality).get(deleted_id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "functionality"
assert log.element_id == functionality.id
diff --git a/admin/tests/test_home.py b/admin/tests/test_home.py
index 5c1a8cb0d42..14452384362 100644
--- a/admin/tests/test_home.py
+++ b/admin/tests/test_home.py
@@ -9,6 +9,6 @@ class TestHome(AbstractViewsTests):
def test_index_rendering(self, test_app):
resp = self.get(test_app, status=302)
- assert "http://localhost/admin/layertree" == resp.location
+ assert resp.location == "http://localhost/admin/layertree"
to_layer_tree = resp.follow()
assert to_layer_tree.html.select_one('div[id="layertree"]') is not None
diff --git a/admin/tests/test_interface.py b/admin/tests/test_interface.py
index 0b9dab763fe..8a407fc9f30 100644
--- a/admin/tests/test_interface.py
+++ b/admin/tests/test_interface.py
@@ -24,7 +24,7 @@ def interface_test_data(dbsession, transact):
layers = []
for i in range(0, 15):
layer = LayerWMS(name=f"layer_wms_{i}")
- layer.public = 1 == i % 2
+ layer.public = i % 2 == 1
layer.ogc_server = servers[i % 4]
dbsession.add(layer)
layers.append(layer)
@@ -94,7 +94,7 @@ def test_submit_new(self, dbsession, test_app):
assert interface.name == "new_name"
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "interface"
assert log.element_id == interface.id
@@ -112,13 +112,13 @@ def test_edit(self, test_app, interface_test_data, dbsession):
form = resp.form
form["description"] = descriptions
assert str(interface.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert interface.name == self.get_first_field_named(form, "name").value
assert form.submit().status_int == 302
assert len(dbsession.query(Interface).filter(Interface.description == descriptions).all()) == 1
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "interface"
assert log.element_id == interface.id
@@ -133,7 +133,7 @@ def test_delete(self, test_app, interface_test_data, dbsession):
assert len(dbsession.query(Interface).filter(Interface.id == interface.id).all()) == 0
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "interface"
assert log.element_id == interface.id
@@ -144,6 +144,6 @@ def test_duplicate(self, interface_test_data, test_app):
interface = interface_test_data["interfaces"][3]
resp = test_app.get(f"/admin/interfaces/{interface.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
assert str(interface.description or "") == "description_3"
assert form.submit().status_int == 302
diff --git a/admin/tests/test_layer_groups.py b/admin/tests/test_layer_groups.py
index 804c6189c50..82c9d665591 100644
--- a/admin/tests/test_layer_groups.py
+++ b/admin/tests/test_layer_groups.py
@@ -12,7 +12,11 @@
def layer_groups_test_data(dbsession, transact):
del transact
- from c2cgeoportal_commons.models.main import LayerGroup, LayergroupTreeitem, Metadata
+ from c2cgeoportal_commons.models.main import (
+ LayerGroup,
+ LayergroupTreeitem,
+ Metadata,
+ )
metadatas_protos = [
("copyable", "true"),
@@ -47,7 +51,7 @@ def flatten_tree(key, value):
for val in value:
add_relation(key, val)
else:
- for val in value.keys():
+ for val in value:
add_relation(key, val)
flatten_tree(val, value[val])
@@ -85,8 +89,8 @@ def test_grid_complex_column_val(self, test_app, layer_groups_test_data):
assert group.id == int(row["_id_"])
assert group.name == row["name"]
- assert "groups_02, groups_06" == row["parents_relation"]
- assert "disclaimer: © le momo, copyable: true" == row["metadatas"]
+ assert row["parents_relation"] == "groups_02, groups_06"
+ assert row["metadatas"] == "disclaimer: © le momo, copyable: true"
def test_grid_search(self, test_app):
# search on metadatas
@@ -100,7 +104,7 @@ def test_edit(self, test_app, layer_groups_test_data, dbsession):
form = self.get_item(test_app, group.id).form
assert str(group.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert group.name == self.get_first_field_named(form, "name").value
assert str(group.description or "") == self.get_first_field_named(form, "description").value
@@ -136,7 +140,7 @@ def test_edit(self, test_app, layer_groups_test_data, dbsession):
assert str(value or "") == str(getattr(group, key) or "")
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "layergroup"
assert log.element_id == group.id
@@ -144,9 +148,7 @@ def test_edit(self, test_app, layer_groups_test_data, dbsession):
assert log.username == "test_user"
def test_post_new_with_children_invalid(self, test_app, layer_groups_test_data):
- """
- Check there is no rendering error when validation fails.
- """
+ """Check there is no rendering error when validation fails."""
groups = layer_groups_test_data["groups"]
resp = test_app.post(
f"{self._prefix}/new",
@@ -165,7 +167,7 @@ def test_post_new_with_children_invalid(self, test_app, layer_groups_test_data):
),
status=200,
)
- assert "Required" == resp.html.select_one(".item-name .help-block").getText().strip()
+ assert resp.html.select_one(".item-name .help-block").getText().strip() == "Required"
def test_post_new_with_children_success(self, test_app, dbsession, layer_groups_test_data):
from c2cgeoportal_commons.models.main import Log, LogAction
@@ -214,7 +216,7 @@ def test_post_new_with_children_success(self, test_app, dbsession, layer_groups_
]
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "layergroup"
assert log.element_id == group.id
@@ -222,9 +224,7 @@ def test_post_new_with_children_success(self, test_app, dbsession, layer_groups_
assert log.username == "test_user"
def test_post_with_ancestor(self, layer_groups_test_data, test_app):
- """
- Check that ancestors are refused to avoid cycles.
- """
+ """Check that ancestors are refused to avoid cycles."""
groups = layer_groups_test_data["groups"]
resp = test_app.post(
f"{self._prefix}/{groups[3].id}",
@@ -259,7 +259,7 @@ def test_duplicate(self, layer_groups_test_data, test_app, dbsession):
group = dbsession.query(LayerGroup).filter(LayerGroup.id == group.id).one()
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
assert group.name == self.get_first_field_named(form, "name").value
assert str(group.description or "") == self.get_first_field_named(form, "description").value
@@ -305,13 +305,13 @@ def test_delete(self, test_app, dbsession, layer_groups_test_data):
group = layer_groups_test_data["groups"][9]
assert (
- 3
- == dbsession.query(LayergroupTreeitem).filter(LayergroupTreeitem.treegroup_id == group.id).count()
+ dbsession.query(LayergroupTreeitem).filter(LayergroupTreeitem.treegroup_id == group.id).count()
+ == 3
)
assert (
- 1
- == dbsession.query(LayergroupTreeitem).filter(LayergroupTreeitem.treeitem_id == group.id).count()
+ dbsession.query(LayergroupTreeitem).filter(LayergroupTreeitem.treeitem_id == group.id).count()
+ == 1
)
test_app.delete(f"/admin/layer_groups/{group.id}", status=200)
@@ -323,17 +323,17 @@ def test_delete(self, test_app, dbsession, layer_groups_test_data):
assert dbsession.query(TreeItem).get(group.id) is None
assert (
- 0
- == dbsession.query(LayergroupTreeitem).filter(LayergroupTreeitem.treegroup_id == group.id).count()
+ dbsession.query(LayergroupTreeitem).filter(LayergroupTreeitem.treegroup_id == group.id).count()
+ == 0
)
assert (
- 0
- == dbsession.query(LayergroupTreeitem).filter(LayergroupTreeitem.treeitem_id == group.id).count()
+ dbsession.query(LayergroupTreeitem).filter(LayergroupTreeitem.treeitem_id == group.id).count()
+ == 0
)
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "layergroup"
assert log.element_id == group.id
diff --git a/admin/tests/test_layers_cog.py b/admin/tests/test_layers_cog.py
index a89f0136348..70d5cbaeb22 100644
--- a/admin/tests/test_layers_cog.py
+++ b/admin/tests/test_layers_cog.py
@@ -20,7 +20,7 @@ def layer_cog_test_data(dbsession: Session, transact: SessionTransaction) -> dic
def layer_builder(i: int) -> LayerCOG:
name = f"layer_cog_{i}"
layer = LayerCOG(name=name)
- layer.public = 1 == i % 2
+ layer.public = i % 2 == 1
layer.url = "https://example.com/image.tiff"
return layer
@@ -73,9 +73,9 @@ def test_new(self, test_app: WebTestApp, layer_cog_test_data: dict[str, Any], db
form = self.get_item(test_app, "new").form
- assert "" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "id").value
- assert "" == self.get_first_field_named(form, "url").value
+ assert self.get_first_field_named(form, "name").value == ""
+ assert self.get_first_field_named(form, "id").value == ""
+ assert self.get_first_field_named(form, "url").value == ""
def test_grid_search(self, test_app: WebTestApp) -> None:
self.check_search(test_app, "layer_cog_10", total=1)
@@ -85,8 +85,8 @@ def test_base_edit(self, test_app: WebTestApp, layer_cog_test_data: dict[str, An
form = self.get_item(test_app, layer.id).form
- assert "layer_cog_10" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "description").value
+ assert self.get_first_field_named(form, "name").value == "layer_cog_10"
+ assert self.get_first_field_named(form, "description").value == ""
def test_public_checkbox_edit(self, test_app: WebTestApp, layer_cog_test_data: dict[str, Any]) -> None:
layer = layer_cog_test_data["layers"][10]
@@ -107,7 +107,7 @@ def test_edit(
form = self.get_item(test_app, layer.id).form
assert str(layer.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert layer.name == self.get_first_field_named(form, "name").value
assert str(layer.description or "") == self.get_first_field_named(form, "description").value
assert layer.public is False
@@ -153,7 +153,7 @@ def test_edit(
assert {ras[1].id, ras[3].id} == {ra.id for ra in layer.restrictionareas}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "layer_cog"
assert log.element_id == layer.id
@@ -182,7 +182,7 @@ def test_submit_new(
).group(1)
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "layer_cog"
assert log.element_id == layer.id
@@ -199,7 +199,7 @@ def test_duplicate(
resp = test_app.get(f"/admin/layers_cog/{layer.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
assert layer.name == self.get_first_field_named(form, "name").value
assert str(layer.description or "") == self.get_first_field_named(form, "description").value
assert layer.public is True
@@ -224,7 +224,13 @@ def test_duplicate(
assert layer_cog_test_data["layers"][3].metadatas[1].name == layer.metadatas[1].name
def test_delete(self, test_app: WebTestApp, dbsession: Session) -> None:
- from c2cgeoportal_commons.models.main import Layer, LayerCOG, Log, LogAction, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Layer,
+ LayerCOG,
+ Log,
+ LogAction,
+ TreeItem,
+ )
layer = dbsession.query(LayerCOG).first()
@@ -235,7 +241,7 @@ def test_delete(self, test_app: WebTestApp, dbsession: Session) -> None:
assert dbsession.query(TreeItem).get(layer.id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "layer_cog"
assert log.element_id == layer.id
diff --git a/admin/tests/test_layers_vectortiles.py b/admin/tests/test_layers_vectortiles.py
index 6e1c757284f..0e8280c893a 100644
--- a/admin/tests/test_layers_vectortiles.py
+++ b/admin/tests/test_layers_vectortiles.py
@@ -18,7 +18,7 @@ def layer_builder(i):
name = f"layer_vectortiles_{i}"
layer = LayerVectorTiles(name=name)
layer.layer = name
- layer.public = 1 == i % 2
+ layer.public = i % 2 == 1
layer.style = "https://vectortiles-staging.geoportail.lu/styles/roadmap/style.json"
layer.xyz = "https://vectortiles-staging.geoportail.lu/styles/roadmap/{z}/{x}/{y}.png"
return layer
@@ -74,10 +74,10 @@ def test_new(self, test_app, layer_vectortiles_test_data, dbsession):
form = self.get_item(test_app, "new").form
- assert "" == self.get_first_field_named(form, "id").value
- assert "" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "style").value
- assert "" == self.get_first_field_named(form, "xyz").value
+ assert self.get_first_field_named(form, "id").value == ""
+ assert self.get_first_field_named(form, "name").value == ""
+ assert self.get_first_field_named(form, "style").value == ""
+ assert self.get_first_field_named(form, "xyz").value == ""
def test_grid_search(self, test_app):
self.check_search(test_app, "layer_vectortiles_10", total=1)
@@ -87,8 +87,8 @@ def test_base_edit(self, test_app, layer_vectortiles_test_data):
form = self.get_item(test_app, layer.id).form
- assert "layer_vectortiles_10" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "description").value
+ assert self.get_first_field_named(form, "name").value == "layer_vectortiles_10"
+ assert self.get_first_field_named(form, "description").value == ""
def test_public_checkbox_edit(self, test_app, layer_vectortiles_test_data):
layer = layer_vectortiles_test_data["layers"][10]
@@ -107,7 +107,7 @@ def test_edit(self, test_app, layer_vectortiles_test_data, dbsession):
form = self.get_item(test_app, layer.id).form
assert str(layer.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert layer.name == self.get_first_field_named(form, "name").value
assert str(layer.description or "") == self.get_first_field_named(form, "description").value
assert layer.public is False
@@ -155,7 +155,7 @@ def test_edit(self, test_app, layer_vectortiles_test_data, dbsession):
assert {ras[1].id, ras[3].id} == {ra.id for ra in layer.restrictionareas}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "layer_vectortiles"
assert log.element_id == layer.id
@@ -183,7 +183,7 @@ def test_submit_new(self, dbsession, test_app, layer_vectortiles_test_data):
).group(1)
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "layer_vectortiles"
assert log.element_id == layer.id
@@ -198,7 +198,7 @@ def test_duplicate(self, layer_vectortiles_test_data, test_app, dbsession):
resp = test_app.get(f"/admin/layers_vectortiles/{layer.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
assert layer.name == self.get_first_field_named(form, "name").value
assert str(layer.description or "") == self.get_first_field_named(form, "description").value
assert layer.public is True
@@ -224,7 +224,13 @@ def test_duplicate(self, layer_vectortiles_test_data, test_app, dbsession):
assert layer_vectortiles_test_data["layers"][3].metadatas[1].name == layer.metadatas[1].name
def test_delete(self, test_app, dbsession):
- from c2cgeoportal_commons.models.main import Layer, LayerVectorTiles, Log, LogAction, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Layer,
+ LayerVectorTiles,
+ Log,
+ LogAction,
+ TreeItem,
+ )
layer = dbsession.query(LayerVectorTiles).first()
@@ -235,7 +241,7 @@ def test_delete(self, test_app, dbsession):
assert dbsession.query(TreeItem).get(layer.id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "layer_vectortiles"
assert log.element_id == layer.id
diff --git a/admin/tests/test_layers_wms.py b/admin/tests/test_layers_wms.py
index d6365744422..08dcaad7034 100644
--- a/admin/tests/test_layers_wms.py
+++ b/admin/tests/test_layers_wms.py
@@ -22,7 +22,7 @@ def layer_wms_test_data(dbsession, transact):
def layer_builder(i):
layer = LayerWMS(name=f"layer_wms_{i}")
layer.layer = f"layer_{i}"
- layer.public = 1 == i % 2
+ layer.public = i % 2 == 1
layer.geo_table = f"geotable_{i}"
layer.ogc_server = servers[i % 4]
layer.style = "décontrasté"
@@ -77,12 +77,12 @@ def test_grid_complex_column_val(self, test_app, layer_wms_test_data):
assert layer.id == int(row["_id_"])
assert layer.name == row["name"]
- assert "restrictionarea_0, restrictionarea_2" == row["restrictionareas"]
- assert "server_0" == row["ogc_server"]
- assert "desktop, edit" == row["interfaces"]
- assert "Date: 2017, 1988; CLC: all" == row["dimensions"]
- assert "layer_group_0, layer_group_3" == row["parents_relation"]
- assert 'copyable: true, snappingConfig: {"tolerance": 50}' == row["metadatas"]
+ assert row["restrictionareas"] == "restrictionarea_0, restrictionarea_2"
+ assert row["ogc_server"] == "server_0"
+ assert row["interfaces"] == "desktop, edit"
+ assert row["dimensions"] == "Date: 2017, 1988; CLC: all"
+ assert row["parents_relation"] == "layer_group_0, layer_group_3"
+ assert row["metadatas"] == 'copyable: true, snappingConfig: {"tolerance": 50}'
def test_grid_sort_on_ogc_server(self, test_app, layer_wms_test_data):
json = self.check_search(test_app, sort="ogc_server")
@@ -116,21 +116,21 @@ def test_new_no_default(self, test_app, layer_wms_test_data, dbsession):
form = self.get_item(test_app, "new").form
- assert "" == self.get_first_field_named(form, "id").value
- assert "" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "layer").value
- assert "" == self.get_first_field_named(form, "ogc_server_id").value
- assert "disabled" == self.get_first_field_named(form, "time_mode").value
- assert "slider" == self.get_first_field_named(form, "time_widget").value
+ assert self.get_first_field_named(form, "id").value == ""
+ assert self.get_first_field_named(form, "name").value == ""
+ assert self.get_first_field_named(form, "layer").value == ""
+ assert self.get_first_field_named(form, "ogc_server_id").value == ""
+ assert self.get_first_field_named(form, "time_mode").value == "disabled"
+ assert self.get_first_field_named(form, "time_widget").value == "slider"
def test_new_default(self, test_app, layer_wms_test_data):
default_wms = layer_wms_test_data["default"]["wms"]
form = self.get_item(test_app, "new").form
- assert "" == self.get_first_field_named(form, "id").value
- assert "" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "layer").value
+ assert self.get_first_field_named(form, "id").value == ""
+ assert self.get_first_field_named(form, "name").value == ""
+ assert self.get_first_field_named(form, "layer").value == ""
assert str(default_wms.ogc_server.id) == self.get_first_field_named(form, "ogc_server_id").value
assert default_wms.time_mode == self.get_first_field_named(form, "time_mode").value
assert default_wms.time_widget == self.get_first_field_named(form, "time_widget").value
@@ -140,8 +140,8 @@ def test_base_edit(self, test_app, layer_wms_test_data):
form = self.get_item(test_app, layer.id).form
- assert "layer_wms_10" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "description").value
+ assert self.get_first_field_named(form, "name").value == "layer_wms_10"
+ assert self.get_first_field_named(form, "description").value == ""
def test_public_checkbox_edit(self, test_app, layer_wms_test_data):
layer = layer_wms_test_data["layers"][10]
@@ -160,7 +160,7 @@ def test_edit(self, test_app, layer_wms_test_data, dbsession):
form = self.get_item(test_app, layer.id).form
assert str(layer.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert layer.name == self.get_first_field_named(form, "name").value
assert str(layer.description or "") == self.get_first_field_named(form, "description").value
assert layer.public is False
@@ -214,7 +214,7 @@ def test_edit(self, test_app, layer_wms_test_data, dbsession):
assert {ras[1].id, ras[3].id} == {ra.id for ra in layer.restrictionareas}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "layer_wms"
assert log.element_id == layer.id
@@ -247,7 +247,7 @@ def test_submit_new(self, dbsession, test_app, layer_wms_test_data):
).group(1)
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "layer_wms"
assert log.element_id == layer.id
@@ -262,7 +262,7 @@ def test_duplicate(self, layer_wms_test_data, test_app, dbsession):
resp = test_app.get(f"/admin/layers_wms/{layer.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
assert layer.name == self.get_first_field_named(form, "name").value
assert str(layer.description or "") == self.get_first_field_named(form, "description").value
assert layer.public is True
@@ -301,15 +301,15 @@ def test_convert_common_fields_copied(self, layer_wms_test_data, test_app, dbses
layer = layer_wms_test_data["layers"][3]
- assert 0 == dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count()
- assert 1 == dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count()
+ assert dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count() == 0
+ assert dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count() == 1
resp = test_app.post(f"/admin/layers_wms/{layer.id}/convert_to_wmts", status=200)
assert resp.json["success"]
assert f"http://localhost/admin/layers_wmts/{layer.id}?msg_col=submit_ok" == resp.json["redirect"]
- assert 1 == dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count()
- assert 0 == dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count()
+ assert dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count() == 1
+ assert dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count() == 0
resp = test_app.get(resp.json["redirect"], status=200)
form = resp.form
@@ -333,8 +333,8 @@ def test_convert_common_fields_copied(self, layer_wms_test_data, test_app, dbses
self._check_dimensions(resp.html, layer.dimensions)
assert (
- "Your submission has been taken into account."
- == resp.html.find("div", {"class": "msg-lbl"}).getText()
+ resp.html.find("div", {"class": "msg-lbl"}).getText()
+ == "Your submission has been taken into account."
)
def test_convert_image_type_from_ogcserver(self, layer_wms_test_data, test_app):
@@ -345,7 +345,7 @@ def test_convert_image_type_from_ogcserver(self, layer_wms_test_data, test_app):
assert f"http://localhost/admin/layers_wmts/{layer.id}?msg_col=submit_ok" == resp.json["redirect"]
resp = test_app.get(resp.json["redirect"], status=200)
- assert "image/png" == resp.form["image_type"].value
+ assert resp.form["image_type"].value == "image/png"
layer = layer_wms_test_data["layers"][2]
resp = test_app.post(f"/admin/layers_wms/{layer.id}/convert_to_wmts", status=200)
@@ -353,7 +353,7 @@ def test_convert_image_type_from_ogcserver(self, layer_wms_test_data, test_app):
assert f"http://localhost/admin/layers_wmts/{layer.id}?msg_col=submit_ok" == resp.json["redirect"]
resp = test_app.get(resp.json["redirect"], status=200)
- assert "image/jpeg" == resp.form["image_type"].value
+ assert resp.form["image_type"].value == "image/jpeg"
def test_convert_without_wmts_defaults(self, test_app, layer_wms_test_data, dbsession):
from c2cgeoportal_commons.models.main import LayerWMTS, Log, LogAction
@@ -363,7 +363,7 @@ def test_convert_without_wmts_defaults(self, test_app, layer_wms_test_data, dbse
test_app.post(f"/admin/layers_wms/{layer.id}/convert_to_wmts", status=200)
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.CONVERT_TO_WMTS
assert log.element_type == "layer_wms"
assert log.element_id == layer.id
@@ -381,7 +381,7 @@ def test_unicity_validator(self, layer_wms_test_data, test_app):
def test_unicity_validator_does_not_matter_amongst_cousin(self, layer_wms_test_data, test_app, dbsession):
from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS
- assert 1 == dbsession.query(LayerGroup).filter(LayerGroup.name == "layer_group_0").count()
+ assert dbsession.query(LayerGroup).filter(LayerGroup.name == "layer_group_0").count() == 1
assert dbsession.query(LayerWMS).filter(LayerWMS.name == "layer_group_0").one_or_none() is None
@@ -396,7 +396,13 @@ def test_unicity_validator_does_not_matter_amongst_cousin(self, layer_wms_test_d
# assert str(layer.id) == re.match('http://localhost/admin/layers_wms/(.*)', resp.location).group(1)
def test_delete(self, test_app, dbsession):
- from c2cgeoportal_commons.models.main import Layer, LayerWMS, Log, LogAction, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Layer,
+ LayerWMS,
+ Log,
+ LogAction,
+ TreeItem,
+ )
layer = dbsession.query(LayerWMS).first()
@@ -407,7 +413,7 @@ def test_delete(self, test_app, dbsession):
assert dbsession.query(TreeItem).get(layer.id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "layer_wms"
assert log.element_id == layer.id
@@ -432,12 +438,12 @@ def test_submit_new_no_layer_name(self, test_app, layer_wms_test_data, dbsession
)
assert (
- "There was a problem with your submission"
- == resp.html.select_one('div[class="error-msg-lbl"]').text
+ resp.html.select_one('div[class="error-msg-lbl"]').text
+ == "There was a problem with your submission"
)
assert (
- "Errors have been highlighted below" == resp.html.select_one('div[class="error-msg-detail"]').text
+ resp.html.select_one('div[class="error-msg-detail"]').text == "Errors have been highlighted below"
)
- assert ["WMS layer name"] == sorted(
+ assert sorted(
(x.select_one("label").text.strip()) for x in resp.html.select("[class~='has-error']")
- )
+ ) == ["WMS layer name"]
diff --git a/admin/tests/test_layers_wmts.py b/admin/tests/test_layers_wmts.py
index 5eed5e5f99b..c47a612af99 100644
--- a/admin/tests/test_layers_wmts.py
+++ b/admin/tests/test_layers_wmts.py
@@ -23,7 +23,7 @@ def layer_builder(i):
layer = LayerWMTS(name=name)
layer.layer = name
layer.url = f"https:///wms.geo.admin.ch_{i}.org?service=wms&request=GetCapabilities"
- layer.public = 1 == i % 2
+ layer.public = i % 2 == 1
layer.geo_table = f"geotable_{i}"
layer.image_type = "image/jpeg"
layer.style = "décontrasté"
@@ -83,20 +83,20 @@ def test_new_no_default(self, test_app, layer_wmts_test_data, dbsession):
form = self.get_item(test_app, "new").form
- assert "" == self.get_first_field_named(form, "id").value
- assert "" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "layer").value
- assert "" == self.get_first_field_named(form, "url").value
- assert "" == self.get_first_field_named(form, "matrix_set").value
+ assert self.get_first_field_named(form, "id").value == ""
+ assert self.get_first_field_named(form, "name").value == ""
+ assert self.get_first_field_named(form, "layer").value == ""
+ assert self.get_first_field_named(form, "url").value == ""
+ assert self.get_first_field_named(form, "matrix_set").value == ""
def test_new_default(self, test_app, layer_wmts_test_data):
default_wmts = layer_wmts_test_data["default"]["wmts"]
form = self.get_item(test_app, "new").form
- assert "" == self.get_first_field_named(form, "id").value
- assert "" == self.get_first_field_named(form, "name").value
- assert "" == self.get_first_field_named(form, "layer").value
+ assert self.get_first_field_named(form, "id").value == ""
+ assert self.get_first_field_named(form, "name").value == ""
+ assert self.get_first_field_named(form, "layer").value == ""
assert default_wmts.url == self.get_first_field_named(form, "url").value
assert default_wmts.matrix_set == self.get_first_field_named(form, "matrix_set").value
@@ -108,7 +108,7 @@ def test_edit(self, test_app, layer_wmts_test_data, dbsession):
form = self.get_item(test_app, layer.id).form
assert str(layer.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert layer.name == self.get_first_field_named(form, "name").value
assert str(layer.description or "") == self.get_first_field_named(form, "description").value
assert layer.public is False
@@ -162,7 +162,7 @@ def test_edit(self, test_app, layer_wmts_test_data, dbsession):
assert {ras[1].id, ras[3].id} == {ra.id for ra in layer.restrictionareas}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "layer_wmts"
assert log.element_id == layer.id
@@ -177,7 +177,7 @@ def test_duplicate(self, layer_wmts_test_data, test_app, dbsession):
resp = test_app.get(f"/admin/layers_wmts/{layer.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
assert layer.name == self.get_first_field_named(form, "name").value
assert str(layer.description or "") == self.get_first_field_named(form, "description").value
assert layer.public is True
@@ -199,7 +199,13 @@ def test_duplicate(self, layer_wmts_test_data, test_app, dbsession):
).group(1)
def test_delete(self, test_app, dbsession):
- from c2cgeoportal_commons.models.main import Layer, LayerWMTS, Log, LogAction, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Layer,
+ LayerWMTS,
+ Log,
+ LogAction,
+ TreeItem,
+ )
layer = dbsession.query(LayerWMTS).first()
@@ -210,7 +216,7 @@ def test_delete(self, test_app, dbsession):
assert dbsession.query(TreeItem).get(layer.id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "layer_wmts"
assert log.element_id == layer.id
@@ -230,14 +236,14 @@ def test_convert_common_fields_copied(self, layer_wmts_test_data, test_app, dbse
layer = layer_wmts_test_data["layers"][3]
- assert 0 == dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count()
- assert 1 == dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count()
+ assert dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count() == 0
+ assert dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count() == 1
resp = test_app.post(f"/admin/layers_wmts/{layer.id}/convert_to_wms", status=200)
assert f"http://localhost/admin/layers_wms/{layer.id}?msg_col=submit_ok" == resp.json["redirect"]
- assert 1 == dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count()
- assert 0 == dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count()
+ assert dbsession.query(LayerWMS).filter(LayerWMS.name == layer.name).count() == 1
+ assert dbsession.query(LayerWMTS).filter(LayerWMTS.name == layer.name).count() == 0
resp = test_app.get(resp.json["redirect"], status=200)
form = resp.form
@@ -260,8 +266,8 @@ def test_convert_common_fields_copied(self, layer_wmts_test_data, test_app, dbse
self._check_restrictionsareas(form, ras, layer)
self._check_dimensions(resp.html, layer.dimensions)
assert (
- "Your submission has been taken into account."
- == resp.html.find("div", {"class": "msg-lbl"}).getText()
+ resp.html.find("div", {"class": "msg-lbl"}).getText()
+ == "Your submission has been taken into account."
)
def test_convert_without_wms_defaults(self, test_app, layer_wmts_test_data, dbsession):
@@ -272,7 +278,7 @@ def test_convert_without_wms_defaults(self, test_app, layer_wmts_test_data, dbse
test_app.post(f"/admin/layers_wmts/{layer.id}/convert_to_wms", status=200)
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.CONVERT_TO_WMS
assert log.element_type == "layer_wmts"
assert log.element_id == layer.id
diff --git a/admin/tests/test_layertree.py b/admin/tests/test_layertree.py
index e135321470f..857d5dbf843 100644
--- a/admin/tests/test_layertree.py
+++ b/admin/tests/test_layertree.py
@@ -140,7 +140,7 @@ def check_new_action(self, test_app, nodes, parent_id, action_name, label, route
def test_themes(self, test_app, layertree_test_data):
resp = self.get(test_app, "/children", status=200)
nodes = resp.json
- assert 5 == len(nodes)
+ assert len(nodes) == 5
# check themes are sorted by ordering
expected = [
@@ -154,7 +154,7 @@ def test_themes(self, test_app, layertree_test_data):
# no unlink on theme
theme_node = next(n for n in nodes if n["id"] == theme.id)
- assert 0 == len([a for a in theme_node["actions"] if a["name"] == "unlink"])
+ assert len([a for a in theme_node["actions"] if a["name"] == "unlink"]) == 0
self.check_translation(nodes, theme)
@@ -176,9 +176,9 @@ def test_groups(self, test_app, layertree_test_data, dbsession):
theme.children_relation[1].ordering = 0
dbsession.flush()
- resp = self.get(test_app, "/children?group_id={0}&path=_{0}".format(theme.id), status=200)
+ resp = self.get(test_app, f"/children?group_id={theme.id}&path=_{theme.id}", status=200)
nodes = resp.json
- assert 2 == len(nodes)
+ assert len(nodes) == 2
# check groups are sorted by ordering
expected = [
@@ -227,9 +227,7 @@ def test_layers(self, test_app, layertree_test_data, dbsession):
group.children_relation[1].ordering = 0
dbsession.flush()
- resp = self.get(
- test_app, "/children?group_id={0}&path=_{1}_{0}".format(group.id, theme.id), status=200
- )
+ resp = self.get(test_app, f"/children?group_id={group.id}&path=_{theme.id}_{group.id}", status=200)
nodes = resp.json
assert len(nodes) == 2
diff --git a/admin/tests/test_lingva_extractor_config.py b/admin/tests/test_lingva_extractor_config.py
index 89b9035d7a5..7e7a16a638f 100644
--- a/admin/tests/test_lingva_extractor_config.py
+++ b/admin/tests/test_lingva_extractor_config.py
@@ -29,10 +29,6 @@
from unittest.mock import Mock, mock_open, patch
-import pytest
-import yaml
-from c2c.template.config import config as configuration
-
from c2cgeoportal_admin.lib.lingva_extractor import GeomapfishConfigExtractor
GMF_CONFIG = """
diff --git a/admin/tests/test_logs.py b/admin/tests/test_logs.py
index 48c4439b77b..875098b9e1b 100644
--- a/admin/tests/test_logs.py
+++ b/admin/tests/test_logs.py
@@ -13,7 +13,6 @@
def logs_test_data(dbsession, transact):
del transact
- from c2cgeoportal_commons.models.main import AbstractLog
from c2cgeoportal_commons.models.main import Log as MainLog
from c2cgeoportal_commons.models.main import LogAction
from c2cgeoportal_commons.models.static import Log as StaticLog
diff --git a/admin/tests/test_main.py b/admin/tests/test_main.py
index fb9c0287d1e..10bc80e8b9a 100644
--- a/admin/tests/test_main.py
+++ b/admin/tests/test_main.py
@@ -5,9 +5,7 @@
@pytest.mark.usefixtures("app_env")
def test_main(app_env):
- """
- Test dev environment.
- """
+ """Test dev environment."""
config = testing.setUp(registry=app_env["registry"])
app = config.make_wsgi_app()
testapp = WebTestApp(app)
diff --git a/admin/tests/test_metadatas.py b/admin/tests/test_metadatas.py
index cfd8600c861..8f9d7bc6e49 100644
--- a/admin/tests/test_metadatas.py
+++ b/admin/tests/test_metadatas.py
@@ -10,7 +10,14 @@
def metadatas_test_data(dbsession, transact):
del transact
- from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, LayerWMTS, Metadata, OGCServer, Theme
+ from c2cgeoportal_commons.models.main import (
+ LayerGroup,
+ LayerWMS,
+ LayerWMTS,
+ Metadata,
+ OGCServer,
+ Theme,
+ )
ogc_server = OGCServer(name="ogc_server")
@@ -333,9 +340,7 @@ def test_group_metadatas(self, metadatas_test_data, test_app):
self._test_edit_treeitem("layer_groups", metadatas_test_data["group"], test_app, LayerGroup)
def test_undefined_metadata(self, metadatas_test_data, test_app):
- """
- Undefined metadata must be kept intact across submissions.
- """
+ """Undefined metadata must be kept intact across submissions."""
from c2cgeoportal_commons.models.main import Metadata
layer = metadatas_test_data["layer_wms"]
diff --git a/admin/tests/test_oauth2_clients.py b/admin/tests/test_oauth2_clients.py
index b1febe74b48..6289f1d18e9 100644
--- a/admin/tests/test_oauth2_clients.py
+++ b/admin/tests/test_oauth2_clients.py
@@ -18,7 +18,7 @@ def oauth2_clients_test_data(dbsession, transact):
from c2cgeoportal_commons.models.static import OAuth2Client
clients = []
- for i in range(23):
+ for _i in range(23):
client = OAuth2Client()
client.client_id = str(uuid4())
client.secret = "1234"
@@ -86,7 +86,7 @@ def test_submit_new(self, dbsession, test_app, oauth2_clients_test_data):
assert oauth2_client.redirect_uri == "http://127.0.0.1:7070/bis"
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "oauth2_client"
assert log.element_id == oauth2_client.id
@@ -120,12 +120,12 @@ def test_edit_then_save(self, dbsession, test_app, oauth2_clients_test_data):
dbsession.expire(oauth2_client)
- assert "New client ID" == oauth2_client.client_id
- assert "New secret" == oauth2_client.secret
- assert "New redirect URI" == oauth2_client.redirect_uri
+ assert oauth2_client.client_id == "New client ID"
+ assert oauth2_client.secret == "New secret"
+ assert oauth2_client.redirect_uri == "New redirect URI"
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "oauth2_client"
assert log.element_id == oauth2_client.id
@@ -140,7 +140,7 @@ def test_duplicate(self, oauth2_clients_test_data, test_app, dbsession):
resp = test_app.get(f"/admin/oauth2_clients/{oauth2_client_proto.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
assert oauth2_client_proto.client_id == form["client_id"].value
assert oauth2_client_proto.secret == form["secret"].value
assert oauth2_client_proto.redirect_uri == form["redirect_uri"].value
@@ -162,7 +162,7 @@ def test_delete(self, test_app, dbsession):
assert dbsession.query(OAuth2Client).get(oauth2_client.id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "oauth2_client"
assert log.element_id == oauth2_client.id
diff --git a/admin/tests/test_ogc_servers.py b/admin/tests/test_ogc_servers.py
index c072a257076..16a0c7aec86 100644
--- a/admin/tests/test_ogc_servers.py
+++ b/admin/tests/test_ogc_servers.py
@@ -81,7 +81,7 @@ def test_submit_new(self, dbsession, test_app):
assert ogc_server.name == "new_name"
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "ogc_server"
assert log.element_id == ogc_server.id
@@ -95,7 +95,7 @@ def test_edit(self, test_app, ogc_server_test_data, dbsession):
resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}", status=200)
form = resp.form
assert str(ogc_server.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert ogc_server.name == form["name"].value
form["description"] = "new_description"
with patch("c2cgeoportal_admin.views.ogc_servers.OGCServerViews._update_cache"):
@@ -103,7 +103,7 @@ def test_edit(self, test_app, ogc_server_test_data, dbsession):
assert ogc_server.description == "new_description"
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "ogc_server"
assert log.element_id == ogc_server.id
@@ -118,7 +118,7 @@ def test_delete(self, test_app, ogc_server_test_data, dbsession):
assert dbsession.query(OGCServer).get(ogc_server.id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "ogc_server"
assert log.element_id == ogc_server.id
@@ -131,7 +131,7 @@ def test_duplicate(self, ogc_server_test_data, test_app, dbsession):
ogc_server = ogc_server_test_data["ogc_servers"][3]
resp = test_app.get(f"/admin/ogc_servers/{ogc_server.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
self.set_first_field_named(form, "name", "clone")
with patch("c2cgeoportal_admin.views.ogc_servers.OGCServerViews._update_cache"):
resp = form.submit("submit")
@@ -181,7 +181,7 @@ def test_synchronize_success(self, ogc_server_test_data, test_app, dbsession):
resp = resp.forms["form-synchronize"].submit("synchronize")
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.SYNCHRONIZE
assert log.element_type == "ogc_server"
assert log.element_id == ogc_server.id
diff --git a/admin/tests/test_restriction_areas.py b/admin/tests/test_restriction_areas.py
index 71edeae5c54..be5e85832cf 100644
--- a/admin/tests/test_restriction_areas.py
+++ b/admin/tests/test_restriction_areas.py
@@ -15,7 +15,12 @@
@pytest.mark.usefixtures("dbsession", "transact")
def restriction_area_test_data(dbsession, transact):
del transact
- from c2cgeoportal_commons.models.main import LayerWMS, OGCServer, RestrictionArea, Role
+ from c2cgeoportal_commons.models.main import (
+ LayerWMS,
+ OGCServer,
+ RestrictionArea,
+ Role,
+ )
roles = []
for i in range(0, 4):
@@ -116,7 +121,7 @@ def test_submit_new(self, dbsession, test_app, restriction_area_test_data):
assert set(restriction_area.layers) == {layers[0], layers[1]}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "restrictionarea"
assert log.element_id == restriction_area.id
@@ -143,7 +148,7 @@ def test_edit(self, test_app, restriction_area_test_data, dbsession):
form = self.get_item(test_app, restriction_area.id).form
assert str(restriction_area.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert restriction_area.name == form["name"].value
expected = Polygon(
[
@@ -174,7 +179,7 @@ def test_edit(self, test_app, restriction_area_test_data, dbsession):
assert set(restriction_area.roles) == {roles[i] for i in range(0, 3)}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "restrictionarea"
assert log.element_id == restriction_area.id
@@ -190,7 +195,7 @@ def test_delete(self, test_app, restriction_area_test_data, dbsession):
assert dbsession.query(RestrictionArea).get(deleted_id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "restrictionarea"
assert log.element_id == restriction_area.id
@@ -208,7 +213,7 @@ def test_duplicate(self, restriction_area_test_data, test_app, dbsession):
form = test_app.get(f"/admin/restriction_areas/{restriction_area.id}/duplicate", status=200).form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
self._check_roles(form, roles, restriction_area)
self.check_children(
form,
diff --git a/admin/tests/test_role.py b/admin/tests/test_role.py
index ed0248e4f3a..94b65e4057f 100644
--- a/admin/tests/test_role.py
+++ b/admin/tests/test_role.py
@@ -155,7 +155,7 @@ def test_submit_new(self, dbsession, test_app, roles_test_data):
assert set(role.users) == {users[0], users[1]}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "role"
assert log.element_id == role.id
@@ -172,7 +172,7 @@ def test_edit(self, dbsession, test_app, roles_test_data):
form = self.get_item(test_app, role.id).form
- assert "secretary_10" == form["name"].value
+ assert form["name"].value == "secretary_10"
expected = Polygon(
[
@@ -266,8 +266,8 @@ def test_edit(self, dbsession, test_app, roles_test_data):
dbsession.expire(role)
- assert "New name" == role.name
- assert "New description" == role.description
+ assert role.name == "New name"
+ assert role.description == "New description"
expected = Polygon(
[
@@ -284,7 +284,7 @@ def test_edit(self, dbsession, test_app, roles_test_data):
assert set(ra_ids) == {f.id for f in role.restrictionareas}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "role"
assert log.element_id == role.id
@@ -299,7 +299,7 @@ def test_duplicate(self, roles_test_data, test_app, dbsession):
resp = test_app.get(f"/admin/roles/{role_proto.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
+ assert self.get_first_field_named(form, "id").value == ""
assert role_proto.name == form["name"].value
assert role_proto.description == form["description"].value
form["name"].value = "clone"
@@ -322,7 +322,7 @@ def test_delete(self, test_app, dbsession):
assert dbsession.query(Role).get(role.id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "role"
assert log.element_id == role.id
diff --git a/admin/tests/test_themes.py b/admin/tests/test_themes.py
index 20418f77a0e..ee93610f45b 100644
--- a/admin/tests/test_themes.py
+++ b/admin/tests/test_themes.py
@@ -54,7 +54,7 @@ def theme_test_data(dbsession, transact):
themes = []
for i in range(0, 25):
theme = Theme(name=f"theme_{i}", ordering=1, icon=f"icon_{i}")
- theme.public = 1 == i % 2
+ theme.public = i % 2 == 1
theme.interfaces = [interfaces[i % 4], interfaces[(i + 2) % 4]]
theme.metadatas = [
Metadata(name=metadatas_protos[id][0], value=metadatas_protos[id][1])
@@ -121,10 +121,10 @@ def test_grid_complex_column_val(self, test_app, theme_test_data):
assert first_theme.id == int(first_row["_id_"])
assert first_theme.name == first_row["name"]
- assert "default_basemap=value_0" == first_row["functionalities"]
- assert "secretary_0, secretary_2" == first_row["restricted_roles"]
- assert "desktop, edit" == first_row["interfaces"]
- assert 'copyable: true, snappingConfig: {"tolerance": 50}' == first_row["metadatas"]
+ assert first_row["functionalities"] == "default_basemap=value_0"
+ assert first_row["restricted_roles"] == "secretary_0, secretary_2"
+ assert first_row["interfaces"] == "desktop, edit"
+ assert first_row["metadatas"] == 'copyable: true, snappingConfig: {"tolerance": 50}'
def test_grid_search(self, test_app):
# search on metadatas key and value parts
@@ -165,7 +165,7 @@ def test_edit(self, test_app, theme_test_data, dbsession):
form = resp.form
assert str(theme.id) == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert theme.name == self.get_first_field_named(form, "name").value
assert str(theme.description or "") == self.get_first_field_named(form, "description").value
assert str(theme.ordering or "") == self.get_first_field_named(form, "ordering").value
@@ -231,10 +231,10 @@ def test_edit(self, test_app, theme_test_data, dbsession):
assert str(value or "") == str(getattr(theme, key) or "")
assert {interfaces[1].id, interfaces[3].id} == {interface.id for interface in theme.interfaces}
assert {functionalities[2].id} == {functionality.id for functionality in theme.functionalities}
- assert 0 == len(theme.restricted_roles)
+ assert len(theme.restricted_roles) == 0
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "theme"
assert log.element_id == theme.id
@@ -242,9 +242,7 @@ def test_edit(self, test_app, theme_test_data, dbsession):
assert log.username == "test_user"
def test_post_new_with_children_invalid(self, test_app, theme_test_data):
- """
- Check there is no rendering error when validation fails.
- """
+ """Check there is no rendering error when validation fails."""
groups = theme_test_data["groups"]
resp = test_app.post(
f"{self._prefix}/new",
@@ -314,7 +312,7 @@ def test_post_new_with_children_success(self, test_app, dbsession, theme_test_da
]
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "theme"
assert log.element_id == theme.id
@@ -322,9 +320,7 @@ def test_post_new_with_children_success(self, test_app, dbsession, theme_test_da
assert log.username == "test_user"
def test_post_new_with_child_layer(self, theme_test_data, test_app):
- """
- Check layers are rejected by the validator (also means that they are not proposed to the user).
- """
+ """Check layers are rejected by the validator (also means that they are not proposed to the user)."""
layers = theme_test_data["layers"]
resp = test_app.post(
f"{self._prefix}/new",
@@ -359,8 +355,8 @@ def test_duplicate(self, theme_test_data, test_app, dbsession):
resp = test_app.get(f"{self._prefix}/{theme.id}/duplicate", status=200)
form = resp.form
- assert "" == self.get_first_field_named(form, "id").value
- assert "hidden" == self.get_first_field_named(form, "id").attrs["type"]
+ assert self.get_first_field_named(form, "id").value == ""
+ assert self.get_first_field_named(form, "id").attrs["type"] == "hidden"
assert theme.name == self.get_first_field_named(form, "name").value
assert str(theme.description or "") == self.get_first_field_named(form, "description").value
assert str(theme.ordering or "") == self.get_first_field_named(form, "ordering").value
@@ -421,7 +417,7 @@ def test_delete(self, test_app, dbsession):
assert dbsession.query(Theme).get(theme.id) is None
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "theme"
assert log.element_id == theme.id
diff --git a/admin/tests/test_treegroup.py b/admin/tests/test_treegroup.py
index b2a4aa2c5d6..ac063d188f1 100644
--- a/admin/tests/test_treegroup.py
+++ b/admin/tests/test_treegroup.py
@@ -8,7 +8,7 @@ def check_children(self, form, group, expected):
form_group = form.html.select_one(f".item-{group}")
items = form_group.select(".deform-seq-item")
assert len(expected) == len(items)
- for item, exp in zip(items, expected):
+ for item, exp in zip(items, expected, strict=False):
assert exp["label"] == item.select_one(".well").getText().strip()
for key, value in exp["values"].items():
assert value == item.select_one(f'input[name="{key}"]')["value"]
diff --git a/admin/tests/test_user.py b/admin/tests/test_user.py
index 956a7660ac0..d16a36fc4c1 100644
--- a/admin/tests/test_user.py
+++ b/admin/tests/test_user.py
@@ -127,7 +127,7 @@ def test_view_edit(self, test_app, users_test_data, dbsession):
assert {roles[2].id, roles[3].id} == {role.id for role in user.roles}
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.UPDATE
assert log.element_type == "user"
assert log.element_id == user.id
@@ -145,7 +145,7 @@ def test_delete(self, test_app, users_test_data, dbsession):
assert dbsession.query(user_role).filter(user_role.c.user_id == user.id).count() == 0
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.DELETE
assert log.element_type == "user"
assert log.element_id == user.id
@@ -224,7 +224,7 @@ def test_duplicate(self, pw_gen_mock, smtp_mock, users_test_data, test_app, dbse
resp = test_app.get(f"/admin/users/{user.id}/duplicate", status=200)
form = resp.form
- assert "" == form["id"].value
+ assert form["id"].value == ""
assert user.username == form["username"].value
assert user.email == form["email"].value
assert str(user.settings_role_id) == form["settings_role_id"].value
@@ -249,7 +249,7 @@ def test_duplicate(self, pw_gen_mock, smtp_mock, users_test_data, test_app, dbse
assert EXPECTED_WELCOME_MAIL.format("clone", "clone", "basile") == parts[1].get_payload(
decode=True
).decode("utf8")
- assert "mail7@valid.net" == parts[0].items()[3][1]
+ assert parts[0].items()[3][1] == "mail7@valid.net"
@patch("c2cgeoportal_commons.lib.email_.smtplib.SMTP")
@patch("c2cgeoportal_admin.views.users.pwgenerator.generate")
@@ -299,10 +299,10 @@ def test_submit_new(self, pw_gen_mock, smtp_mock, dbsession, test_app, users_tes
assert EXPECTED_WELCOME_MAIL.format("new_user", "new_user", "basile") == parts[1].get_payload(
decode=True
).decode("utf8")
- assert "valid@email.net" == parts[0].items()[3][1]
+ assert parts[0].items()[3][1] == "valid@email.net"
log = dbsession.query(Log).one()
- assert log.date != None
+ assert log.date is not None
assert log.action == LogAction.INSERT
assert log.element_type == "user"
assert log.element_id == user.id
@@ -339,9 +339,7 @@ def test_grid_dberror(self, dbsession):
UserViews(request).grid()
def test_grid_settings_role_none(self, dbsession, test_app):
- """
- Grid view must work even if a user's settings_role is None.
- """
+ """Grid view must work even if a user's settings_role is None."""
from c2cgeoportal_commons.models.static import User
dbsession.add(User("test", email="test@valid.net"))
diff --git a/admin/tests/themes_ordering.py b/admin/tests/themes_ordering.py
index edba54a8590..afba47dcdc5 100644
--- a/admin/tests/themes_ordering.py
+++ b/admin/tests/themes_ordering.py
@@ -41,7 +41,7 @@ def test_edit(self, test_app, themes_ordering_test_data):
)
resp = form.submit("submit", status=302)
- assert "http://localhost/admin/layertree" == resp.location
+ assert resp.location == "http://localhost/admin/layertree"
for i, theme in enumerate(sorted(themes_ordering_test_data["themes"], key=lambda t: t.name)):
assert i == theme.ordering
diff --git a/bin/azure b/bin/azure
index dd09b067255..24c4cea98f8 100755
--- a/bin/azure
+++ b/bin/azure
@@ -25,7 +25,7 @@
import argparse
import glob
import os
-import subprocess
+import subprocess # nosec
import yaml
from azure.storage.blob import BlobServiceClient, ContainerClient, __version__
diff --git a/bin/build-l10n b/bin/build-l10n
index ce85daa5502..ea64b9a151d 100755
--- a/bin/build-l10n
+++ b/bin/build-l10n
@@ -4,7 +4,7 @@ import argparse
import glob
import os
import shutil
-import subprocess
+import subprocess # nosec
def main() -> None:
diff --git a/ci/changelog b/ci/changelog
index 661004c953b..665b61d1cc8 100755
--- a/ci/changelog
+++ b/ci/changelog
@@ -31,7 +31,7 @@
import json
import os
import re
-import subprocess
+import subprocess # nosec
import sys
from typing import Any
diff --git a/commons/c2cgeoportal_commons/alembic/env.py b/commons/c2cgeoportal_commons/alembic/env.py
index 6c05079fe3c..99667969b5f 100755
--- a/commons/c2cgeoportal_commons/alembic/env.py
+++ b/commons/c2cgeoportal_commons/alembic/env.py
@@ -103,7 +103,11 @@ def run_migrations_online() -> None:
# Autogenerate config
alembic_name = context.config.get_main_option("type")
- from c2cgeoportal_commons.models import Base, main, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ Base,
+ main,
+ static,
+ )
_schema = main._schema if alembic_name == "main" else static._schema # pylint: disable=protected-access
diff --git a/commons/c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py b/commons/c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py
index 3b40b6fddb4..d745fb9b7f2 100644
--- a/commons/c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py
+++ b/commons/c2cgeoportal_commons/alembic/main/166ff2dcc48d_create_database.py
@@ -40,7 +40,15 @@
from alembic import op
from c2c.template.config import config
from sqlalchemy import Column, ForeignKey, MetaData, Table
-from sqlalchemy.types import Boolean, DateTime, Float, Integer, String, Unicode, UserDefinedType
+from sqlalchemy.types import (
+ Boolean,
+ DateTime,
+ Float,
+ Integer,
+ String,
+ Unicode,
+ UserDefinedType,
+)
# revision identifiers, used by Alembic.
revision = "166ff2dcc48d"
@@ -93,10 +101,7 @@ def upgrade() -> None:
Column("readwrite", Boolean, default=False),
schema=schema,
)
- op.execute(
- "SELECT AddGeometryColumn('%(schema)s', 'restrictionarea', "
- "'area', %(srid)s, 'POLYGON', 2)" % {"schema": schema, "srid": srid}
- )
+ op.execute(f"SELECT AddGeometryColumn('{schema}', 'restrictionarea', " f"'area', {srid}, 'POLYGON', 2)")
op.create_table(
"shorturl",
Column("id", Integer, primary_key=True),
@@ -116,10 +121,7 @@ def upgrade() -> None:
Column("description", Unicode),
schema=schema,
)
- op.execute(
- "SELECT AddGeometryColumn('%(schema)s', 'role', "
- "'extent', %(srid)s, 'POLYGON', 2)" % {"schema": schema, "srid": srid}
- )
+ op.execute(f"SELECT AddGeometryColumn('{schema}', 'role', " f"'extent', {srid}, 'POLYGON', 2)")
role = Table("role", MetaData(), Column("name", Unicode, unique=True, nullable=False), schema=schema)
op.bulk_insert(role, [{"name": "role_admin"}])
@@ -172,10 +174,7 @@ def upgrade() -> None:
Column("params", Unicode, nullable=True),
schema=schema,
)
- op.execute(
- "SELECT AddGeometryColumn('%(schema)s', 'tsearch', 'the_geom', "
- "%(srid)s, 'GEOMETRY', 2)" % {"schema": schema, "srid": srid}
- )
+ op.execute(f"SELECT AddGeometryColumn('{schema}', 'tsearch', 'the_geom', " f"{srid}, 'GEOMETRY', 2)")
op.create_index("tsearch_ts_idx", "tsearch", ["ts"], schema=schema, postgresql_using="gin")
op.create_table(
"treegroup",
diff --git a/commons/c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py b/commons/c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py
index 777bdf654f9..b2ad419528a 100644
--- a/commons/c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py
+++ b/commons/c2cgeoportal_commons/alembic/main/21f11066f8ec_trigger_on_role_updates_user_in_static.py
@@ -71,7 +71,7 @@ def downgrade() -> None:
schema = config["schema"]
op.execute(
- """
+ f"""
CREATE OR REPLACE FUNCTION {schema}.on_role_name_change()
RETURNS trigger AS
$$
@@ -82,7 +82,5 @@ def downgrade() -> None:
RETURN NEW;
END;
$$
-LANGUAGE plpgsql""".format(
- schema=schema
- )
+LANGUAGE plpgsql"""
)
diff --git a/commons/c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py b/commons/c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py
index c6298f22324..cbacc5cece1 100644
--- a/commons/c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py
+++ b/commons/c2cgeoportal_commons/alembic/main/56dc90838d90_fix_removing_layerv1.py
@@ -50,11 +50,9 @@ def upgrade() -> None:
schema = config["schema"]
op.execute(
- (
- "DELETE from {schema}.layer_restrictionarea WHERE layer_id IN ("
- "SELECT id from {schema}.treeitem WHERE type = 'layerv1'"
- ");"
- ).format(schema=schema)
+ f"DELETE from {schema}.layer_restrictionarea WHERE layer_id IN ("
+ f"SELECT id from {schema}.treeitem WHERE type = 'layerv1'"
+ ");"
)
op.execute(f"DELETE from {schema}.treeitem WHERE type = 'layerv1';")
diff --git a/commons/c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py b/commons/c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py
index 4107a44967f..0a8278fe29e 100644
--- a/commons/c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py
+++ b/commons/c2cgeoportal_commons/alembic/main/7530011a66a7_trigger_on_role_updates_user_in_static.py
@@ -71,7 +71,7 @@ def downgrade() -> None:
schema = config["schema"]
op.execute(
- """
+ f"""
CREATE OR REPLACE FUNCTION {schema}.on_role_name_change()
RETURNS trigger AS
$$
@@ -82,7 +82,5 @@ def downgrade() -> None:
RETURN NEW;
END;
$$
-LANGUAGE plpgsql""".format(
- schema=schema
- )
+LANGUAGE plpgsql"""
)
diff --git a/commons/c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py b/commons/c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py
index 1129d0194a5..ed914b6974f 100644
--- a/commons/c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py
+++ b/commons/c2cgeoportal_commons/alembic/main/7d271f4527cd_add_layer_column_in_layerv1_table.py
@@ -53,10 +53,10 @@ def upgrade() -> None:
op.add_column("layerv1", Column("layer", Unicode), schema=schema)
op.execute(
- "UPDATE {schema}.layerv1 AS l1 "
+ f"UPDATE {schema}.layerv1 AS l1 "
"SET layer = name "
- "FROM {schema}.treeitem AS ti "
- "WHERE l1.id = ti.id".format(schema=schema)
+ f"FROM {schema}.treeitem AS ti "
+ "WHERE l1.id = ti.id"
)
diff --git a/commons/c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py b/commons/c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py
index 143943fe90e..de7fef02973 100644
--- a/commons/c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py
+++ b/commons/c2cgeoportal_commons/alembic/main/9268a1dffac0_add_trigger_to_be_able_to_correctly_.py
@@ -50,7 +50,7 @@ def upgrade() -> None:
schema = config["schema"]
op.execute(
- """
+ f"""
CREATE FUNCTION {schema}.on_role_name_change()
RETURNS trigger AS
$$
@@ -61,14 +61,12 @@ def upgrade() -> None:
RETURN NEW;
END;
$$
-LANGUAGE plpgsql""".format(
- schema=schema
- )
+LANGUAGE plpgsql"""
)
op.execute(
- "CREATE TRIGGER on_role_name_change AFTER UPDATE ON {schema}.role FOR EACH ROW "
- "EXECUTE PROCEDURE {schema}.on_role_name_change()".format(schema=schema)
+ f"CREATE TRIGGER on_role_name_change AFTER UPDATE ON {schema}.role FOR EACH ROW "
+ f"EXECUTE PROCEDURE {schema}.on_role_name_change()"
)
diff --git a/commons/c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py b/commons/c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py
index 50ba1783b8f..190e3b33809 100644
--- a/commons/c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py
+++ b/commons/c2cgeoportal_commons/alembic/main/eeb345672454_merge_2_4_and_master_branches.py
@@ -35,7 +35,6 @@
Create Date: 2019-09-03 09:11:57.786920
"""
-
# revision identifiers, used by Alembic.
revision = "eeb345672454"
down_revision = ("78fd093c8393", "56dc90838d90")
diff --git a/commons/c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py b/commons/c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py
index 68f7f3294a5..b21d92d217f 100644
--- a/commons/c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py
+++ b/commons/c2cgeoportal_commons/alembic/static/1da396a88908_move_user_table_to_static_schema.py
@@ -82,20 +82,13 @@ def upgrade() -> None:
try:
op.execute(
- "INSERT INTO %(staticschema)s.user "
- "(type, username, password, email, is_password_changed, role_name%(parent_column)s) ("
+ f"INSERT INTO {staticschema}.user "
+ f"(type, username, password, email, is_password_changed, role_name{parent_column}) ("
"SELECT u.type, u.username, u.password, u.email, "
- "u.is_password_changed, r.name%(parent_select)s "
- "FROM %(schema)s.user AS u "
- "LEFT OUTER JOIN %(schema)s.role AS r ON (r.id = u.role_id) %(parent_join)s"
+ f"u.is_password_changed, r.name{parent_select} "
+ f"FROM {schema}.user AS u "
+ f"LEFT OUTER JOIN {schema}.role AS r ON (r.id = u.role_id) {parent_join}"
")"
- % {
- "staticschema": staticschema,
- "schema": schema,
- "parent_select": parent_select,
- "parent_column": parent_column,
- "parent_join": parent_join,
- }
)
op.drop_table("user", schema=schema)
except Exception: # pylint: disable=broad-exception-caught
@@ -135,20 +128,13 @@ def downgrade() -> None:
parent_join = f"LEFT OUTER JOIN {parentschema}.role AS pr ON (pr.name = u.parent_role_name)"
op.execute(
- "INSERT INTO %(schema)s.user "
- "(type, username, password, email, is_password_changed, role_id%(parent_column)s) ("
+ f"INSERT INTO {schema}.user "
+ f"(type, username, password, email, is_password_changed, role_id{parent_column}) ("
"SELECT u.type, u.username, u.password, u.email, "
- "u.is_password_changed, r.id%(parent_select)s "
- "FROM %(staticschema)s.user AS u "
- "LEFT OUTER JOIN %(schema)s.role AS r ON (r.name = u.role_name) %(parent_join)s"
+ f"u.is_password_changed, r.id{parent_select} "
+ f"FROM {staticschema}.user AS u "
+ f"LEFT OUTER JOIN {schema}.role AS r ON (r.name = u.role_name) {parent_join}"
")"
- % {
- "staticschema": staticschema,
- "schema": schema,
- "parent_select": parent_select,
- "parent_column": parent_column,
- "parent_join": parent_join,
- }
)
op.drop_table("user", schema=staticschema)
diff --git a/commons/c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py b/commons/c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py
index 99d9d4ee71a..1d5917363c0 100644
--- a/commons/c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py
+++ b/commons/c2cgeoportal_commons/alembic/static/53d671b17b20_add_timezone_on_datetime_fields.py
@@ -50,14 +50,12 @@ def upgrade() -> None:
staticschema = config["schema_static"]
op.execute(
- """
+ f"""
SET TIME ZONE 'UTC';
ALTER TABLE {staticschema}.user ALTER COLUMN last_login TYPE timestamp with time zone;
SET TIME ZONE LOCAL;
ALTER TABLE {staticschema}.user ALTER COLUMN expire_on TYPE timestamp with time zone;
-""".format(
- staticschema=staticschema
- )
+"""
)
@@ -66,12 +64,10 @@ def downgrade() -> None:
staticschema = config["schema_static"]
op.execute(
- """
+ f"""
SET TIME ZONE 'UTC';
ALTER TABLE {staticschema}.user ALTER COLUMN last_login TYPE timestamp without time zone;
SET TIME ZONE LOCAL;
ALTER TABLE {staticschema}.user ALTER COLUMN expire_on TYPE timestamp without time zone;
-""".format(
- staticschema=staticschema
- )
+"""
)
diff --git a/commons/c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py b/commons/c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py
index 59b750d8008..5f3625a9561 100644
--- a/commons/c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py
+++ b/commons/c2cgeoportal_commons/alembic/static/aa41e9613256_wip_add_openid_connect_support.py
@@ -35,7 +35,6 @@
Create Date: 2024-08-30 15:56:31.163378
"""
-
from alembic import op
from c2c.template.config import config
diff --git a/commons/c2cgeoportal_commons/models/__init__.py b/commons/c2cgeoportal_commons/models/__init__.py
index d12489f7f44..275aaefe16a 100644
--- a/commons/c2cgeoportal_commons/models/__init__.py
+++ b/commons/c2cgeoportal_commons/models/__init__.py
@@ -47,7 +47,7 @@
class BaseType(sqlalchemy.ext.declarative.DeclarativeMeta, type):
- pass
+ """Base type for all the models class."""
Base: BaseType = sqlalchemy.orm.declarative_base()
diff --git a/commons/c2cgeoportal_commons/models/main.py b/commons/c2cgeoportal_commons/models/main.py
index ffc87dd9f43..0e008f48cbc 100644
--- a/commons/c2cgeoportal_commons/models/main.py
+++ b/commons/c2cgeoportal_commons/models/main.py
@@ -56,7 +56,13 @@
from c2cgeoform.ext.colander_ext import Geometry as ColanderGeometry
from c2cgeoform.ext.deform_ext import MapWidget, RelationSelect2Widget
from colander import drop
- from deform.widget import CheckboxWidget, HiddenWidget, SelectWidget, TextAreaWidget, TextInputWidget
+ from deform.widget import (
+ CheckboxWidget,
+ HiddenWidget,
+ SelectWidget,
+ TextAreaWidget,
+ TextInputWidget,
+ )
colander_null = colander.null
except ModuleNotFoundError:
@@ -84,7 +90,6 @@ def __init__(self, *args: Any, **kwargs: Any):
def state_str(state: Any) -> str:
"""Return a string describing an instance via its InstanceState."""
-
return "None" if state is None else f"<{state.class_.__name__} {state.obj()}>"
# In the original function sqlalchemy use the id of the object that don't allow us to give some useful
@@ -308,7 +313,7 @@ def __str__(self) -> str:
return f"{self.name}[{self.id}]>"
@property
- def bounds(self) -> tuple[float, float, float, float] | None: # TODO
+ def bounds(self) -> tuple[float, float, float, float] | None:
if self.extent is None:
return None
return cast(tuple[float, float, float, float], to_shape(self.extent).bounds)
@@ -367,11 +372,7 @@ def is_in_interface(self, name: str) -> bool:
if not hasattr(self, "interfaces"):
return False
- for interface in self.interfaces:
- if interface.name == name:
- return True
-
- return False
+ return any(interface.name == name for interface in self.interfaces)
def get_metadata(self, name: str) -> list["Metadata"]:
return [metadata for metadata in self.metadatas if metadata.name == name]
@@ -1035,7 +1036,7 @@ def __init__(
@staticmethod
def get_default(dbsession: Session) -> DimensionLayer | None:
return cast(
- Optional[DimensionLayer],
+ DimensionLayer | None,
dbsession.query(LayerWMS).filter(LayerWMS.name == "wms-defaults").one_or_none(),
)
@@ -1179,7 +1180,7 @@ def __init__(self, name: str = "", public: bool = True, image_type: ImageType =
@staticmethod
def get_default(dbsession: Session) -> DimensionLayer | None:
return cast(
- Optional[DimensionLayer],
+ DimensionLayer | None,
dbsession.query(LayerWMTS).filter(LayerWMTS.name == "wmts-defaults").one_or_none(),
)
@@ -1374,7 +1375,7 @@ def __init__(self, name: str = "", public: bool = True, style: str = "", sql: st
@staticmethod
def get_default(dbsession: Session) -> DimensionLayer | None:
return cast(
- Optional[DimensionLayer],
+ DimensionLayer | None,
dbsession.query(LayerVectorTiles)
.filter(LayerVectorTiles.name == "vector-tiles-defaults")
.one_or_none(),
diff --git a/commons/c2cgeoportal_commons/models/static.py b/commons/c2cgeoportal_commons/models/static.py
index 0e60d1f80d2..3327f939629 100644
--- a/commons/c2cgeoportal_commons/models/static.py
+++ b/commons/c2cgeoportal_commons/models/static.py
@@ -324,7 +324,7 @@ def set_temp_password(self, password: str) -> None:
@staticmethod
def __encrypt_password_legacy(password: str) -> str:
"""Hash the given password with SHA1."""
- return sha1(password.encode("utf8")).hexdigest() # nosec
+ return sha1(password.encode("utf8")).hexdigest() # noqa: S324
@staticmethod
def __encrypt_password(password: str) -> str:
diff --git a/commons/c2cgeoportal_commons/testing/__init__.py b/commons/c2cgeoportal_commons/testing/__init__.py
index 14a6ff17afe..debb5ae292c 100644
--- a/commons/c2cgeoportal_commons/testing/__init__.py
+++ b/commons/c2cgeoportal_commons/testing/__init__.py
@@ -78,11 +78,10 @@ def get_tm_session(
def generate_mappers() -> None:
"""Initialize the model for a Pyramid app."""
-
# import or define all models here to ensure they are attached to the
# Base.metadata prior to any initialization routines
- import c2cgeoportal_commons.models.main # pylint: disable=unused-import,import-outside-toplevel
- import c2cgeoportal_commons.models.static # pylint: disable=import-outside-toplevel
+ import c2cgeoportal_commons.models.main # pylint: disable=unused-import,import-outside-toplevel # noqa: F401
+ import c2cgeoportal_commons.models.static # pylint: disable=import-outside-toplevel # noqa: F401
# run configure_mappers after defining all of the models to ensure
# all relationships can be setup
diff --git a/commons/c2cgeoportal_commons/testing/initializedb.py b/commons/c2cgeoportal_commons/testing/initializedb.py
index e3951d17c64..e9167ce9dca 100644
--- a/commons/c2cgeoportal_commons/testing/initializedb.py
+++ b/commons/c2cgeoportal_commons/testing/initializedb.py
@@ -46,11 +46,15 @@ def usage(argv: list[str]) -> None:
def schema_exists(connection: Connection, schema_name: str) -> bool:
"""Get if the schema exist."""
- sql = f"""
-SELECT count(*) AS count
-FROM information_schema.schemata
-WHERE schema_name = '{schema_name}';
-"""
+ del schema_name
+
+ sql = " ".join(
+ [ # noqa: S608
+ "SELECT count(*) AS count",
+ "FROM information_schema.schemata",
+ "WHERE schema_name = '{schema_name}';",
+ ]
+ )
result = connection.execute(sqlalchemy.text(sql))
row = result.first()
return cast(bool, row[0] == 1) # type: ignore[index]
@@ -64,8 +68,12 @@ def truncate_tables(connection: Connection) -> None:
def setup_test_data(dbsession: Session) -> None:
"""Initialize the testing data."""
- from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ Role,
+ )
+ from c2cgeoportal_commons.models.static import ( # pylint: disable=import-outside-toplevel
+ User,
+ )
role_admin = dbsession.merge(Role(name="role_admin"))
role_user = dbsession.merge(Role(name="role_user"))
diff --git a/commons/tests/conftest.py b/commons/tests/conftest.py
index dd7d28ccf5f..1ce9c4c3ac4 100644
--- a/commons/tests/conftest.py
+++ b/commons/tests/conftest.py
@@ -5,10 +5,14 @@
import pytest
import transaction
from c2c.template.config import config
-from sqlalchemy.exc import DBAPIError
-
-from c2cgeoportal_commons.testing import generate_mappers, get_engine, get_session_factory, get_tm_session
+from c2cgeoportal_commons.testing import (
+ generate_mappers,
+ get_engine,
+ get_session_factory,
+ get_tm_session,
+)
from c2cgeoportal_commons.testing.initializedb import truncate_tables
+from sqlalchemy.exc import DBAPIError
@pytest.fixture(scope="session")
diff --git a/commons/tests/lib/test_url.py b/commons/tests/lib/test_url.py
index 7477789912d..506e8e3bf47 100644
--- a/commons/tests/lib/test_url.py
+++ b/commons/tests/lib/test_url.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -29,9 +29,8 @@
from unittest import TestCase
-from pyramid.testing import DummyRequest
-
from c2cgeoportal_commons.lib.url import Url, get_url2
+from pyramid.testing import DummyRequest
class TestUrl(TestCase):
diff --git a/commons/tests/lib/test_validators.py b/commons/tests/lib/test_validators.py
index 3f28cf13f12..a176740e21e 100644
--- a/commons/tests/lib/test_validators.py
+++ b/commons/tests/lib/test_validators.py
@@ -1,7 +1,6 @@
# pylint: disable=no-self-use
import pytest
-
from c2cgeoportal_commons.lib.validators import url
diff --git a/commons/tests/models/test_interface.py b/commons/tests/models/test_interface.py
index b64d7b1b0c0..ad7afbcd22a 100644
--- a/commons/tests/models/test_interface.py
+++ b/commons/tests/models/test_interface.py
@@ -6,9 +6,8 @@
@pytest.mark.usefixtures("transact")
class TestInterface:
def test_delete_cascade_to_tsearch(self, dbsession):
- from sqlalchemy import func
-
from c2cgeoportal_commons.models.main import FullTextSearch, Interface
+ from sqlalchemy import func
interface = Interface("desktop", "Desktop interface")
interface_id = interface.id
@@ -24,5 +23,5 @@ def test_delete_cascade_to_tsearch(self, dbsession):
dbsession.flush()
assert (
- 0 == dbsession.query(FullTextSearch).filter(FullTextSearch.interface_id == interface_id).count()
+ dbsession.query(FullTextSearch).filter(FullTextSearch.interface_id == interface_id).count() == 0
)
diff --git a/commons/tests/models/test_roles.py b/commons/tests/models/test_roles.py
index b4a227807bc..ac68c3537a7 100644
--- a/commons/tests/models/test_roles.py
+++ b/commons/tests/models/test_roles.py
@@ -41,12 +41,11 @@ def test_delete(self, dbsession):
dbsession.delete(roles[0])
roles = dbsession.query(Role).all()
assert len(roles) == 0, "removed a role"
- assert 0 == dbsession.query(user_role).count()
+ assert dbsession.query(user_role).count() == 0
def test_delete_cascade_to_tsearch(self, dbsession):
- from sqlalchemy import func
-
from c2cgeoportal_commons.models.main import FullTextSearch, Role
+ from sqlalchemy import func
role = dbsession.query(Role).filter(Role.name == "secretary").one()
role_id = role.id
@@ -61,4 +60,4 @@ def test_delete_cascade_to_tsearch(self, dbsession):
dbsession.delete(role)
dbsession.flush()
- assert 0 == dbsession.query(FullTextSearch).filter(FullTextSearch.role_id == role_id).count()
+ assert dbsession.query(FullTextSearch).filter(FullTextSearch.role_id == role_id).count() == 0
diff --git a/commons/tests/models/test_users.py b/commons/tests/models/test_users.py
index 43086621fb6..2908ab8d00e 100644
--- a/commons/tests/models/test_users.py
+++ b/commons/tests/models/test_users.py
@@ -30,7 +30,7 @@ def test_select(self, dbsession):
users = dbsession.query(User).all()
assert len(users) == 1, "querying for users"
assert users[0].username == "babar", "user from test data is babar"
- assert 2 == len(users[0].roles)
+ assert len(users[0].roles) == 2
def test_remove(self, dbsession):
from c2cgeoportal_commons.models.static import User, user_role
@@ -39,7 +39,7 @@ def test_remove(self, dbsession):
dbsession.delete(users[0])
users = dbsession.query(User).all()
assert len(users) == 0, "removed a user"
- assert 0 == dbsession.query(user_role).count()
+ assert dbsession.query(user_role).count() == 0
def test_add(self, dbsession):
from c2cgeoportal_commons.models.main import Role
@@ -52,9 +52,9 @@ def test_add(self, dbsession):
assert dbsession.query(User).count() == 2, "added a user"
dbsession.expire(user)
assert user.username == "momo", "added user is momo"
- assert 1 == len(user.roles)
+ assert len(user.roles) == 1
assert user.roles[0].name == "Role3"
- assert 1 == dbsession.query(user_role).filter(user_role.c.user_id == user.id).count()
+ assert dbsession.query(user_role).filter(user_role.c.user_id == user.id).count() == 1
@staticmethod
def test_edit(dbsession):
@@ -62,10 +62,10 @@ def test_edit(dbsession):
from c2cgeoportal_commons.models.static import User, user_role
user = dbsession.query(User).first()
- assert 2 == len(user.roles)
+ assert len(user.roles) == 2
user.roles = [Role(name="Role4")]
dbsession.flush()
dbsession.expire(user)
- assert 1 == len(user.roles)
+ assert len(user.roles) == 1
assert user.roles[0].name == "Role4"
- assert 1 == dbsession.query(user_role).filter(user_role.c.user_id == user.id).count()
+ assert dbsession.query(user_role).filter(user_role.c.user_id == user.id).count() == 1
diff --git a/doc/import_ngeo_config.py b/doc/import_ngeo_config.py
index ffb417e34b2..83c47c20e9b 100755
--- a/doc/import_ngeo_config.py
+++ b/doc/import_ngeo_config.py
@@ -30,7 +30,7 @@ def _format_type(type_definition: dict[str, Any]) -> str:
f"{_format_type(type_definition['declaration']['indexSignature']['type'])}}}"
)
- assert False, f"Unknown type '{type_definition['type']}':\n{type_definition}"
+ raise AssertionError(f"Unknown type '{type_definition['type']}':\n{type_definition}")
def _get_type(type_definition: dict[str, Any]) -> list[str]:
diff --git a/doc/integrator/requirements.rst b/doc/integrator/requirements.rst
index 7181204e539..3f3cad91c24 100644
--- a/doc/integrator/requirements.rst
+++ b/doc/integrator/requirements.rst
@@ -11,7 +11,7 @@ components installed on your system:
* **Git**
* **Docker** >= 17.05
-* **Python** >= 3.8, with ``pip``
+* **Python** >= 3.10, with ``pip``
* **Apache** >= 2.4 (optional, can be used as a front for SSL)
* **PostgreSQL** >= 9.1/**PostGIS** >= 2.1
diff --git a/doc/pyproject.toml b/doc/pyproject.toml
index 1bb00bb8bac..d894991c3da 100644
--- a/doc/pyproject.toml
+++ b/doc/pyproject.toml
@@ -1,11 +1,3 @@
-[tool.black]
-line-length = 110
-target-version = ['py39']
-
-[tool.isort]
-profile = "black"
-line_length = 110
-
[tool.poetry]
name = 'c2cgeoportal'
version = '0.0.0'
diff --git a/docker/config/bin/eval-templates b/docker/config/bin/eval-templates
index 3680ed03219..05d9bfa97c1 100755
--- a/docker/config/bin/eval-templates
+++ b/docker/config/bin/eval-templates
@@ -5,7 +5,7 @@ import glob
import os
import random
import re
-import subprocess
+import subprocess # nosec
import urllib.parse
import zipfile
from typing import cast
@@ -115,14 +115,14 @@ def _main() -> None:
if os.environ.get("VISIBLE_ENTRY_POINT"):
os.environ["VISIBLE_ENTRY_POINT_RE_ESCAPED"] = re.escape(os.environ["VISIBLE_ENTRY_POINT"])
os.environ["MAPSERVER_DATA_SUBSELECT"] = (
- "SELECT {ST_JOIN}(ra.area) "
+ "SELECT {ST_JOIN}(ra.area) " # nosec
"FROM {PGSCHEMA}.restrictionarea AS ra, {PGSCHEMA}.role_restrictionarea AS rra, "
"{PGSCHEMA}.layer_restrictionarea AS lra, {PGSCHEMA}.treeitem AS la "
"WHERE rra.role_id in (%role_ids%) AND rra.restrictionarea_id = ra.id "
"AND lra.restrictionarea_id = ra.id AND lra.layer_id = la.id AND la.name = "
).format(PGSCHEMA=os.environ["PGSCHEMA"], ST_JOIN=os.environ.get("ST_JOIN", "ST_Collect"))
os.environ["MAPSERVER_DATA_NOAREA_SUBSELECT"] = (
- "SELECT rra.role_id "
+ "SELECT rra.role_id " # nosec
"FROM {PGSCHEMA}.restrictionarea AS ra, {PGSCHEMA}.role_restrictionarea AS rra, "
"{PGSCHEMA}.layer_restrictionarea AS lra, {PGSCHEMA}.treeitem AS la "
"WHERE rra.restrictionarea_id = ra.id AND lra.restrictionarea_id = ra.id "
diff --git a/docker/qgisserver/.bandit.yaml b/docker/qgisserver/.bandit.yaml
deleted file mode 100644
index 1bf9b483e1a..00000000000
--- a/docker/qgisserver/.bandit.yaml
+++ /dev/null
@@ -1,2 +0,0 @@
-skips:
- - B101 # Use of assert detected.
diff --git a/docker/qgisserver/.prospector.yaml b/docker/qgisserver/.prospector.yaml
index 7c072ce7a21..98eacd5fdbf 100644
--- a/docker/qgisserver/.prospector.yaml
+++ b/docker/qgisserver/.prospector.yaml
@@ -3,10 +3,11 @@ inherits:
- utils:base
- utils:fix
- utils:no-design-checks
+ - utils:unsafe
pyroma:
run: False
-bandit:
+mypy:
options:
- config: .bandit.yaml
+ python_version: '3.10'
diff --git a/docker/qgisserver/geomapfish_qgisserver/__init__.py b/docker/qgisserver/geomapfish_qgisserver/__init__.py
index f0e30ef8309..1791d1ff675 100644
--- a/docker/qgisserver/geomapfish_qgisserver/__init__.py
+++ b/docker/qgisserver/geomapfish_qgisserver/__init__.py
@@ -34,7 +34,9 @@ def serverClassFactory( # pylint: disable=invalid-name
_LOG.info("Starting GeoMapFish access restriction...")
try:
- from .accesscontrol import GeoMapFishAccessControl # pylint: disable=import-outside-toplevel
+ from .accesscontrol import (
+ GeoMapFishAccessControl, # pylint: disable=import-outside-toplevel
+ )
return GeoMapFishAccessControl(serverIface)
except Exception: # pylint: disable=broad-exception-caught
diff --git a/docker/qgisserver/geomapfish_qgisserver/accesscontrol.py b/docker/qgisserver/geomapfish_qgisserver/accesscontrol.py
index 7e421bceef3..ddc8df3c2d8 100644
--- a/docker/qgisserver/geomapfish_qgisserver/accesscontrol.py
+++ b/docker/qgisserver/geomapfish_qgisserver/accesscontrol.py
@@ -20,6 +20,7 @@
import yaml
import zope.event.classhandler
from c2c.template.config import config
+from c2cgeoportal_commons.lib.url import Url, get_url2
from qgis.core import (
QgsDataSourceUri,
QgsFeature,
@@ -35,10 +36,10 @@
from sqlalchemy.orm import configure_mappers, joinedload, sessionmaker, subqueryload
from sqlalchemy.orm.session import Session
-from c2cgeoportal_commons.lib.url import Url, get_url2
-
if TYPE_CHECKING:
- from c2cgeoportal_commons.models import main # pylint: disable=ungrouped-imports,useless-suppression
+ from c2cgeoportal_commons.models import (
+ main, # pylint: disable=ungrouped-imports,useless-suppression
+ )
_LOG = logging.getLogger(__name__)
@@ -58,7 +59,7 @@ def create_session_factory(url: str, configuration: dict[str, Any]) -> sessionma
class GMFException(Exception):
- """Standard exception"""
+ """Standard exception."""
class Access(Enum):
@@ -341,7 +342,7 @@ def __init__(
self.DBSession = DBSession # pylint: disable=invalid-name
self.area_cache: dict[Any, tuple[Access, BaseGeometry]] = {}
- self.layers: dict[str, list["main.LayerWMS"]] | None = None
+ self.layers: dict[str, list[main.LayerWMS]] | None = None
self.lock = Lock()
self.srid = srid
self.ogcserver = ogcserver
@@ -473,10 +474,14 @@ def browse(path: list[str], node: QgsLayerTreeNode) -> None:
def get_roles(self, session: Session) -> str | list["main.Role"]:
"""
Get the current user's available roles based on request parameter USER_ID.
+
Returns:
- List of c2cgeoportal_commons.models.main.Role instances.
+
"""
- from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.main import (
+ Role, # pylint: disable=import-outside-toplevel
+ )
parameters = self.serverInterface().requestHandler().parameterMap()
@@ -514,8 +519,8 @@ def get_restriction_areas(
Returns:
- Access mode (NO | AREA | FULL)
- List of access areas as shapely geometric objects
- """
+ """
# Root...
if roles == "ROOT":
return Access.FULL, None
@@ -528,7 +533,9 @@ def get_restriction_areas(
if not roles:
return Access.NO, None
- from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.main import (
+ Role, # pylint: disable=import-outside-toplevel
+ )
restriction_areas = set()
for layer in gmf_layers:
@@ -554,9 +561,11 @@ def get_restriction_areas(
def get_area(self, layer: str, session: Session, read_write: bool = False) -> tuple[Access, BaseGeometry]:
"""
Calculate access area for a QgsMapLayer and an access mode.
+
Returns:
- Access mode (NO | AREA | FULL)
- Access area as WKT or None
+
"""
roles = self.get_roles(session)
if roles == "ROOT":
@@ -588,10 +597,7 @@ def get_area(self, layer: str, session: Session, read_write: bool = False) -> tu
return (Access.AREA, area)
def layerFilterSubsetString(self, layer: QgsVectorLayer) -> str | None: # pylint: disable=invalid-name
- """
- Returns an additional subset string (typically SQL) filter.
- """
-
+ """Returns an additional subset string (typically SQL) filter."""
_LOG.debug("layerFilterSubsetString %s %s", layer.name(), layer.dataProvider().storageType())
if self.ogcserver is None:
@@ -633,10 +639,7 @@ def layerFilterSubsetString(self, layer: QgsVectorLayer) -> str | None: # pylin
raise
def layerFilterExpression(self, layer: QgsVectorLayer) -> str | None: # pylint: disable=invalid-name
- """
- Returns an additional expression filter.
- """
-
+ """Returns an additional expression filter."""
_LOG.debug("layerFilterExpression %s %s", layer.name(), layer.dataProvider().storageType())
if self.ogcserver is None:
@@ -678,10 +681,7 @@ def layerFilterExpression(self, layer: QgsVectorLayer) -> str | None: # pylint:
def layerPermissions( # pylint: disable=invalid-name
self, layer: QgsVectorLayer
) -> qgis.server.QgsAccessControlFilter.LayerPermissions:
- """
- Returns the layer rights.
- """
-
+ """Returns the layer rights."""
_LOG.debug("layerPermissions %s", layer.name())
try:
@@ -725,10 +725,7 @@ def layerPermissions( # pylint: disable=invalid-name
def authorizedLayerAttributes( # pylint: disable=invalid-name
self, layer: QgsVectorLayer, attributes: list[str]
) -> list[str]:
- """
- Returns the authorized layer attributes.
- """
-
+ """Returns the authorized layer attributes."""
roles = self.get_roles(self.DBSession())
if roles == "ROOT":
return attributes
diff --git a/docker/qgisserver/geomapfish_qgisserver/gmf_logging.py b/docker/qgisserver/geomapfish_qgisserver/gmf_logging.py
index f8f82d57942..c0d95eaca38 100644
--- a/docker/qgisserver/geomapfish_qgisserver/gmf_logging.py
+++ b/docker/qgisserver/geomapfish_qgisserver/gmf_logging.py
@@ -37,9 +37,7 @@ def emit(self, record: logging.LogRecord) -> None:
class _RequestFilter(logging.Filter):
- """
- A logging filter that adds request information to CEE logs.
- """
+ """A logging filter that adds request information to CEE logs."""
def filter(self, record: Any) -> bool:
request_handler = SERVER_IFACE.requestHandler() if SERVER_IFACE else None
@@ -66,13 +64,13 @@ def filter(self, record: Any) -> bool:
class JsonLogHandler(c2cwsgiutils.pyramid_logging.JsonLogHandler):
- """
- Log to stdout in JSON.
- """
+ """Log to stdout in JSON."""
def __init__(self, stream: TextIO | None) -> None:
+ """Constructor."""
super().__init__(stream)
self.addFilter(_REQUEST_FILTER)
def emit(self, record: logging.LogRecord) -> None:
+ """Emit the record."""
QgsMessageLog.logMessage(self.format(record), record.name, level=Qgis.Critical)
diff --git a/docker/qgisserver/poetry.lock b/docker/qgisserver/poetry.lock
index 9d04896bb67..d8fc2352acd 100644
--- a/docker/qgisserver/poetry.lock
+++ b/docker/qgisserver/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
[[package]]
name = "astroid"
@@ -1007,6 +1007,7 @@ pylint-django = ">=2.6.1"
pylint-flask = "0.6"
PyYAML = "*"
requirements-detector = ">=1.3.2"
+ruff = {version = "*", optional = true, markers = "extra == \"with-ruff\" or extra == \"with_everything\""}
setoptconf-tmp = ">=0.3.1,<0.4.0"
toml = ">=0.10.2,<0.11.0"
@@ -1416,6 +1417,33 @@ typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.1
[package.extras]
jupyter = ["ipywidgets (>=7.5.1,<9)"]
+[[package]]
+name = "ruff"
+version = "0.8.1"
+description = "An extremely fast Python linter and code formatter, written in Rust."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"},
+ {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"},
+ {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"},
+ {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"},
+ {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"},
+ {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"},
+ {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"},
+ {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"},
+ {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"},
+ {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"},
+ {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"},
+]
+
[[package]]
name = "semver"
version = "3.0.2"
@@ -2015,4 +2043,4 @@ test = ["zope.testing"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.10,<3.13"
-content-hash = "b0baac3eb7b2e7b3ba939035e02fca84001764b6ce40d0a0bf0cc1fd4e442e85"
+content-hash = "c8b2c78df70ab71817b89f0a09a672456017e1598eff4d86fbeeb41dd1dfcfca"
diff --git a/docker/qgisserver/pyproject.toml b/docker/qgisserver/pyproject.toml
index f213313f26d..5c9851cc624 100644
--- a/docker/qgisserver/pyproject.toml
+++ b/docker/qgisserver/pyproject.toml
@@ -1,20 +1,5 @@
-[tool.mypy]
-python_version = 3.10
-warn_redundant_casts = true
-warn_unused_ignores = true
-check_untyped_defs = true
-skip_version_check = true
-ignore_missing_imports = true
-
-[tool.black]
-line-length = 110
-target-version = ['py310']
-
-[tool.isort]
-profile = "black"
-line_length = 110
-known_third_party = "c2cwsgiutils,c2cgeoform,qgis,pytest"
-known_first_party = ["geomapfish_qgisserver", "c2cgeoportal_commons"]
+[tool.ruff]
+target-version = 'py310'
[tool.poetry]
name = 'c2cgeoportal'
@@ -38,7 +23,7 @@ psycopg2 = "2.9.10"
pytz = "2024.2"
[tool.poetry.dev-dependencies]
-prospector = { extras = ["with_mypy", "with_bandit"], version = "1.13.3" }
+prospector = { version = "1.13.3", extras = ["with_mypy", "with_bandit", "with_ruff"] }
prospector-profile-duplicated = "1.8.0"
prospector-profile-utils = "1.13.0"
types-pyyaml = "6.0.12.20240917"
diff --git a/docker/qgisserver/tests/functional/accesscontrol_allow_to_edit_test.py b/docker/qgisserver/tests/functional/accesscontrol_allow_to_edit_test.py
index dba24217fd9..739a333560f 100644
--- a/docker/qgisserver/tests/functional/accesscontrol_allow_to_edit_test.py
+++ b/docker/qgisserver/tests/functional/accesscontrol_allow_to_edit_test.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018-2023, Camptocamp SA
+# Copyright (c) 2018-2024, Camptocamp SA
# All rights reserved.
# This program is free software; you can redistribute it and/or modify it under the terms of the
@@ -12,9 +12,10 @@
from qgis.core import QgsFeature, QgsGeometry, QgsProject
from shapely.geometry import LineString, box
-from .accesscontrol_test import add_node_in_qgis_project, set_request_parameters
from geomapfish_qgisserver.accesscontrol import OGCServerAccessControl
+from .accesscontrol_test import add_node_in_qgis_project, set_request_parameters
+
area1 = box(400000, 70000, 800000, 100000)
geom_in = LineString([[500000, 80000], [500000, 90000]])
geom_intersects = LineString([[500000, 50000], [500000, 90000]])
@@ -155,6 +156,4 @@ def test_allow_to_edit(self, server_iface, DBSession, test_data2): # noqa: igno
geom.fromWkb(geometry.wkb)
feature.setGeometry(geom)
result = ogcserver_accesscontrol.allowToEdit(layer, feature)
- assert expected == result, "allowToEdit with '{}', should return '{}'.".format(
- user_name, expected
- )
+ assert expected == result, f"allowToEdit with '{user_name}', should return '{expected}'."
diff --git a/docker/qgisserver/tests/functional/accesscontrol_protected_attributes_test.py b/docker/qgisserver/tests/functional/accesscontrol_protected_attributes_test.py
index 7cb3d899fe1..8e8a7d30d02 100644
--- a/docker/qgisserver/tests/functional/accesscontrol_protected_attributes_test.py
+++ b/docker/qgisserver/tests/functional/accesscontrol_protected_attributes_test.py
@@ -8,11 +8,15 @@
from unittest.mock import patch
import pytest
-from qgis.core import QgsProject, QgsVectorLayer
+from qgis.core import QgsProject
from shapely.geometry import box
+from geomapfish_qgisserver.accesscontrol import (
+ GeoMapFishAccessControl,
+ OGCServerAccessControl,
+)
+
from .accesscontrol_test import add_node_in_qgis_project, set_request_parameters
-from geomapfish_qgisserver.accesscontrol import GeoMapFishAccessControl, OGCServerAccessControl
area1 = box(485869.5728, 76443.1884, 837076.5648, 299941.7864)
@@ -124,7 +128,13 @@ def _test_data_protected(clean_dbsession, protected: bool):
@pytest.fixture(scope="module")
def test_data_not_protected(clean_dbsession):
- from c2cgeoportal_commons.models.main import Functionality, LayerWMS, Metadata, OGCServer, Role
+ from c2cgeoportal_commons.models.main import (
+ Functionality,
+ LayerWMS,
+ Metadata,
+ OGCServer,
+ Role,
+ )
from c2cgeoportal_commons.models.static import User
test_data = _test_data_protected(clean_dbsession, False)
@@ -140,7 +150,13 @@ def test_data_not_protected(clean_dbsession):
@pytest.fixture(scope="module")
def test_data_protected(clean_dbsession):
- from c2cgeoportal_commons.models.main import Functionality, LayerWMS, Metadata, OGCServer, Role
+ from c2cgeoportal_commons.models.main import (
+ Functionality,
+ LayerWMS,
+ Metadata,
+ OGCServer,
+ Role,
+ )
from c2cgeoportal_commons.models.static import User
test_data = _test_data_protected(clean_dbsession, True)
diff --git a/docker/qgisserver/tests/functional/accesscontrol_test.py b/docker/qgisserver/tests/functional/accesscontrol_test.py
index c210f311b0b..6d6d161be5d 100644
--- a/docker/qgisserver/tests/functional/accesscontrol_test.py
+++ b/docker/qgisserver/tests/functional/accesscontrol_test.py
@@ -22,7 +22,9 @@
area1 = box(485869.5728, 76443.1884, 837076.5648, 299941.7864)
-def set_request_parameters(server_iface, params, env={}):
+def set_request_parameters(server_iface, params, env=None):
+ if env is None:
+ env = {}
server_iface.configure_mock(
**{
"configFilePath.return_value": params.get("MAP", None),
@@ -199,9 +201,7 @@ def test_data(clean_dbsession):
@pytest.fixture(scope="function")
def wms_use_layer_ids(test_data):
- """
- Activate WMSUseLayerIDs.
- """
+ """Activate WMSUseLayerIDs."""
project = test_data["project"]
try:
project.writeEntry("WMSUseLayerIDs", "/", True)
@@ -267,7 +267,7 @@ def test_get_layers(self, server_iface, DBSession, test_data): # noqa: ignore=N
layers = ogcserver_accesscontrol.get_layers(dbsession)
assert set(expected.keys()) == set(layers.keys())
- for key in expected.keys():
+ for key in expected:
assert set(expected[key]) == {layer.name for layer in layers[key]}
def test_get_roles(self, server_iface, DBSession, test_data): # noqa: ignore=N803
@@ -277,7 +277,7 @@ def test_get_roles(self, server_iface, DBSession, test_data): # noqa: ignore=N8
)
set_request_parameters(server_iface, {"USER_ID": "0"})
- assert "ROOT" == ogcserver_accesscontrol.get_roles(dbsession)
+ assert ogcserver_accesscontrol.get_roles(dbsession) == "ROOT"
test_users = test_data["users"]
test_roles = test_data["roles"]
@@ -306,11 +306,11 @@ def test_get_restriction_areas(self, server_iface, DBSession, test_data): # noq
server_iface, "qgisserver1", "no_project", 21781, lambda: dbsession
)
- assert (Access.FULL, None) == ogcserver_accesscontrol.get_restriction_areas(
+ assert ogcserver_accesscontrol.get_restriction_areas(
dbsession.query(LayerWMS).filter(LayerWMS.name == "private_layer1").one(),
read_write=True,
roles="ROOT",
- )
+ ) == (Access.FULL, None)
for layer_names, rw, role_names, expected in (
(("private_layer1",), False, ("role1",), (Access.AREA, [area1])),
@@ -322,9 +322,9 @@ def test_get_restriction_areas(self, server_iface, DBSession, test_data): # noq
]
roles = [dbsession.query(Role).filter(Role.name == role_name).one() for role_name in role_names]
ras = ogcserver_accesscontrol.get_restriction_areas(layers, rw, roles)
- assert expected == ras, "get_restriction_areas with {} should return {}".format(
- (layer_names, rw, role_names), expected
- )
+ assert (
+ expected == ras
+ ), f"get_restriction_areas with {(layer_names, rw, role_names)} should return {expected}"
def test_get_area(self, server_iface, DBSession, test_data): # noqa: ignore=N803
dbsession = DBSession()
@@ -395,8 +395,8 @@ def test_cache_key(server_iface, DBSession, test_data): # noqa: ignore=N803
)
set_request_parameters(server_iface, {"USER_ID": "0"}, {"HTTP_HOST": "example.com"})
- assert "0" == server_iface.requestHandler().parameter("USER_ID")
- assert "example.com-ROOT" == ogcserver_accesscontrol.cacheKey()
+ assert server_iface.requestHandler().parameter("USER_ID") == "0"
+ assert ogcserver_accesscontrol.cacheKey() == "example.com-ROOT"
user = test_data["users"]["user12"]
role1 = test_data["roles"]["role1"]
diff --git a/docker/qgisserver/tests/functional/conftest.py b/docker/qgisserver/tests/functional/conftest.py
index 9988539040d..340a3280ce4 100644
--- a/docker/qgisserver/tests/functional/conftest.py
+++ b/docker/qgisserver/tests/functional/conftest.py
@@ -3,12 +3,11 @@
import pytest
from c2c.template.config import config
+from c2cgeoportal_commons.testing import generate_mappers
from qgis.server import QgsServerInterface
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
-from c2cgeoportal_commons.testing import generate_mappers
-
@pytest.fixture(scope="session")
def settings():
@@ -33,7 +32,14 @@ def DBSession(settings): # noqa: ignore=N802
@pytest.fixture(scope="module")
@pytest.mark.usefixtures("DBSession")
def clean_dbsession(DBSession): # noqa: ignore=N803
- from c2cgeoportal_commons.models.main import OGCServer, RestrictionArea, Role, TreeItem, layer_ra, role_ra
+ from c2cgeoportal_commons.models.main import (
+ OGCServer,
+ RestrictionArea,
+ Role,
+ TreeItem,
+ layer_ra,
+ role_ra,
+ )
from c2cgeoportal_commons.models.static import User, user_role
def clean():
diff --git a/geoportal/c2cgeoportal_geoportal/__init__.py b/geoportal/c2cgeoportal_geoportal/__init__.py
index 2e38add0feb..857f3c3c30d 100644
--- a/geoportal/c2cgeoportal_geoportal/__init__.py
+++ b/geoportal/c2cgeoportal_geoportal/__init__.py
@@ -37,6 +37,7 @@
from typing import TYPE_CHECKING, Any, Optional, cast
import c2cgeoform
+import c2cgeoportal_commons.models
import c2cwsgiutils
import c2cwsgiutils.db
import c2cwsgiutils.index
@@ -50,6 +51,7 @@
import sqlalchemy.orm
import zope.event.classhandler
from c2cgeoform import translator
+from c2cgeoportal_commons.models import InvalidateCacheEvent
from c2cwsgiutils.health_check import HealthCheck
from c2cwsgiutils.prometheus import MemoryMapCollector
from deform import Form
@@ -62,10 +64,14 @@
from pyramid_mako import add_mako_renderer
from sqlalchemy.orm import joinedload
-import c2cgeoportal_commons.models
import c2cgeoportal_geoportal.views
-from c2cgeoportal_commons.models import InvalidateCacheEvent
-from c2cgeoportal_geoportal.lib import C2CPregenerator, caching, check_collector, checker, oidc
+from c2cgeoportal_geoportal.lib import (
+ C2CPregenerator,
+ caching,
+ check_collector,
+ checker,
+ oidc,
+)
from c2cgeoportal_geoportal.lib.cacheversion import version_cache_buster
from c2cgeoportal_geoportal.lib.caching import get_region
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
@@ -79,7 +85,9 @@
from c2cgeoportal_geoportal.views.entry import Entry, canvas_view, custom_view
if TYPE_CHECKING:
- from c2cgeoportal_commons.models import static # pylint: disable=ungrouped-imports,useless-suppression
+ from c2cgeoportal_commons.models import (
+ static, # pylint: disable=ungrouped-imports,useless-suppression
+ )
_LOG = logging.getLogger(__name__)
@@ -174,7 +182,6 @@ def add_interface_ngeo(
permission: str | None = None,
) -> None:
"""Add the ngeo interfaces views and routes."""
-
config.add_route(route_name, route, request_method="GET")
# Permalink theme: recover the theme for generating custom viewer.js url
config.add_route(
@@ -202,7 +209,6 @@ def add_interface_canvas(
permission: str | None = None,
) -> None:
"""Add the ngeo interfaces views and routes."""
-
renderer = f"/etc/geomapfish/interfaces/{route_name}.html.mako"
config.add_route(route_name, route, request_method="GET")
# Permalink theme: recover the theme for generating custom viewer.js URL
@@ -235,7 +241,6 @@ def add_interface_custom(
permission: str | None = None,
) -> None:
"""Add custom interfaces views and routes."""
-
config.add_route(route_name, route, request_method="GET")
# Permalink theme: recover the theme for generating custom viewer.js URL
config.add_route(
@@ -259,7 +264,6 @@ def add_interface_custom(
def add_admin_interface(config: pyramid.config.Configurator) -> None:
"""Add the administration interface views and routes."""
-
assert c2cgeoportal_commons.models.DBSession is not None
config.add_request_method(
@@ -318,7 +322,6 @@ def is_allowed_url(
Allowed if URL netloc is request host or is found in allowed hosts.
"""
-
url_netloc = urllib.parse.urlparse(url).netloc
return url_netloc, url_netloc == request.host or url_netloc in _get_netlocs(allowed_hosts)
@@ -329,7 +332,6 @@ def is_allowed_host(request: pyramid.request.Request) -> bool:
Allowed if URL netloc is request host or is found in allowed hosts.
"""
-
return request.host in request.registry.settings.get("allowed_hosts", [])
@@ -354,7 +356,7 @@ def is_valid_referrer(request: pyramid.request.Request, settings: dict[str, Any]
def create_get_user_from_request(
- settings: dict[str, Any]
+ settings: dict[str, Any],
) -> Callable[[pyramid.request.Request, str | None], Optional["static.User"]]:
"""Get the get_user_from_request function."""
@@ -370,8 +372,12 @@ def get_user_from_request(
* it has been deactivated
* the referrer is invalid
"""
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
+ from c2cgeoportal_commons.models.static import ( # pylint: disable=import-outside-toplevel
+ User,
+ )
assert DBSession is not None
@@ -467,8 +473,12 @@ def default_user_validator(request: pyramid.request.Request, username: str, pass
otherwise.
"""
del request # unused
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
+ from c2cgeoportal_commons.models.static import ( # pylint: disable=import-outside-toplevel
+ User,
+ )
assert DBSession is not None
@@ -930,7 +940,9 @@ def init_db_sessions(
)
c2cgeoportal_commons.models.Base.metadata.clear()
- from c2cgeoportal_commons.models import main # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ main,
+ )
if health_check is not None:
for name, session in c2cgeoportal_commons.models.DBSessions.items():
diff --git a/geoportal/c2cgeoportal_geoportal/lib/__init__.py b/geoportal/c2cgeoportal_geoportal/lib/__init__.py
index 35906491655..b531a7dbee8 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/__init__.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/__init__.py
@@ -38,10 +38,10 @@
import dateutil
import pyramid.request
import pyramid.response
+from c2cgeoportal_commons.lib.url import get_url2
from pyramid.interfaces import IRoutePregenerator
from zope.interface import implementer
-from c2cgeoportal_commons.lib.url import get_url2
from c2cgeoportal_geoportal.lib.cacheversion import get_cache_version
from c2cgeoportal_geoportal.lib.caching import get_region
@@ -145,8 +145,12 @@ def get_setting(settings: Any, path: Iterable[str], default: Any = None) -> Any:
@_CACHE_REGION_OBJ.cache_on_arguments()
def get_ogc_server_wms_url_ids(request: pyramid.request.Request, host: str) -> dict[str, list[int]]:
"""Get the OGCServer ids mapped on the WMS URL."""
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.main import OGCServer # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ OGCServer,
+ )
del host # used for cache
assert DBSession is not None
@@ -163,8 +167,12 @@ def get_ogc_server_wms_url_ids(request: pyramid.request.Request, host: str) -> d
@_CACHE_REGION_OBJ.cache_on_arguments()
def get_ogc_server_wfs_url_ids(request: pyramid.request.Request, host: str) -> dict[str, list[int]]:
"""Get the OGCServer ids mapped on the WFS URL."""
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.main import OGCServer # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ OGCServer,
+ )
del host # used for cache
assert DBSession is not None
@@ -218,7 +226,10 @@ def _get_intranet_networks(
@_CACHE_REGION.cache_on_arguments()
def get_role_id(name: str) -> int:
"""Get the role ID."""
- from c2cgeoportal_commons.models import DBSession, main # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ main,
+ )
assert DBSession is not None
@@ -250,7 +261,4 @@ def get_roles_name(request: pyramid.request.Request) -> pyramid.response.Respons
def is_intranet(request: pyramid.request.Request) -> bool:
"""Get if it's an intranet user."""
address = ipaddress.ip_address(request.client_addr)
- for network in _get_intranet_networks(request):
- if address in network:
- return True
- return False
+ return any(address in network for network in _get_intranet_networks(request))
diff --git a/geoportal/c2cgeoportal_geoportal/lib/authentication.py b/geoportal/c2cgeoportal_geoportal/lib/authentication.py
index b8feb9dd2e3..e311524f3a0 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/authentication.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/authentication.py
@@ -67,7 +67,7 @@ def __init__(
self.debug = debug
def unauthenticated_userid(self, request: pyramid.request.Request) -> str | None:
- if not request.method == "GET" or "auth" not in request.params:
+ if request.method != "GET" or "auth" not in request.params:
return None
auth_enc = request.params.get("auth")
if auth_enc is None:
diff --git a/geoportal/c2cgeoportal_geoportal/lib/caching.py b/geoportal/c2cgeoportal_geoportal/lib/caching.py
index 826c5ef2546..f887b7c7281 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/caching.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/caching.py
@@ -33,6 +33,7 @@
import pyramid.interfaces
import zope.interface
+from c2cgeoportal_commons.models import Base
from dogpile.cache.api import NO_VALUE, CacheBackend, CachedValue, NoValue
from dogpile.cache.backends.memory import MemoryBackend
from dogpile.cache.backends.redis import RedisBackend, RedisSentinelBackend
@@ -40,8 +41,6 @@
from dogpile.cache.util import sha1_mangle_key
from sqlalchemy.orm.util import identity_key
-from c2cgeoportal_commons.models import Base
-
if TYPE_CHECKING:
from dogpile.cache.api import SerializedReturnType
else:
@@ -65,7 +64,6 @@ def keygen_function(namespace: Any, function: Callable[..., Any]) -> Callable[..
This is used by :meth:`.CacheRegion.cache_on_arguments` to generate a cache key from a decorated function.
"""
-
if namespace is None:
namespace = (function.__module__, function.__name__)
else:
@@ -140,7 +138,7 @@ def get(self, key: str) -> CachedValue | bytes | NoValue:
assert isinstance(val, bytes)
value = self._redis.deserializer(val) # type: ignore[misc]
if value != NO_VALUE and self._use_memory_cache:
- assert isinstance(value, (CachedValue, bytes))
+ assert isinstance(value, CachedValue | bytes)
self._memory.set(key, value)
return value
diff --git a/geoportal/c2cgeoportal_geoportal/lib/checker.py b/geoportal/c2cgeoportal_geoportal/lib/checker.py
index 710ba551ae3..9b9abdd5a0e 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/checker.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/checker.py
@@ -147,8 +147,8 @@ def check(_request: pyramid.request.Request, response: pyramid.response.Response
health_check.add_url_check(
name="checker_fulltextsearch",
- url=lambda r: get_both(r)["url"], # type: ignore
- headers=lambda r: get_both(r)["headers"], # type: ignore
+ url=lambda r: get_both(r)["url"], # type: ignore[misc]
+ headers=lambda r: get_both(r)["headers"], # type: ignore[misc]
params={"query": fts_settings["search"], "limit": "1"},
check_cb=check,
level=fts_settings["level"],
@@ -156,8 +156,12 @@ def check(_request: pyramid.request.Request, response: pyramid.response.Response
def _themes_errors(settings: dict[str, Any], health_check: c2cwsgiutils.health_check.HealthCheck) -> None:
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.main import Interface # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ Interface,
+ )
assert DBSession is not None
@@ -256,7 +260,7 @@ def __call__(self, request: pyramid.request.Request) -> None:
cmd: list[str] = ["check-example", url]
env = dict(os.environ)
for name, value in self.route.get("environment", {}).items():
- if isinstance(value, (list, dict)):
+ if isinstance(value, list | dict):
value = json.dumps(value)
elif not isinstance(value, str):
value = str(value)
diff --git a/geoportal/c2cgeoportal_geoportal/lib/common_headers.py b/geoportal/c2cgeoportal_geoportal/lib/common_headers.py
index c80a59c271f..3d276abfcc2 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/common_headers.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/common_headers.py
@@ -123,7 +123,6 @@ def _set_common_headers(
content_type: str | None,
) -> pyramid.response.Response:
"""Set the common headers."""
-
response.headers.update(service_headers_settings.get("headers", {}))
if cache in (Cache.PRIVATE, Cache.PRIVATE_NO):
diff --git a/geoportal/c2cgeoportal_geoportal/lib/dbreflection.py b/geoportal/c2cgeoportal_geoportal/lib/dbreflection.py
index 6fcaaaa8b50..feb0c0b989d 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/dbreflection.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/dbreflection.py
@@ -76,7 +76,9 @@ def __get__(
return getattr(target, self.value_attr) if target else None
def __set__(self, obj: str, val: str) -> None:
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
assert DBSession is not None
@@ -118,8 +120,10 @@ def get_table(
engine = session.bind.engine
metadata = MetaData()
else:
- from c2cgeoportal_commons.models import Base # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ Base,
+ DBSession,
+ )
assert DBSession is not None
assert DBSession.bind is not None
@@ -162,7 +166,6 @@ def get_class(
valid string. If there is no table identified by tablename in the database a NoSuchTableError SQLAlchemy
exception is raised.
"""
-
tablename, schema = _get_schema(tablename)
table = get_table(tablename, schema, None, primary_key=primary_key)
@@ -187,7 +190,9 @@ def _create_class(
readonly_attributes: list[str] | None = None,
pk_name: str | None = None,
) -> type:
- from c2cgeoportal_commons.models import Base # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ Base,
+ )
exclude_properties = exclude_properties or ()
attributes = {
@@ -201,7 +206,7 @@ def _create_class(
# The randint is to fix the SAWarning: This declarative base already contains a class with the same
# class name and module name
cls = type(
- f"{table.name.capitalize()}_{random.randint(0, 9999999)}", # nosec
+ f"{table.name.capitalize()}_{random.randint(0, 9999999)}", # noqa: S311
(GeoInterface, Base),
attributes,
)
diff --git a/geoportal/c2cgeoportal_geoportal/lib/filter_capabilities.py b/geoportal/c2cgeoportal_geoportal/lib/filter_capabilities.py
index c1f2f566b87..ea5946a499f 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/filter_capabilities.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/filter_capabilities.py
@@ -32,25 +32,33 @@
import xml.sax.xmlreader # nosec
from collections.abc import Callable
from io import StringIO
-from typing import Any, Union
+from typing import Any
from xml.sax.saxutils import XMLFilterBase, XMLGenerator # nosec
import defusedxml.expatreader
import pyramid.httpexceptions
import pyramid.request
import requests
+from c2cgeoportal_commons.lib.url import Url
from owslib.map.wms111 import ContentMetadata as ContentMetadata111
from owslib.map.wms130 import ContentMetadata as ContentMetadata130
from owslib.wms import WebMapService
from pyramid.httpexceptions import HTTPBadGateway
-from c2cgeoportal_commons.lib.url import Url
-from c2cgeoportal_geoportal.lib import caching, get_ogc_server_wfs_url_ids, get_ogc_server_wms_url_ids
-from c2cgeoportal_geoportal.lib.layers import get_private_layers, get_protected_layers, get_writable_layers
+from c2cgeoportal_geoportal.lib import (
+ caching,
+ get_ogc_server_wfs_url_ids,
+ get_ogc_server_wms_url_ids,
+)
+from c2cgeoportal_geoportal.lib.layers import (
+ get_private_layers,
+ get_protected_layers,
+ get_writable_layers,
+)
_CACHE_REGION = caching.get_region("std")
_LOG = logging.getLogger(__name__)
-ContentMetadata = Union[ContentMetadata111, ContentMetadata130]
+ContentMetadata = ContentMetadata111 | ContentMetadata130
@_CACHE_REGION.cache_on_arguments()
@@ -111,7 +119,6 @@ def filter_capabilities(
request: pyramid.request.Request, content: str, wms: bool, url: Url, headers: dict[str, str]
) -> str:
"""Filter the WMS/WFS capabilities."""
-
wms_structure_ = wms_structure(request, url, headers.get("Host"))
ogc_server_ids = (
@@ -153,7 +160,6 @@ def filter_capabilities(
def filter_wfst_capabilities(content: str, wfs_url: Url, request: pyramid.request.Request) -> str:
"""Filter the WTS capabilities."""
-
writable_layers: set[str] = set()
ogc_server_ids = get_ogc_server_wfs_url_ids(request, request.host).get(wfs_url.url())
if ogc_server_ids is None:
@@ -312,7 +318,7 @@ def _keep_layer(self, layer_name: str) -> bool:
)
def characters(self, content: str) -> None:
- if self.in_name and self.layers_path and not self.layers_path[-1].self_hidden is True:
+ if self.in_name and self.layers_path and self.layers_path[-1].self_hidden is not True:
layer_name = normalize_typename(content)
if self._keep_layer(layer_name):
for layer in self.layers_path:
@@ -342,9 +348,8 @@ def normalize_tag(tag: str) -> str:
e.g. '{https://....}TypeName' -> 'TypeName'
"""
normalized = tag
- if len(tag) >= 3:
- if tag[0] == "{":
- normalized = tag[1:].split("}")[1]
+ if len(tag) >= 3 and tag[0] == "{":
+ normalized = tag[1:].split("}")[1]
return normalized.lower()
diff --git a/geoportal/c2cgeoportal_geoportal/lib/functionality.py b/geoportal/c2cgeoportal_geoportal/lib/functionality.py
index bcc2179f94c..74563b3ae1f 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/functionality.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/functionality.py
@@ -30,9 +30,9 @@
from typing import Any, cast
import pyramid.request
+from c2cgeoportal_commons.models import main, static
from sqlalchemy.orm import joinedload
-from c2cgeoportal_commons.models import main, static
from c2cgeoportal_geoportal.lib import get_typed, get_types_map, is_intranet
from c2cgeoportal_geoportal.lib.caching import get_region
@@ -43,7 +43,9 @@
@_CACHE_REGION_OBJ.cache_on_arguments()
def _get_role(name: str) -> dict[str, Any]:
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
assert DBSession is not None
diff --git a/geoportal/c2cgeoportal_geoportal/lib/layers.py b/geoportal/c2cgeoportal_geoportal/lib/layers.py
index 99fdb221655..115a44fb791 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/layers.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/layers.py
@@ -42,7 +42,10 @@
def _get_layers_query(request: Request, what: sqlalchemy.orm.Mapper[Any] | type[Any]) -> Query[Any]:
- from c2cgeoportal_commons.models import DBSession, main # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ main,
+ )
assert DBSession is not None
@@ -64,7 +67,9 @@ def get_protected_layers_query(
Private layers but accessible to the user.
"""
- from c2cgeoportal_commons.models import main # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ main,
+ )
q = _get_layers_query(request, what)
q = q.filter(main.Layer.public.is_(False))
@@ -76,7 +81,9 @@ def get_protected_layers_query(
def get_writable_layers_query(request: Request, ogc_server_ids: Iterable[int]) -> Query["main.LayerWMS"]:
"""Get the writable layers query."""
- from c2cgeoportal_commons.models import main # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ main,
+ )
q = _get_layers_query(request, main.LayerWMS)
return (
@@ -92,7 +99,10 @@ def get_protected_layers(request: Request, ogc_server_ids: Iterable[int]) -> dic
Private layers but accessible to the user.
"""
- from c2cgeoportal_commons.models import DBSession, main # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ main,
+ )
assert DBSession is not None
@@ -104,7 +114,9 @@ def get_protected_layers(request: Request, ogc_server_ids: Iterable[int]) -> dic
def get_writable_layers(request: Request, ogc_server_ids: Iterable[int]) -> dict[int, "main.LayerWMS"]:
"""Get the writable layers."""
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
assert DBSession is not None
@@ -117,7 +129,10 @@ def get_writable_layers(request: Request, ogc_server_ids: Iterable[int]) -> dict
@CACHE_REGION.cache_on_arguments()
def get_private_layers(ogc_server_ids: Iterable[int]) -> dict[int, "main.LayerWMS"]:
"""Get the private layers."""
- from c2cgeoportal_commons.models import DBSession, main # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ main,
+ )
assert DBSession is not None
diff --git a/geoportal/c2cgeoportal_geoportal/lib/lingva_extractor.py b/geoportal/c2cgeoportal_geoportal/lib/lingva_extractor.py
index 253606f9fa1..59a72a6210e 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/lingva_extractor.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/lingva_extractor.py
@@ -29,10 +29,10 @@
import json
import os
import re
-import subprocess
+import subprocess # nosec
import traceback
from collections.abc import Callable
-from typing import TYPE_CHECKING, Any, Optional, cast
+from typing import TYPE_CHECKING, Any, cast
from xml.dom import Node
from xml.parsers.expat import ExpatError
@@ -42,6 +42,7 @@
import yaml
from bottle import MakoTemplate, template
from c2c.template.config import config
+from c2cgeoportal_commons.lib.url import Url, get_url2
from defusedxml.minidom import parseString
from geoalchemy2.types import Geometry
from lingva.extractors import Extractor, Message
@@ -54,13 +55,14 @@
from sqlalchemy.orm.util import class_mapper
import c2cgeoportal_geoportal
-from c2cgeoportal_commons.lib.url import Url, get_url2
from c2cgeoportal_geoportal.lib.bashcolor import Color, colorize
from c2cgeoportal_geoportal.lib.caching import init_region
from c2cgeoportal_geoportal.views.layers import Layers, get_layer_class
if TYPE_CHECKING:
- from c2cgeoportal_commons.models import main # pylint: disable=ungrouped-imports,useless-suppression
+ from c2cgeoportal_commons.models import (
+ main, # pylint: disable=ungrouped-imports,useless-suppression
+ )
class LinguaExtractorException(Exception):
@@ -76,7 +78,7 @@ def _get_config(key: str, default: str | None = None) -> str | None:
"""
request = pyramid.threadlocal.get_current_request()
if request is not None:
- return cast(Optional[str], request.params.get(key.lower(), default))
+ return cast(str | None, request.params.get(key.lower(), default))
return os.environ.get(key, default)
@@ -174,23 +176,23 @@ def __call__(
int_filename = filename
if re.match("^" + re.escape(f"./{self.config['package']}/templates"), filename):
try:
- empty_template = Template("") # nosec
+ empty_template = Template("") # noqa: S702
- class Lookup(TemplateLookup): # type: ignore
+ class Lookup(TemplateLookup): # type: ignore[misc]
def get_template(self, uri: str) -> Template:
del uri # unused
return empty_template
- class MyTemplate(MakoTemplate): # type: ignore
+ class MyTemplate(MakoTemplate): # type: ignore[misc]
tpl = None
def prepare(self, **kwargs: Any) -> None:
options.update({"input_encoding": self.encoding})
lookup = Lookup(**kwargs)
if self.source:
- self.tpl = Template(self.source, lookup=lookup, **kwargs) # nosec
+ self.tpl = Template(self.source, lookup=lookup, **kwargs) # noqa: S702
else:
- self.tpl = Template( # nosec
+ self.tpl = Template( # noqa: S702
uri=self.name, filename=self.filename, lookup=lookup, **kwargs
)
@@ -252,10 +254,13 @@ def init_db(settings: dict[str, Any]) -> None:
First test the connection, on when environment it should be OK, with the command line we should get
an exception ind initialize the connection.
"""
-
try:
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.main import Theme # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ Theme,
+ )
assert DBSession is not None
@@ -302,7 +307,7 @@ def __call__(
init_region({"backend": "dogpile.cache.memory"}, "obj")
with open(filename, encoding="utf8") as config_file:
- gmf_config = yaml.load(config_file, Loader=yaml.BaseLoader) # nosec
+ gmf_config = yaml.load(config_file, Loader=yaml.BaseLoader) # noqa: S506
# For application config (config.yaml)
if "vars" in gmf_config:
return self._collect_app_config(filename)
@@ -332,7 +337,9 @@ def _collect_app_config(self, filename: str) -> list[Message]:
DBSession,
DBSessions,
)
- from c2cgeoportal_commons.models.main import Metadata # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ Metadata,
+ )
assert DBSession is not None
@@ -385,7 +392,6 @@ def _collect_app_config(self, filename: str) -> list[Message]:
interface_config.get("constants", {})
.get("gmfDisplayQueryGridOptions", {})
.get("mergeTabs", {})
- .keys()
):
location = (
f"interfaces_config/{interface}/constants/gmfDisplayQueryGridOptions/"
@@ -479,7 +485,9 @@ def __call__(
try:
init_db(self.config)
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
assert DBSession is not None
@@ -588,8 +596,12 @@ def _import(
has_interfaces: bool = True,
name_regex: str = ".*",
) -> None:
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.main import Interface # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ Interface,
+ )
assert DBSession is not None
@@ -667,8 +679,12 @@ def _import_layer_wms(self, layer: "main.Layer", messages: list[str]) -> None:
raise
def _import_layer_wmts(self, layer: "main.Layer", messages: list[str]) -> None:
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.main import OGCServer # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ OGCServer,
+ )
assert DBSession is not None
diff --git a/geoportal/c2cgeoportal_geoportal/lib/oauth2.py b/geoportal/c2cgeoportal_geoportal/lib/oauth2.py
index a43daed74f3..9becfd4aa28 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/oauth2.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/oauth2.py
@@ -30,12 +30,12 @@
from typing import Any, TypedDict
import basicauth
+import c2cgeoportal_commons
import oauthlib.common
import oauthlib.oauth2
import pyramid.threadlocal
from pyramid.httpexceptions import HTTPBadRequest
-import c2cgeoportal_commons
from c2cgeoportal_geoportal.lib.caching import get_region
_LOG = logging.getLogger(__name__)
@@ -73,9 +73,11 @@ def authenticate_client(
both body and query can be obtained by direct attribute access, i.e.
request.client_id for client_id in the URL query.
- Keyword Arguments:
-
- request: oauthlib.common.Request
+ Arguments:
+ ---------
+ request: oauthlib.common.Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Returns: True or False
@@ -86,6 +88,7 @@ def authenticate_client(
- Refresh Token Grant
.. _`HTTP Basic Authentication Scheme`: https://tools.ietf.org/html/rfc1945#section-11.1
+
"""
del args, kwargs
@@ -117,7 +120,10 @@ def authenticate_client_id(
_LOG.debug("authenticate_client_id %s", client_id)
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -163,9 +169,11 @@ def client_authentication_required(
client credentials or whenever Client provided client authentication, see
`Section 6`_
- Keyword Arguments:
-
- request: oauthlib.common.Request
+ Arguments:
+ ---------
+ request: oauthlib.common.Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Returns: True or False
@@ -177,6 +185,7 @@ def client_authentication_required(
.. _`Section 4.3.2`: https://tools.ietf.org/html/rfc6749#section-4.3.2
.. _`Section 4.1.3`: https://tools.ietf.org/html/rfc6749#section-4.1.3
.. _`Section 6`: https://tools.ietf.org/html/rfc6749#section-6
+
"""
del request, args, kwargs
@@ -205,24 +214,30 @@ def confirm_redirect_uri(
the client's allowed redirect URIs, but against the URI used when the
code was saved.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- code: Unicode authorization_code.
- redirect_uri: Unicode absolute URI
- client: Client object set by you, see authenticate_client.
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ code: Unicode authorization_code.
+ redirect_uri: Unicode absolute URI
+ client: Client object set by you, see authenticate_client.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Returns: True or False
Method is used by:
- Authorization Code Grant (during token request)
+
"""
del args, kwargs
_LOG.debug("confirm_redirect_uri %s %s", client_id, redirect_uri)
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -248,16 +263,19 @@ def get_default_redirect_uri(
"""
Get the default redirect URI for the client.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Returns: The default redirect URI for the client
Method is used by:
- Authorization Code Grant
- Implicit Grant
+
"""
del request, args, kwargs
@@ -275,10 +293,12 @@ def get_default_scopes(
"""
Get the default scopes for the client.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Returns: List of default scopes
@@ -287,6 +307,7 @@ def get_default_scopes(
- Implicit Grant
- Resource Owner Password Credentials Grant
- Client Credentials grant
+
"""
del request, args, kwargs
@@ -304,15 +325,18 @@ def get_original_scopes(
"""
Get the list of scopes associated with the refresh token.
- Keyword Arguments:
-
- refresh_token: Unicode refresh token
- request: The HTTP Request
+ Arguments:
+ ---------
+ refresh_token: Unicode refresh token
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Returns: List of scopes.
Method is used by:
- Refresh token grant
+
"""
del refresh_token, request, args, kwargs
@@ -352,17 +376,20 @@ def introspect_token(
efficiency, but must fallback to other types to be compliant with RFC.
The dict of claims is added to request.token after this method.
- Keyword Arguments:
-
- token: The token string.
- token_type_hint: access_token or refresh_token.
- request: OAuthlib request.
+ Arguments:
+ ---------
+ token: The token string.
+ token_type_hint: access_token or refresh_token.
+ request: OAuthlib request.
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Introspect Endpoint (all grants are compatible)
.. _`Introspect Claims`: https://tools.ietf.org/html/rfc7662#section-2.2
.. _`JWT Claims`: https://tools.ietf.org/html/rfc7519#section-4
+
"""
del token, request, args, kwargs
@@ -381,20 +408,26 @@ def invalidate_authorization_code(
"""
Invalidate an authorization code after use.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- code: The authorization code grant (request.code).
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ code: The authorization code grant (request.code).
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Authorization Code Grant
+
"""
del args, kwargs
_LOG.debug("invalidate_authorization_code %s", client_id)
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -426,14 +459,17 @@ def is_within_original_scope(
used in situations where returning all valid scopes from the
get_original_scopes is not practical.
- Keyword Arguments:
-
- request_scopes: A list of scopes that were requested by client
- refresh_token: Unicode refresh_token
- request: The HTTP Request
+ Arguments:
+ ---------
+ request_scopes: A list of scopes that were requested by client
+ refresh_token: Unicode refresh_token
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Refresh token grant
+
"""
del request, args, kwargs
@@ -452,14 +488,17 @@ def revoke_token(
"""
Revoke an access or refresh token.
- Keyword Arguments:
-
- token: The token string.
- token_type_hint: access_token or refresh_token.
- request: The HTTP Request
+ Arguments:
+ ---------
+ token: The token string.
+ token_type_hint: access_token or refresh_token.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Revocation Endpoint
+
"""
del token, request, args, kwargs
@@ -475,12 +514,13 @@ def rotate_refresh_token(self, request: oauthlib.common.Request) -> bool:
or replaced with a new one (rotated). Return True to rotate and
and False for keeping original.
- Keyword Arguments:
-
- request: oauthlib.common.Request
+ Arguments:
+ ---------
+ request: oauthlib.common.Request
Method is used by:
- Refresh Token Grant
+
"""
del request
@@ -515,11 +555,13 @@ def save_authorization_code(
chose to send one. That value should be saved and used in
'validate_code'.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- code: A dict of the authorization code grant and, optionally, state.
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ code: A dict of the authorization code grant and, optionally, state.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Authorization Code Grant
@@ -528,12 +570,16 @@ def save_authorization_code(
Code Challenge (request.code_challenge) and
Code Challenge Method (request.code_challenge_method)
+
"""
del args, kwargs
_LOG.debug("save_authorization_code %s", client_id)
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -604,11 +650,13 @@ def save_bearer_token(
Note that while "scope" is a string-separated list of authorized scopes,
the original list is still available in request.scopes
- Keyword Arguments:
-
- client_id: Unicode client identifier
- token: A Bearer token dict
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ token: A Bearer token dict
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Returns: The default redirect URI for the client
@@ -617,12 +665,16 @@ def save_bearer_token(
- Implicit Grant
- Resource Owner Password Credentials Grant (might not associate a client)
- Client Credentials grant
+
"""
del args, kwargs
_LOG.debug("save_bearer_token")
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -654,11 +706,11 @@ def validate_bearer_token(
"""
Ensure the Bearer token is valid and authorized access to scopes.
- Keyword Arguments:
-
- token: A string of random characters.
- scopes: A list of scopes associated with the protected resource.
- request: The HTTP Request
+ Arguments:
+ ---------
+ token: A string of random characters.
+ scopes: A list of scopes associated with the protected resource.
+ request: The HTTP Request
A key to OAuth 2 security and restricting impact of leaked tokens is
the short expiration time of tokens, *always ensure the token has not
@@ -690,22 +742,25 @@ def validate_bearer_token(
one provided for django these attributes will be made available
in all protected views as keyword arguments.
- Keyword Arguments:
-
- token: Unicode Bearer token
- scopes: List of scopes (defined by you)
- request: The HTTP Request
+ Arguments:
+ ---------
+ token: Unicode Bearer token
+ scopes: List of scopes (defined by you)
+ request: The HTTP Request
Method is indirectly used by all core Bearer token issuing grant types:
- Authorization Code Grant
- Implicit Grant
- Resource Owner Password Credentials Grant
- Client Credentials Grant
- """
+ """
_LOG.debug("validate_bearer_token %s", scopes)
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -736,20 +791,26 @@ def validate_client_id(
to set request.client to the client object associated with the
given client_id.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- request: oauthlib.common.Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ request: oauthlib.common.Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Authorization Code Grant
- Implicit Grant
+
"""
del args, kwargs
_LOG.debug("validate_client_id")
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -784,21 +845,27 @@ def validate_code(
associated with this authorization code. Similarly request.scopes
must also be set.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- code: Unicode authorization code
- client: Client object set by you, see authenticate_client.
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ code: Unicode authorization code
+ client: Client object set by you, see authenticate_client.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Authorization Code Grant
+
"""
del args, kwargs
_LOG.debug("validate_code %s", client_id)
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -839,18 +906,21 @@ def validate_grant_type(
"""
Ensure client is authorized to use the grant_type requested.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- grant_type: Unicode grant type, i.e. authorization_code, password.
- client: Client object set by you, see authenticate_client.
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ grant_type: Unicode grant type, i.e. authorization_code, password.
+ client: Client object set by you, see authenticate_client.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Authorization Code Grant
- Resource Owner Password Credentials Grant
- Client Credentials Grant
- Refresh Token Grant
+
"""
del client, request, args, kwargs
@@ -877,21 +947,27 @@ def validate_redirect_uri(
All clients should register the absolute URIs of all URIs they intend
to redirect to. The registration is outside of the scope of oauthlib.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- redirect_uri: Unicode absolute URI
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ redirect_uri: Unicode absolute URI
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Authorization Code Grant
- Implicit Grant
+
"""
del request, args, kwargs
_LOG.debug("validate_redirect_uri %s %s", client_id, redirect_uri)
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -918,22 +994,28 @@ def validate_refresh_token(
OBS! The request.user attribute should be set to the resource owner
associated with this refresh token.
- Keyword Arguments:
-
- refresh_token: Unicode refresh token
- client: Client object set by you, see authenticate_client.
- request: The HTTP Request
+ Arguments:
+ ---------
+ refresh_token: Unicode refresh token
+ client: Client object set by you, see authenticate_client.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Authorization Code Grant (indirectly by issuing refresh tokens)
- Resource Owner Password Credentials Grant (also indirectly)
- Refresh Token Grant
+
"""
del args, kwargs
_LOG.debug("validate_refresh_token %s", client.client_id if client else None)
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -961,16 +1043,19 @@ def validate_response_type(
"""
Ensure client is authorized to use the response_type requested.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- response_type: Unicode response type, i.e. code, token.
- client: Client object set by you, see authenticate_client.
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ response_type: Unicode response type, i.e. code, token.
+ client: Client object set by you, see authenticate_client.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Authorization Code Grant
- Implicit Grant
+
"""
del client, request, args, kwargs
@@ -990,18 +1075,21 @@ def validate_scopes(
"""
Ensure the client is authorized access to requested scopes.
- Keyword Arguments:
-
- client_id: Unicode client identifier
- scopes: List of scopes (defined by you)
- client: Client object set by you, see authenticate_client.
- request: The HTTP Request
+ Arguments:
+ ---------
+ client_id: Unicode client identifier
+ scopes: List of scopes (defined by you)
+ client: Client object set by you, see authenticate_client.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by all core grant types:
- Authorization Code Grant
- Implicit Grant
- Resource Owner Password Credentials Grant
- Client Credentials Grant
+
"""
del client, request, args, kwargs
@@ -1026,15 +1114,18 @@ def validate_user(
not set you will be unable to associate a token with a user in the
persistence method used (commonly, save_bearer_token).
- Keyword Arguments:
-
- username: Unicode username
- password: Unicode password
- client: Client object set by you, see authenticate_client.
- request: The HTTP Request
+ Argument:
+ ---------
+ username: Unicode username
+ password: Unicode password
+ client: Client object set by you, see authenticate_client.
+ request: The HTTP Request
+ args: Additional arguments, ignored
+ kwargs: Additional keyword arguments, ignored
Method is used by:
- Resource Owner Password Credentials Grant
+
"""
del password, client, request, args, kwargs
@@ -1056,10 +1147,10 @@ def is_pkce_required(self, client_id: int, request: oauthlib.common.Request) ->
a technique to mitigate against the threat through the use of Proof Key for Code Exchange
(PKCE, pronounced “pixy”). See RFC7636.
- Keyword Arguments:
-
- client_id: Client identifier.
- request (oauthlib.common.Request): OAuthlib request.
+ Arguments:
+ ---------
+ client_id: Client identifier.
+ request (oauthlib.common.Request): OAuthlib request.
Method is used by:
@@ -1068,7 +1159,10 @@ def is_pkce_required(self, client_id: int, request: oauthlib.common.Request) ->
"""
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -1096,20 +1190,23 @@ def get_code_challenge(self, code: str, request: oauthlib.common.Request) -> str
Return the code_challenge associated to the code. If None is returned, code is considered to not
be associated to any challenges.
- Keyword Arguments:
-
- code: Authorization code.
- request: OAuthlib request.
+ Arguments:
+ ---------
+ code: Authorization code.
+ request: OAuthlib request.
Return:
-
code_challenge string
Method is used by:
Authorization Code Grant - when PKCE is active
+
"""
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
@@ -1136,10 +1233,10 @@ def get_code_challenge_method(self, code: str, request: oauthlib.common.Request)
Must return plain or S256. You can return a custom value if you have implemented your own
AuthorizationCodeGrant class.
- Keyword Arguments:
-
- code: Authorization code.
- request: OAuthlib request.
+ Arguments:
+ ---------
+ code: Authorization code.
+ request: OAuthlib request.
Return type:
@@ -1148,8 +1245,12 @@ def get_code_challenge_method(self, code: str, request: oauthlib.common.Request)
Method is used by:
Authorization Code Grant - when PKCE is active
+
"""
- from c2cgeoportal_commons.models import DBSession, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ static,
+ )
assert DBSession is not None
diff --git a/geoportal/c2cgeoportal_geoportal/lib/oidc.py b/geoportal/c2cgeoportal_geoportal/lib/oidc.py
index 083aa2b116e..71964b445c1 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/oidc.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/oidc.py
@@ -34,7 +34,11 @@
import pyramid.response
import simple_openid_connect.client
import simple_openid_connect.data
-from pyramid.httpexceptions import HTTPBadRequest, HTTPInternalServerError, HTTPUnauthorized
+from pyramid.httpexceptions import (
+ HTTPBadRequest,
+ HTTPInternalServerError,
+ HTTPUnauthorized,
+)
from pyramid.security import remember
from c2cgeoportal_geoportal.lib.caching import get_region
@@ -48,9 +52,7 @@
# User create on demand
class DynamicUser(NamedTuple):
- """
- User created dynamically.
- """
+ """User created dynamically."""
id: int
username: str
@@ -62,10 +64,7 @@ class DynamicUser(NamedTuple):
@_CACHE_REGION_OBJ.cache_on_arguments()
def get_oidc_client(request: pyramid.request.Request, host: str) -> simple_openid_connect.client.OpenidClient:
- """
- Get the OpenID Connect client from the request settings.
- """
-
+ """Get the OpenID Connect client from the request settings."""
del host # used for cache key
authentication_settings = request.registry.settings.get("authentication", {})
@@ -83,9 +82,7 @@ def get_oidc_client(request: pyramid.request.Request, host: str) -> simple_openi
class OidcRememberObject(TypedDict):
- """
- The JSON object that is stored in a cookie to remember the user.
- """
+ """The JSON object that is stored in a cookie to remember the user."""
access_token: str
access_token_expires: str
@@ -146,11 +143,13 @@ def get_user_from_remember(
:param settings: The OpenID Connect configuration.
:param update_create_user: If the user should be updated or created if it does not exist.
"""
-
# Those imports are here to avoid initializing the models module before the database schema are
# correctly initialized.
from c2cgeoportal_commons import models # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models import main, static # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ main,
+ static,
+ )
assert models.DBSession is not None
@@ -213,9 +212,7 @@ def get_user_from_remember(
class OidcRemember:
- """
- Build the abject that we want to remember in the cookie.
- """
+ """Build the abject that we want to remember in the cookie."""
def __init__(self, request: pyramid.request.Request):
self.request = request
@@ -229,10 +226,7 @@ def remember(
),
host: str,
) -> OidcRememberObject:
- """
- Remember the user in the cookie.
- """
-
+ """Remember the user in the cookie."""
del host # Used for cache key
if isinstance(token_response, simple_openid_connect.data.TokenErrorResponse):
@@ -297,8 +291,6 @@ def remember(
def includeme(config: pyramid.config.Configurator) -> None:
- """
- Pyramid includeme function.
- """
+ """Pyramid includeme function."""
config.add_request_method(get_remember_from_user_info, name="get_remember_from_user_info")
config.add_request_method(get_user_from_remember, name="get_user_from_remember")
diff --git a/geoportal/c2cgeoportal_geoportal/lib/wmstparsing.py b/geoportal/c2cgeoportal_geoportal/lib/wmstparsing.py
index c6d4c1d7f1d..6376d63d585 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/wmstparsing.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/wmstparsing.py
@@ -57,10 +57,10 @@ class TimeInformation:
Collect the WMS time information.
Arguments:
-
extent: A time extent instance (``TimeExtentValue`` or ``TimeExtentInterval``)
mode: The layer mode ("single", "range" or "disabled")
widget: The layer mode ("slider" (default) or "datepicker")
+
"""
def __init__(self) -> None:
@@ -98,7 +98,7 @@ def merge_mode(self, mode: str) -> None:
self.mode = mode
def merge_widget(self, widget: str | None) -> None:
- widget = "slider" if not widget else widget
+ widget = widget if widget else "slider"
assert widget is not None
if self.widget is not None:
@@ -134,11 +134,11 @@ def __init__(
Initialize.
Arguments:
-
values: A set() of datetime
resolution: The resolution from the mapfile time definition
min_def_value: the minimum default value as a datetime
max_def_value: the maximum default value as a datetime
+
"""
self.values = values
self.resolution = resolution
@@ -183,13 +183,13 @@ def __init__(
Initialize.
Arguments:
-
start: The start value as a datetime
end: The end value as a datetime
interval: The interval as a tuple (years, months, days, seconds)
resolution: The resolution from the mapfile time definition
min_def_value: the minimum default value as a datetime
max_def_value: the maximum default value as a datetime
+
"""
self.start = start
self.end = end
@@ -311,7 +311,7 @@ def _parse_date(date: str) -> tuple[str, datetime.datetime]:
try:
dt = datetime.datetime.strptime(date, pattern)
return resolution, dt.replace(tzinfo=isodate.UTC)
- except Exception: # pylint: disable=broad-exception-caught # nosec
+ except Exception: # pylint: disable=broad-exception-caught
pass
try:
diff --git a/geoportal/c2cgeoportal_geoportal/lib/xsd.py b/geoportal/c2cgeoportal_geoportal/lib/xsd.py
index 96611f793e5..6c2a8e6104b 100644
--- a/geoportal/c2cgeoportal_geoportal/lib/xsd.py
+++ b/geoportal/c2cgeoportal_geoportal/lib/xsd.py
@@ -42,10 +42,8 @@
def _element_callback(tb: str, column: sqlalchemy.sql.elements.NamedColumn[Any]) -> None:
if column.info.get("readonly"):
- with tag(tb, "xsd:annotation"):
- with tag(tb, "xsd:appinfo"):
- with tag(tb, "readonly", {"value": "true"}):
- pass
+ with tag(tb, "xsd:annotation"), tag(tb, "xsd:appinfo"), tag(tb, "readonly", {"value": "true"}):
+ pass
class XSDGenerator(PapyrusXSDGenerator): # type: ignore
@@ -105,7 +103,9 @@ def add_column_property_xsd(self, tb: str, column_property: ColumnProperty[Any])
super().add_column_property_xsd(tb, column_property)
def add_association_proxy_xsd(self, tb: str, column_property: ColumnProperty[Any]) -> None:
- from c2cgeoportal_commons.models import DBSession # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models import ( # pylint: disable=import-outside-toplevel
+ DBSession,
+ )
assert DBSession is not None
@@ -125,11 +125,13 @@ def add_association_proxy_xsd(self, tb: str, column_property: ColumnProperty[Any
attrs["nillable"] = "true"
attrs["name"] = proxy
with tag(tb, "xsd:element", attrs) as tb2:
- with tag(tb2, "xsd:simpleType") as tb3:
- with tag(tb3, "xsd:restriction", {"base": "xsd:string"}) as tb4:
- for (value,) in query:
- with tag(tb4, "xsd:enumeration", {"value": value}):
- pass
+ with (
+ tag(tb2, "xsd:simpleType") as tb3,
+ tag(tb3, "xsd:restriction", {"base": "xsd:string"}) as tb4,
+ ):
+ for (value,) in query:
+ with tag(tb4, "xsd:enumeration", {"value": value}):
+ pass
self.element_callback(tb4, column)
diff --git a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml
index 1123c6f3a0e..fb7d19ccf07 100644
--- a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml
+++ b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/.prospector.yaml
@@ -1,30 +1,3 @@
inherits:
- duplicated
- - utils:no-design-checks
-
-max-line-length: 110
-
-pycodestyle:
- options:
- max-line-length: 110
- disable:
- - E203
-
-pylint:
- options:
- max-line-length: 110
- disable:
- - too-many-locals
- - too-many-statements
- - too-many-branches
- - c-extension-no-member
-
-pyflakes:
- disable:
- - F401
-
-mccabe:
- run: false
-
-bandit:
- run: true
+ - utils:base-less-strict
diff --git a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py
index 4e5dc9fffdf..7d5ae13b42b 100644
--- a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py
+++ b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/gunicorn.conf.py
@@ -109,7 +109,6 @@ def on_starting(server: gunicorn.arbiter.Arbiter) -> None:
Called just before the master process is initialized.
"""
-
del server
prometheus.start()
@@ -121,7 +120,6 @@ def post_fork(server: gunicorn.arbiter.Arbiter, worker: gunicorn.workers.base.Wo
Called just after a worker has been forked.
"""
-
del server, worker
prometheus.cleanup()
@@ -133,7 +131,6 @@ def child_exit(server: gunicorn.arbiter.Arbiter, worker: gunicorn.workers.base.W
Called just after a worker has been exited, in the master process.
"""
-
del server
multiprocess.mark_process_dead(worker.pid)
diff --git a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py
index b101439948c..98cec234489 100644
--- a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py
+++ b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/authentication.py
@@ -1,8 +1,7 @@
+from c2cgeoportal_geoportal.lib.authentication import create_authentication
from pyramid.authorization import ACLAuthorizationPolicy
from pyramid.config import Configurator
-from c2cgeoportal_geoportal.lib.authentication import create_authentication
-
def includeme(config: Configurator) -> None:
"""Initialize the authentication( for a Pyramid app."""
diff --git a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py
index 1882e6726ac..18e8462241a 100644
--- a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py
+++ b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/models.py
@@ -1,8 +1,7 @@
import logging
-from pyramid.i18n import TranslationStringFactory
-
from c2cgeoportal_commons.models.main import * # noqa: ignore=F401, pylint: disable=unused-wildcard-import
+from pyramid.i18n import TranslationStringFactory
_ = TranslationStringFactory("{{cookiecutter.package}}_geoportal-server")
_LOG = logging.getLogger(__name__)
diff --git a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py
index 25d96644183..2be921b74e8 100644
--- a/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py
+++ b/geoportal/c2cgeoportal_geoportal/scaffolds/advance_create/{{cookiecutter.project}}/geoportal/{{cookiecutter.package}}_geoportal/multi_organization.py
@@ -3,5 +3,4 @@
def includeme(config: Configurator) -> None:
"""Initialize the multi organization."""
-
del config # Unused
diff --git a/geoportal/c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/pyproject.toml b/geoportal/c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/pyproject.toml
index f1c32198485..354842adf7b 100644
--- a/geoportal/c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/pyproject.toml
+++ b/geoportal/c2cgeoportal_geoportal/scaffolds/create/{{cookiecutter.project}}/pyproject.toml
@@ -1,7 +1,2 @@
-[tool.black]
-line-length = 110
-target-version = ['py39']
-
-[tool.isort]
-profile = "black"
-line_length = 110
+[tool.ruff]
+target-version = 'py310'
diff --git a/geoportal/c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py b/geoportal/c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py
index 2440797b946..b1d34188d63 100644
--- a/geoportal/c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py
+++ b/geoportal/c2cgeoportal_geoportal/scaffolds/update/{{cookiecutter.project}}/CONST_create_template/tests/test_testapp.py
@@ -41,7 +41,7 @@ def test_desktop_alt(url: str) -> None:
def test_enum() -> None:
- """Test the enumerations view"""
+ """Test the enumerations view."""
response = requests.get("https://front/layers/test/values/type", verify=False, timeout=30) # nosec
assert response.status_code == 200, response.text
diff --git a/geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py b/geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py
index f9d2305ca39..8d8080f011f 100644
--- a/geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py
+++ b/geoportal/c2cgeoportal_geoportal/scripts/c2cupgrade.py
@@ -32,13 +32,14 @@
import os
import re
import shutil
-import subprocess
+import subprocess # nosec
import sys
+import tempfile
from argparse import ArgumentParser, Namespace
from collections.abc import Callable
from json.decoder import JSONDecodeError
-from subprocess import call, check_call, check_output
-from typing import Any, Union, cast
+from subprocess import call, check_call, check_output # nosec
+from typing import Any, cast
import pkg_resources
import requests
@@ -61,51 +62,10 @@
def fix_style() -> None:
"""Fix the style of all the project files using isort, Black and Prettier."""
-
- file_to_clean = []
- for filename, content in (
- (".prettierignore", "*.min.js\n"),
- ("pyproject.toml", "[tool.black]\nline-length = 110\ntarget-version = ['py39']\n"),
- (".prettierrc.yaml", "bracketSpacing: false\nquoteProps: preserve\n"),
- (
- ".editorconfig",
- """root = true
-[*]
-max_line_length = 110
-""",
- ),
- ):
- if not os.path.exists(filename):
- file_to_clean.append(filename)
- if os.path.exists(os.path.join("CONST_create_template", filename)):
- shutil.copyfile(os.path.join("CONST_create_template", filename), filename)
- else:
- with open(filename, "w", encoding="utf8") as file_:
- file_.write(content)
-
- if os.path.exists("ci/config.yaml"):
- os.rename("ci/config.yaml", "ci/config.yaml_")
if os.path.exists(".pre-commit-config.yaml"):
print("Run pre-commit to fix the style.")
sys.stdout.flush()
subprocess.run(["pre-commit", "run", "--all-files"]) # pylint: disable=subprocess-run-check
- else:
- print("Run c2cciutils-checks to fix the style.")
- sys.stdout.flush()
- subprocess.run( # pylint: disable=subprocess-run-check
- ["c2cciutils-checks", "--fix", "--check=isort"]
- )
- subprocess.run( # pylint: disable=subprocess-run-check
- ["c2cciutils-checks", "--fix", "--check=black"]
- )
- subprocess.run( # pylint: disable=subprocess-run-check
- ["c2cciutils-checks", "--fix", "--check=prettier"]
- )
- if os.path.exists("ci/config.yaml_"):
- os.rename("ci/config.yaml_", "ci/config.yaml")
-
- for filename in file_to_clean:
- os.remove(filename)
def main() -> None:
@@ -217,7 +177,7 @@ def get_upgrade(section: str) -> list[Any] | dict[str, Any]:
sys.exit(1)
with open(".upgrade.yaml", encoding="utf8") as project_file:
- return cast(Union[list[Any], dict[str, Any]], yaml.safe_load(project_file)[section])
+ return cast(list[Any] | dict[str, Any], yaml.safe_load(project_file)[section])
def print_step(
self,
@@ -254,7 +214,7 @@ def test_checkers(self) -> tuple[bool, str | None]:
resp = requests.get(
self.project["checker_url"],
headers=self.project.get("checker_headers"),
- verify=False, # nosec
+ verify=False, # noqa: S501
timeout=120,
)
except requests.exceptions.ConnectionError as exception:
@@ -324,12 +284,13 @@ def step0(self, step: int) -> None:
@Step(1)
def step1(self, step: int) -> None:
- shutil.copyfile("project.yaml", "/tmp/project.yaml")
- try:
- check_call(["git", "reset", "--hard"])
- check_call(["git", "clean", "--force", "-d"])
- finally:
- shutil.copyfile("/tmp/project.yaml", "project.yaml")
+ with tempfile.NamedTemporaryFile("w") as project_temp_file:
+ shutil.copyfile("project.yaml", project_temp_file)
+ try:
+ check_call(["git", "reset", "--hard"])
+ check_call(["git", "clean", "--force", "-d"])
+ finally:
+ shutil.copyfile(project_temp_file, "project.yaml")
self.run_step(step + 1)
@@ -343,36 +304,36 @@ def step2(self, step: int) -> None:
@Step(3)
def step3(self, step: int) -> None:
- project_path = os.path.join("/tmp", self.project["project_folder"])
- os.mkdir(project_path)
- shutil.copyfile("/src/project.yaml", os.path.join(project_path, "project.yaml"))
- check_call(
- [
- "pcreate",
- "--overwrite",
- "--scaffold=update",
- project_path,
- ]
- )
- if self.get_project().get("advance", False):
+ with tempfile.TemporaryDirectory() as temp_directory_name:
+ project_path = os.path.join(temp_directory_name, self.project["project_folder"])
+ os.mkdir(project_path)
+ shutil.copyfile("/src/project.yaml", os.path.join(project_path, "project.yaml"))
check_call(
[
"pcreate",
"--overwrite",
- "--scaffold=advance_update",
+ "--scaffold=update",
project_path,
]
)
+ if self.get_project().get("advance", False):
+ check_call(
+ [
+ "pcreate",
+ "--overwrite",
+ "--scaffold=advance_update",
+ project_path,
+ ]
+ )
- shutil.copyfile(os.path.join(project_path, ".upgrade.yaml"), ".upgrade.yaml")
- for upgrade_file in cast(list[dict[str, Any]], self.get_upgrade("upgrade_files")):
- action = upgrade_file["action"]
- if action == "remove":
- self.files_to_remove(upgrade_file, prefix="CONST_create_template", force=True)
- if action == "move":
- self.files_to_move(upgrade_file, prefix="CONST_create_template", force=True)
+ shutil.copyfile(os.path.join(project_path, ".upgrade.yaml"), ".upgrade.yaml")
+ for upgrade_file in cast(list[dict[str, Any]], self.get_upgrade("upgrade_files")):
+ action = upgrade_file["action"]
+ if action == "remove":
+ self.files_to_remove(upgrade_file, prefix="CONST_create_template", force=True)
+ if action == "move":
+ self.files_to_move(upgrade_file, prefix="CONST_create_template", force=True)
- shutil.rmtree(project_path)
os.remove(".upgrade.yaml")
check_call(["git", "add", "--all", "--force", "CONST_create_template/"])
@@ -385,26 +346,26 @@ def step4(self, step: int) -> None:
if os.path.exists("CONST_create_template"):
check_call(["git", "rm", "-r", "--force", "CONST_create_template/"])
- project_path = os.path.join("/tmp", self.project["project_folder"])
- check_call(["ln", "-s", "/src", project_path])
- check_call(
- [
- "pcreate",
- "--overwrite",
- "--scaffold=update",
- project_path,
- ]
- )
- if self.get_project().get("advance", False):
+ with tempfile.TemporaryDirectory() as temp_directory_name:
+ project_path = os.path.join(temp_directory_name, self.project["project_folder"])
+ check_call(["ln", "-s", "/src", project_path])
check_call(
[
"pcreate",
"--overwrite",
- "--scaffold=advance_update",
+ "--scaffold=update",
project_path,
]
)
- os.remove(project_path)
+ if self.get_project().get("advance", False):
+ check_call(
+ [
+ "pcreate",
+ "--overwrite",
+ "--scaffold=advance_update",
+ project_path,
+ ]
+ )
check_call(["git", "add", "--all", "CONST_create_template/"])
@@ -644,10 +605,7 @@ def is_managed(self, file_: str, files_to_get: bool = False) -> bool:
if not managed:
for files in self.project["managed_files"]:
- if isinstance(files, str):
- pattern = files
- else:
- pattern = files["pattern"]
+ pattern = files if isinstance(files, str) else files["pattern"]
if re.match(pattern + "$", file_):
print(f"File '{file_}' included by project config pattern `managed_files` '{pattern}'.")
print("managed", file_, pattern)
diff --git a/geoportal/c2cgeoportal_geoportal/scripts/manage_users.py b/geoportal/c2cgeoportal_geoportal/scripts/manage_users.py
index 9890e2ed825..de184a6b93f 100644
--- a/geoportal/c2cgeoportal_geoportal/scripts/manage_users.py
+++ b/geoportal/c2cgeoportal_geoportal/scripts/manage_users.py
@@ -37,7 +37,6 @@
def get_argparser() -> argparse.ArgumentParser:
"""Get the argument parser for this script."""
-
usage = """Reset a user password.
The username is used as password if the password is not provided with the corresponding option.
User can be created if it does not exist yet."""
@@ -66,7 +65,6 @@ def main() -> None:
to get the options list, do: docker compose exec geoportal manage-users --help
"""
-
parser = get_argparser()
options = parser.parse_args()
username = options.user
@@ -76,8 +74,12 @@ def main() -> None:
session = get_session(settings, transaction.manager)
# Must be done only once we have loaded the project config
- from c2cgeoportal_commons.models.main import Role # pylint: disable=import-outside-toplevel
- from c2cgeoportal_commons.models.static import User # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ Role,
+ )
+ from c2cgeoportal_commons.models.static import ( # pylint: disable=import-outside-toplevel
+ User,
+ )
print("\n")
diff --git a/geoportal/c2cgeoportal_geoportal/scripts/pcreate.py b/geoportal/c2cgeoportal_geoportal/scripts/pcreate.py
index c292b002d9f..978475a4486 100644
--- a/geoportal/c2cgeoportal_geoportal/scripts/pcreate.py
+++ b/geoportal/c2cgeoportal_geoportal/scripts/pcreate.py
@@ -29,10 +29,10 @@
import json
import os
import re
-import subprocess
+import subprocess # nosec
import sys
from argparse import ArgumentParser
-from typing import Any, Union, cast
+from typing import Any, cast
import pkg_resources
import requests
@@ -46,7 +46,6 @@
def get_argparser() -> ArgumentParser:
"""Get the argument parser for this script."""
-
parser = ArgumentParser(
prog=sys.argv[0],
add_help=True,
@@ -183,9 +182,7 @@ def get_context(self) -> dict[str, str | int]:
}
context.update(self.read_project_file())
if os.environ.get("CI") == "true":
- context["authtkt_secret"] = ( # nosec
- "io7heoDui8xaikie1rushaeGeiph8Bequei6ohchaequob6viejei0xooWeuvohf"
- )
+ context["authtkt_secret"] = "io7heoDui8xaikie1rushaeGeiph8Bequei6ohchaequob6viejei0xooWeuvohf" # noqa: S105
self.get_var(context, "srid", "Spatial Reference System Identifier (e.g. 2056): ", int)
srid = cast(int, context["srid"])
@@ -246,7 +243,7 @@ def read_project_file(self) -> dict[str, str | int]:
if os.path.exists(project_file):
with open(project_file, encoding="utf8") as f:
project = yaml.safe_load(f)
- return cast(dict[str, Union[str, int]], project.get("template_vars", {}))
+ return cast(dict[str, str | int], project.get("template_vars", {}))
else:
return {}
@@ -280,16 +277,12 @@ def epsg2bbox(srid: int) -> list[str] | None:
r = requests.get(f"https://epsg.io/?format=json&q={srid}", timeout=60)
bbox = r.json()["results"][0]["bbox"]
r = requests.get(
- "https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[1]},{bbox[0]}".format(
- srid=srid, bbox=bbox
- ),
+ f"https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[1]},{bbox[0]}",
timeout=60,
)
r1 = r.json()[0]
r = requests.get(
- "https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[3]},{bbox[2]}".format(
- srid=srid, bbox=bbox
- ),
+ f"https://epsg.io/trans?s_srs=4326&t_srs={srid}&data={bbox[3]},{bbox[2]}",
timeout=60,
)
r2 = r.json()[0]
diff --git a/geoportal/c2cgeoportal_geoportal/scripts/theme2fts.py b/geoportal/c2cgeoportal_geoportal/scripts/theme2fts.py
index 3256786eff3..04c8951f997 100644
--- a/geoportal/c2cgeoportal_geoportal/scripts/theme2fts.py
+++ b/geoportal/c2cgeoportal_geoportal/scripts/theme2fts.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2014-2023, Camptocamp SA
+# Copyright (c) 2014-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -95,7 +95,6 @@ def get_argparser() -> ArgumentParser:
def main() -> None:
"""Run the command."""
-
options = get_argparser().parse_args()
settings = get_appsettings(options)
@@ -180,7 +179,9 @@ def _add_fts(
action: str,
role: Optional["c2cgeoportal_commons.models.main.Role"],
) -> None:
- from c2cgeoportal_commons.models.main import FullTextSearch # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ FullTextSearch,
+ )
key = (
item.name if self.options.name else item.id,
@@ -248,7 +249,9 @@ def _add_group(
export: bool,
role: Optional["c2cgeoportal_commons.models.main.Role"],
) -> bool:
- from c2cgeoportal_commons.models.main import LayerGroup # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ LayerGroup,
+ )
fill = False
for child in group.children:
diff --git a/geoportal/c2cgeoportal_geoportal/scripts/urllogin.py b/geoportal/c2cgeoportal_geoportal/scripts/urllogin.py
index bedf0e61536..a1fb840214d 100644
--- a/geoportal/c2cgeoportal_geoportal/scripts/urllogin.py
+++ b/geoportal/c2cgeoportal_geoportal/scripts/urllogin.py
@@ -56,7 +56,6 @@ def create_token(aeskey: str, user: str, password: str, valid: bool) -> str:
def get_argparser() -> argparse.ArgumentParser:
"""Get the argument parser for this script."""
-
parser = argparse.ArgumentParser(description="Generate an auth token")
fill_arguments(parser, use_attribute=True)
parser.add_argument("user", help="The username")
@@ -67,7 +66,6 @@ def get_argparser() -> argparse.ArgumentParser:
def main() -> None:
"""Run the command."""
-
args = get_argparser().parse_args()
settings = get_appsettings(args)
urllogin = settings.get("urllogin", {})
diff --git a/geoportal/c2cgeoportal_geoportal/views/dev.py b/geoportal/c2cgeoportal_geoportal/views/dev.py
index dc11dad84f6..d61f78bef7b 100644
--- a/geoportal/c2cgeoportal_geoportal/views/dev.py
+++ b/geoportal/c2cgeoportal_geoportal/views/dev.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2021, Camptocamp SA
+# Copyright (c) 2011-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,10 @@
import pyramid.request
import pyramid.response
+from c2cgeoportal_commons.lib.url import Url
from pyramid.httpexceptions import HTTPFound
from pyramid.view import view_config
-from c2cgeoportal_commons.lib.url import Url
from c2cgeoportal_geoportal.views.proxy import Proxy
logger = logging.getLogger(__name__)
diff --git a/geoportal/c2cgeoportal_geoportal/views/dynamic.py b/geoportal/c2cgeoportal_geoportal/views/dynamic.py
index 7441ab71ab6..b12813a7a20 100644
--- a/geoportal/c2cgeoportal_geoportal/views/dynamic.py
+++ b/geoportal/c2cgeoportal_geoportal/views/dynamic.py
@@ -31,12 +31,12 @@
from typing import Any, cast
import pyramid.request
+from c2cgeoportal_commons import models
+from c2cgeoportal_commons.models import main
from pyramid.httpexceptions import HTTPNotFound
from pyramid.view import view_config
from sqlalchemy import func
-from c2cgeoportal_commons import models
-from c2cgeoportal_commons.models import main
from c2cgeoportal_geoportal import is_allowed_host
from c2cgeoportal_geoportal.lib.cacheversion import get_cache_version
from c2cgeoportal_geoportal.lib.caching import get_region
@@ -78,13 +78,12 @@ def _interface(
Get the interface configuration.
Arguments:
-
interface_config: Current interface configuration
interface_name: Interface name (we use in the configuration)
original_interface_name: Original interface name (directly for the query string)
dynamic: The values that's dynamically generated
- """
+ """
if "extends" in interface_config:
constants = self._interface(
self.interfaces_config[interface_config["extends"]],
diff --git a/geoportal/c2cgeoportal_geoportal/views/entry.py b/geoportal/c2cgeoportal_geoportal/views/entry.py
index ec566170c3f..444008d203f 100644
--- a/geoportal/c2cgeoportal_geoportal/views/entry.py
+++ b/geoportal/c2cgeoportal_geoportal/views/entry.py
@@ -114,7 +114,6 @@ def _get_ngeo_resources(pattern: str) -> list[str]:
def canvas_view(request: pyramid.request.Request, interface_config: dict[str, Any]) -> dict[str, Any]:
"""Get view used as entry point of a canvas interface."""
-
js_files = _get_ngeo_resources(f"{interface_config.get('layout', interface_config['name'])}*.js")
css_files = _get_ngeo_resources(f"{interface_config.get('layout', interface_config['name'])}*.css")
css = "\n ".join(
@@ -149,7 +148,6 @@ def custom_view(
request: pyramid.request.Request, interface_config: dict[str, Any]
) -> pyramid.response.Response:
"""Get view used as entry point of a canvas interface."""
-
set_common_headers(request, "index", Cache.PUBLIC_NO, content_type="text/html")
html_filename = interface_config.get("html_filename", f"{interface_config['name']}.html")
diff --git a/geoportal/c2cgeoportal_geoportal/views/fulltextsearch.py b/geoportal/c2cgeoportal_geoportal/views/fulltextsearch.py
index d2f1f8cbd15..ee041b8e21e 100644
--- a/geoportal/c2cgeoportal_geoportal/views/fulltextsearch.py
+++ b/geoportal/c2cgeoportal_geoportal/views/fulltextsearch.py
@@ -29,14 +29,14 @@
import re
import pyramid.request
+from c2cgeoportal_commons.models import DBSession
+from c2cgeoportal_commons.models.main import FullTextSearch, Interface
from geoalchemy2.shape import to_shape
from geojson import Feature, FeatureCollection
from pyramid.httpexceptions import HTTPBadRequest, HTTPInternalServerError
from pyramid.view import view_config
from sqlalchemy import ColumnElement, and_, desc, func, or_
-from c2cgeoportal_commons.models import DBSession
-from c2cgeoportal_commons.models.main import FullTextSearch, Interface
from c2cgeoportal_geoportal import locale_negotiator
from c2cgeoportal_geoportal.lib.caching import get_region
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
diff --git a/geoportal/c2cgeoportal_geoportal/views/geometry_processing.py b/geoportal/c2cgeoportal_geoportal/views/geometry_processing.py
index 47f66abdc77..de7620570db 100644
--- a/geoportal/c2cgeoportal_geoportal/views/geometry_processing.py
+++ b/geoportal/c2cgeoportal_geoportal/views/geometry_processing.py
@@ -27,6 +27,7 @@
import pyramid.request
+from c2cgeoportal_commons.models import DBSession
from geoalchemy2.shape import from_shape, to_shape
from geojson import loads
from pyramid.httpexceptions import HTTPBadRequest
@@ -35,8 +36,6 @@
from shapely.geometry.base import BaseGeometry
from sqlalchemy import func
-from c2cgeoportal_commons.models import DBSession
-
class GeometryProcessing:
"""
diff --git a/geoportal/c2cgeoportal_geoportal/views/i18n.py b/geoportal/c2cgeoportal_geoportal/views/i18n.py
index aa21d76eed7..5e7cdb1e781 100644
--- a/geoportal/c2cgeoportal_geoportal/views/i18n.py
+++ b/geoportal/c2cgeoportal_geoportal/views/i18n.py
@@ -68,7 +68,6 @@ def locale(request: pyramid.request.Request) -> pyramid.response.Response:
@view_config(route_name="localepot") # type: ignore
def localepot(request: pyramid.request.Request) -> pyramid.response.Response:
"""Get the pot from an HTTP request."""
-
# Build the list of files to be processed
sources = []
sources += glob.glob(f"/app/{request.registry.package_name}/static-ngeo/js/apps/*.html.ejs")
diff --git a/geoportal/c2cgeoportal_geoportal/views/layers.py b/geoportal/c2cgeoportal_geoportal/views/layers.py
index 491d2a8e145..13328badbe3 100644
--- a/geoportal/c2cgeoportal_geoportal/views/layers.py
+++ b/geoportal/c2cgeoportal_geoportal/views/layers.py
@@ -40,6 +40,7 @@
import sqlalchemy.ext.declarative
import sqlalchemy.orm
import sqlalchemy.orm.query
+from c2cgeoportal_commons import models
from geoalchemy2 import Geometry
from geoalchemy2.shape import from_shape, to_shape
from geojson.feature import Feature, FeatureCollection
@@ -56,19 +57,27 @@
from shapely import unary_union
from shapely.errors import TopologicalError
from sqlalchemy import Enum, Numeric, String, Text, Unicode, UnicodeText, exc, func
-from sqlalchemy.orm.exc import MultipleResultsFound, NoResultFound # type: ignore[attr-defined]
+from sqlalchemy.orm.exc import ( # type: ignore[attr-defined]
+ MultipleResultsFound,
+ NoResultFound,
+)
from sqlalchemy.orm.properties import ColumnProperty
from sqlalchemy.orm.util import class_mapper
from sqlalchemy.sql import and_, or_
-from c2cgeoportal_commons import models
from c2cgeoportal_geoportal.lib import get_roles_id
from c2cgeoportal_geoportal.lib.caching import get_region
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
-from c2cgeoportal_geoportal.lib.dbreflection import _AssociationProxy, get_class, get_table
+from c2cgeoportal_geoportal.lib.dbreflection import (
+ _AssociationProxy,
+ get_class,
+ get_table,
+)
if TYPE_CHECKING:
- from c2cgeoportal_commons.models import main # pylint: disable=ungrouped-imports.useless-suppression
+ from c2cgeoportal_commons.models import (
+ main, # pylint: disable=ungrouped-imports.useless-suppression
+ )
_LOG = logging.getLogger(__name__)
@@ -222,7 +231,9 @@ def _get_geom_col_info(layer: "main.Layer") -> tuple[str, int]:
@staticmethod
def _get_layer(layer_id: int) -> "main.Layer":
"""Return a ``Layer`` object for ``layer_id``."""
- from c2cgeoportal_commons.models.main import Layer # pylint: disable=import-outside-toplevel
+ from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
+ Layer,
+ )
assert models.DBSession is not None
@@ -281,7 +292,6 @@ def _get_protocol_for_request(self) -> Protocol:
def _proto_read(self, layer: "main.Layer") -> FeatureCollection:
"""Read features for the layer based on the self.request."""
-
from c2cgeoportal_commons.models.main import ( # pylint: disable=import-outside-toplevel
Layer,
RestrictionArea,
@@ -495,7 +505,7 @@ def enumerate_attribute_values(self) -> dict[str, Any]:
raise HTTPInternalServerError("Missing configuration")
layername = self.request.matchdict["layer_name"]
fieldname = self.request.matchdict["field_name"]
- # TODO check if layer is public or not
+ # TODO check if layer is public or not # pylint: disable=fixme
return cast(dict[str, Any], self._enumerate_attribute_values(layername, fieldname))
@@ -541,15 +551,14 @@ def get_layer_class(layer: "main.Layer", with_last_update_columns: bool = False)
Get the SQLAlchemy class to edit a GeoMapFish layer.
Keyword Arguments:
-
layer: The GeoMapFish layer
with_last_update_columns: False to just have a class to access to the table and be able to
modify the last_update_columns, True to have a correct class to build the UI
(without the hidden column).
Returns: SQLAlchemy class
- """
+ """
assert layer.geo_table is not None
# Exclude the columns used to record the last features update
@@ -616,7 +625,6 @@ class ColumnProperties(TypedDict, total=False):
def get_layer_metadata(layer: "main.Layer") -> list[ColumnProperties]:
"""Get the metadata related to a layer."""
-
assert models.DBSession is not None
cls = get_layer_class(layer, with_last_update_columns=True)
@@ -690,7 +698,7 @@ def _convert_column_type(column_type: object) -> ColumnProperties:
return restriction
# String type
- if isinstance(column_type, (String, Text, Unicode, UnicodeText)):
+ if isinstance(column_type, String | Text | Unicode | UnicodeText):
if column_type.length is None:
return {"type": "xsd:string"}
return {"type": "xsd:string", "maxLength": int(column_type.length)}
diff --git a/geoportal/c2cgeoportal_geoportal/views/login.py b/geoportal/c2cgeoportal_geoportal/views/login.py
index 2d812a3c94b..fd061bf6a0c 100644
--- a/geoportal/c2cgeoportal_geoportal/views/login.py
+++ b/geoportal/c2cgeoportal_geoportal/views/login.py
@@ -38,6 +38,9 @@
import pyotp
import pyramid.request
import pyramid.response
+from c2cgeoportal_commons import models
+from c2cgeoportal_commons.lib.email_ import send_email_config
+from c2cgeoportal_commons.models import static
from pyramid.httpexceptions import (
HTTPBadRequest,
HTTPForbidden,
@@ -50,9 +53,6 @@
from pyramid.view import forbidden_view_config, view_config
from sqlalchemy.orm.exc import NoResultFound # type: ignore[attr-defined]
-from c2cgeoportal_commons import models
-from c2cgeoportal_commons.lib.email_ import send_email_config
-from c2cgeoportal_commons.models import static
from c2cgeoportal_geoportal import is_allowed_url, is_valid_referrer
from c2cgeoportal_geoportal.lib import get_setting, is_intranet, oauth2, oidc
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
@@ -126,9 +126,7 @@ def loginform(self) -> dict[str, Any]:
@staticmethod
def _validate_2fa_totp(user: static.User, otp: str) -> bool:
- if pyotp.TOTP(user.tech_data.get("2fa_totp_secret", "")).verify(otp):
- return True
- return False
+ return bool(pyotp.TOTP(user.tech_data.get("2fa_totp_secret", "")).verify(otp))
@view_config(route_name="login") # type: ignore
def login(self) -> pyramid.response.Response:
@@ -374,10 +372,9 @@ def change_password(self) -> pyramid.response.Response:
_LOG.info("The login '%s' does not exist.", login)
raise HTTPUnauthorized("See server logs for details")
- if self.two_factor_auth:
- if not self._validate_2fa_totp(user, otp):
- _LOG.info("The second factor is wrong for user '%s'.", login)
- raise HTTPUnauthorized("See server logs for details")
+ if self.two_factor_auth and not self._validate_2fa_totp(user, otp):
+ _LOG.info("The second factor is wrong for user '%s'.", login)
+ raise HTTPUnauthorized("See server logs for details")
else:
user = self.request.user
@@ -662,7 +659,7 @@ def oidc_callback(self) -> pyramid.response.Response:
"login",
Cache.PRIVATE_NO,
response=Response(
- # TODO respect the user interface...
+ # TODO respect the user interface... # pylint: disable=fixme
json.dumps(
{
"username": user.display_name,
diff --git a/geoportal/c2cgeoportal_geoportal/views/mapserverproxy.py b/geoportal/c2cgeoportal_geoportal/views/mapserverproxy.py
index 474530112f8..3e9875a416e 100644
--- a/geoportal/c2cgeoportal_geoportal/views/mapserverproxy.py
+++ b/geoportal/c2cgeoportal_geoportal/views/mapserverproxy.py
@@ -29,13 +29,18 @@
import logging
from typing import Any
-from pyramid.httpexceptions import HTTPForbidden, HTTPFound, HTTPInternalServerError, HTTPUnauthorized
+from c2cgeoportal_commons.lib.url import Url
+from c2cgeoportal_commons.models import main
+from pyramid.httpexceptions import (
+ HTTPForbidden,
+ HTTPFound,
+ HTTPInternalServerError,
+ HTTPUnauthorized,
+)
from pyramid.request import Request
from pyramid.response import Response
from pyramid.view import view_config
-from c2cgeoportal_commons.lib.url import Url
-from c2cgeoportal_commons.models import main
from c2cgeoportal_geoportal.lib import get_roles_id, get_roles_name
from c2cgeoportal_geoportal.lib.caching import get_region
from c2cgeoportal_geoportal.lib.common_headers import Cache
diff --git a/geoportal/c2cgeoportal_geoportal/views/ogcproxy.py b/geoportal/c2cgeoportal_geoportal/views/ogcproxy.py
index ca0298e3de3..dd1d12c2ca8 100644
--- a/geoportal/c2cgeoportal_geoportal/views/ogcproxy.py
+++ b/geoportal/c2cgeoportal_geoportal/views/ogcproxy.py
@@ -28,11 +28,11 @@
import logging
import pyramid.request
+from c2cgeoportal_commons.lib.url import Url, get_url2
+from c2cgeoportal_commons.models import DBSession, main
from pyramid.httpexceptions import HTTPBadRequest
from sqlalchemy.orm.exc import NoResultFound # type: ignore[attr-defined]
-from c2cgeoportal_commons.lib.url import Url, get_url2
-from c2cgeoportal_commons.models import DBSession, main
from c2cgeoportal_geoportal.lib.caching import get_region
from c2cgeoportal_geoportal.views.proxy import Proxy
diff --git a/geoportal/c2cgeoportal_geoportal/views/pdfreport.py b/geoportal/c2cgeoportal_geoportal/views/pdfreport.py
index 4342daf0cd1..3d5d2b9505f 100644
--- a/geoportal/c2cgeoportal_geoportal/views/pdfreport.py
+++ b/geoportal/c2cgeoportal_geoportal/views/pdfreport.py
@@ -31,12 +31,12 @@
import pyramid.request
import pyramid.response
-from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden
-from pyramid.view import view_config
-
from c2cgeoportal_commons import models
from c2cgeoportal_commons.lib.url import Url
from c2cgeoportal_commons.models import main
+from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden
+from pyramid.view import view_config
+
from c2cgeoportal_geoportal.lib.common_headers import Cache
from c2cgeoportal_geoportal.lib.layers import get_private_layers, get_protected_layers
from c2cgeoportal_geoportal.views.ogcproxy import OGCProxy
@@ -121,7 +121,7 @@ def get_report(self) -> pyramid.response.Response:
)
if layer_config["check_credentials"]:
- # FIXME: support of mapserver groups
+ # FIXME: support of mapserver groups # pylint: disable=fixme
ogc_server = (
models.DBSession.query(main.OGCServer)
.filter(main.OGCServer.name == layer_config["ogc_server"])
diff --git a/geoportal/c2cgeoportal_geoportal/views/printproxy.py b/geoportal/c2cgeoportal_geoportal/views/printproxy.py
index a46f2736f88..2cd8bc13840 100644
--- a/geoportal/c2cgeoportal_geoportal/views/printproxy.py
+++ b/geoportal/c2cgeoportal_geoportal/views/printproxy.py
@@ -33,10 +33,10 @@
import pyramid.request
import pyramid.response
import requests
+from c2cgeoportal_commons.lib.url import Url
from pyramid.httpexceptions import HTTPBadGateway, HTTPFound
from pyramid.view import view_config
-from c2cgeoportal_commons.lib.url import Url
from c2cgeoportal_geoportal.lib import is_intranet
from c2cgeoportal_geoportal.lib.caching import get_region
from c2cgeoportal_geoportal.lib.common_headers import Cache
diff --git a/geoportal/c2cgeoportal_geoportal/views/proxy.py b/geoportal/c2cgeoportal_geoportal/views/proxy.py
index f18a2c8c805..427308ebcfa 100644
--- a/geoportal/c2cgeoportal_geoportal/views/proxy.py
+++ b/geoportal/c2cgeoportal_geoportal/views/proxy.py
@@ -33,9 +33,9 @@
import pyramid.request
import pyramid.response
import requests
+from c2cgeoportal_commons.lib.url import Url
from pyramid.httpexceptions import HTTPBadGateway, exception_response
-from c2cgeoportal_commons.lib.url import Url
from c2cgeoportal_geoportal.lib.caching import get_region
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
from c2cgeoportal_geoportal.views import restrict_headers
diff --git a/geoportal/c2cgeoportal_geoportal/views/raster.py b/geoportal/c2cgeoportal_geoportal/views/raster.py
index 5f476cc2b65..5c742dcf958 100644
--- a/geoportal/c2cgeoportal_geoportal/views/raster.py
+++ b/geoportal/c2cgeoportal_geoportal/views/raster.py
@@ -36,11 +36,11 @@
import numpy
import pyramid.request
import zope.event.classhandler
+from c2cgeoportal_commons.models import InvalidateCacheEvent
from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound
from pyramid.view import view_config
from rasterio.io import DatasetReader
-from c2cgeoportal_commons.models import InvalidateCacheEvent
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
if TYPE_CHECKING:
@@ -108,7 +108,9 @@ def _get_data(self, layer: dict[str, Any], name: str) -> "fiona.collection.Colle
path = layer["file"]
if layer.get("type", "shp_index") == "shp_index":
# Avoid loading if not needed
- from fiona.collection import Collection # pylint: disable=import-outside-toplevel
+ from fiona.collection import ( # pylint: disable=import-outside-toplevel
+ Collection,
+ )
self.data[name] = Collection(path)
elif layer.get("type") == "gdal":
diff --git a/geoportal/c2cgeoportal_geoportal/views/resourceproxy.py b/geoportal/c2cgeoportal_geoportal/views/resourceproxy.py
index 3ccef3c0672..460c9423d1f 100644
--- a/geoportal/c2cgeoportal_geoportal/views/resourceproxy.py
+++ b/geoportal/c2cgeoportal_geoportal/views/resourceproxy.py
@@ -65,7 +65,7 @@ def proxy(self) -> pyramid.response.Response:
response = self._build_response(
response, response.content, cache_control, "externalresource", content_type=content_type
)
- for header in response.headers.keys():
+ for header in response.headers:
if header not in self.settings["allowed_headers"]:
response.headers.pop(header)
return response
diff --git a/geoportal/c2cgeoportal_geoportal/views/shortener.py b/geoportal/c2cgeoportal_geoportal/views/shortener.py
index 2480734a62b..ba2aaf2d439 100644
--- a/geoportal/c2cgeoportal_geoportal/views/shortener.py
+++ b/geoportal/c2cgeoportal_geoportal/views/shortener.py
@@ -34,11 +34,16 @@
from urllib.parse import urlparse
import pyramid.request
-from pyramid.httpexceptions import HTTPBadRequest, HTTPFound, HTTPInternalServerError, HTTPNotFound
-from pyramid.view import view_config
-
from c2cgeoportal_commons.lib.email_ import send_email_config
from c2cgeoportal_commons.models import DBSession, static
+from pyramid.httpexceptions import (
+ HTTPBadRequest,
+ HTTPFound,
+ HTTPInternalServerError,
+ HTTPNotFound,
+)
+from pyramid.view import view_config
+
from c2cgeoportal_geoportal import is_allowed_url
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
@@ -107,7 +112,7 @@ def create(self) -> dict[str, str]:
tries = 0
while not shortened:
ref = "".join(
- random.choice(string.ascii_letters + string.digits) # nosec
+ random.choice(string.ascii_letters + string.digits) # noqa: S311
for i in range(self.settings.get("length", 4))
)
test_url = DBSession.query(static.Shorturl).filter(static.Shorturl.ref == ref).all()
diff --git a/geoportal/c2cgeoportal_geoportal/views/theme.py b/geoportal/c2cgeoportal_geoportal/views/theme.py
index 42f2b2c5fbf..2fa7060a2bd 100644
--- a/geoportal/c2cgeoportal_geoportal/views/theme.py
+++ b/geoportal/c2cgeoportal_geoportal/views/theme.py
@@ -35,7 +35,7 @@
import time
from collections import Counter
from math import sqrt
-from typing import Any, Optional, Union, cast
+from typing import Any, cast
import dogpile.cache.api
import pyramid.httpexceptions
@@ -43,6 +43,9 @@
import requests
import sqlalchemy
import sqlalchemy.orm.query
+from c2cgeoportal_commons import models
+from c2cgeoportal_commons.lib.url import Url, get_url2
+from c2cgeoportal_commons.models import cache_invalidate_cb, main
from c2cwsgiutils.auth import auth_view
from defusedxml import lxml
from lxml import etree # nosec
@@ -51,11 +54,13 @@
from sqlalchemy.orm import subqueryload
from sqlalchemy.orm.exc import NoResultFound # type: ignore[attr-defined]
-from c2cgeoportal_commons import models
-from c2cgeoportal_commons.lib.url import Url, get_url2
-from c2cgeoportal_commons.models import cache_invalidate_cb, main
from c2cgeoportal_geoportal import is_allowed_host, is_allowed_url
-from c2cgeoportal_geoportal.lib import get_roles_id, get_typed, get_types_map, is_intranet
+from c2cgeoportal_geoportal.lib import (
+ get_roles_id,
+ get_typed,
+ get_types_map,
+ is_intranet,
+)
from c2cgeoportal_geoportal.lib.caching import get_region
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
from c2cgeoportal_geoportal.lib.functionality import get_mapserver_substitution_params
@@ -72,7 +77,7 @@
_CACHE_OGC_SERVER_REGION = get_region("ogc-server")
_TIMEOUT = int(os.environ.get("C2CGEOPORTAL_THEME_TIMEOUT", "300"))
-Metadata = Union[str, int, float, bool, list[Any], dict[str, Any]]
+Metadata = str | int | float | bool | list[Any] | dict[str, Any]
async def get_http_cached(
@@ -323,7 +328,6 @@ async def _wms_getcap_cached(
def _create_layer_query(self, interface: str) -> sqlalchemy.orm.query.RowReturningQuery[tuple[str]]:
"""Create an SQLAlchemy query for Layer and for the role identified to by ``role_id``."""
-
assert models.DBSession is not None
query: sqlalchemy.orm.query.RowReturningQuery[tuple[str]] = models.DBSession.query(
@@ -596,7 +600,6 @@ def _layer_included(tree_item: main.TreeItem) -> bool:
def _get_ogc_servers(self, group: main.LayerGroup, depth: int) -> set[str | bool]:
"""Get unique identifier for each child by recursing on all the children."""
-
ogc_servers: set[str | bool] = set()
# escape loop
@@ -713,15 +716,14 @@ async def _group(
)
group_theme["mixed"] = mixed
- if org_depth == 1:
- if not mixed:
- assert time_ is not None
- assert dim is not None
- group_theme["ogcServer"] = cast(list[Any], ogc_servers)[0]
- if time_.has_time() and time_.layer is None:
- group_theme["time"] = time_.to_dict()
+ if org_depth == 1 and not mixed:
+ assert time_ is not None
+ assert dim is not None
+ group_theme["ogcServer"] = cast(list[Any], ogc_servers)[0]
+ if time_.has_time() and time_.layer is None:
+ group_theme["time"] = time_.to_dict()
- group_theme["dimensions"] = dim.get_dimensions()
+ group_theme["dimensions"] = dim.get_dimensions()
return group_theme, errors
return None, errors
@@ -775,7 +777,6 @@ async def _themes(
self, interface: str = "desktop", filter_themes: bool = True, min_levels: int = 1
) -> tuple[list[dict[str, Any]], set[str]]:
"""Return theme information for the role identified by ``role_id``."""
-
assert models.DBSession is not None
self._load_tree_items()
@@ -894,7 +895,7 @@ def _get_role_ids(self) -> set[int] | None:
async def _wfs_get_features_type(
self, wfs_url: Url, ogc_server: main.OGCServer, preload: bool = False, cache: bool = True
- ) -> tuple[Optional[etree.Element], set[str]]: # pylint: disable=c-extension-no-member
+ ) -> tuple[etree.Element | None, set[str]]: # pylint: disable=c-extension-no-member
errors = set()
wfs_url.add_query(
@@ -987,7 +988,8 @@ async def _preload(self, errors: set[str]) -> None:
for ogc_server, nb_layers in (
models.DBSession.query(
- main.OGCServer, sqlalchemy.func.count(main.LayerWMS.id) # pylint: disable=not-callable
+ main.OGCServer,
+ sqlalchemy.func.count(main.LayerWMS.id), # pylint: disable=not-callable
)
.filter(main.LayerWMS.ogc_server_id == main.OGCServer.id)
.group_by(main.OGCServer.id)
@@ -1037,7 +1039,7 @@ def _get_features_attributes_cache(
"available namespaces: %s (OGC server: %s)",
type_namespace,
name,
- ", ".join([str(k) for k in child.nsmap.keys()]),
+ ", ".join([str(k) for k in child.nsmap]),
ogc_server_name,
)
elif child.nsmap[type_namespace] != namespace:
@@ -1069,7 +1071,7 @@ def _get_features_attributes_cache(
"available namespaces: %s (OGC server: %s)",
type_namespace,
name,
- ", ".join([str(k) for k in child.nsmap.keys()]),
+ ", ".join([str(k) for k in child.nsmap]),
ogc_server_name,
)
for key, value in children.attrib.items():
@@ -1114,7 +1116,6 @@ def _get_features_attributes_cache(
@view_config(route_name="themes", renderer="json") # type: ignore[misc]
def themes(self) -> dict[str, dict[str, dict[str, Any]] | list[str]]:
-
is_allowed_host(self.request)
interface = self.request.params.get("interface", "desktop")
@@ -1145,7 +1146,8 @@ async def get_theme() -> dict[str, dict[str, Any] | list[str]]:
result["ogcServers"] = {}
for ogc_server, nb_layers in (
models.DBSession.query(
- main.OGCServer, sqlalchemy.func.count(main.LayerWMS.id) # pylint: disable=not-callable
+ main.OGCServer,
+ sqlalchemy.func.count(main.LayerWMS.id), # pylint: disable=not-callable
)
.filter(main.LayerWMS.ogc_server_id == main.OGCServer.id)
.group_by(main.OGCServer.id)
@@ -1239,7 +1241,7 @@ def get_theme_anonymous(
if self.request.user is None:
return cast(
- dict[str, Union[dict[str, dict[str, Any]], list[str]]],
+ dict[str, dict[str, dict[str, Any]] | list[str]],
get_theme_anonymous(
is_intranet(self.request),
interface,
diff --git a/geoportal/c2cgeoportal_geoportal/views/tinyowsproxy.py b/geoportal/c2cgeoportal_geoportal/views/tinyowsproxy.py
index 9edd8efb1f1..c33ca1c3c2b 100644
--- a/geoportal/c2cgeoportal_geoportal/views/tinyowsproxy.py
+++ b/geoportal/c2cgeoportal_geoportal/views/tinyowsproxy.py
@@ -30,13 +30,18 @@
from typing import Any
import pyramid.request
-from defusedxml import ElementTree
-from pyramid.httpexceptions import HTTPBadRequest, HTTPForbidden, HTTPInternalServerError, HTTPUnauthorized
-from pyramid.view import view_config
-
from c2cgeoportal_commons import models
from c2cgeoportal_commons.lib.url import Url
from c2cgeoportal_commons.models import main
+from defusedxml import ElementTree
+from pyramid.httpexceptions import (
+ HTTPBadRequest,
+ HTTPForbidden,
+ HTTPInternalServerError,
+ HTTPUnauthorized,
+)
+from pyramid.view import view_config
+
from c2cgeoportal_geoportal.lib.common_headers import Cache
from c2cgeoportal_geoportal.lib.filter_capabilities import (
filter_wfst_capabilities,
@@ -97,11 +102,10 @@ def proxy(self) -> pyramid.response.Response:
if operation is None or operation == "":
operation = "getcapabilities"
- if operation == "describefeaturetype":
- # for DescribeFeatureType we require that exactly one type-name
- # is given, otherwise we would have to filter the result
- if len(typenames) != 1:
- raise HTTPBadRequest("Exactly one type-name must be given for DescribeFeatureType requests")
+ # for DescribeFeatureType we require that exactly one type-name
+ # is given, otherwise we would have to filter the result
+ if operation == "describefeaturetype" and len(typenames) != 1:
+ raise HTTPBadRequest("Exactly one type-name must be given for DescribeFeatureType requests")
if not self._is_allowed(typenames):
raise HTTPForbidden("No access rights for at least one of the given type-names")
diff --git a/geoportal/c2cgeoportal_geoportal/views/vector_tiles.py b/geoportal/c2cgeoportal_geoportal/views/vector_tiles.py
index 9fd929ba9eb..78c8062bd44 100644
--- a/geoportal/c2cgeoportal_geoportal/views/vector_tiles.py
+++ b/geoportal/c2cgeoportal_geoportal/views/vector_tiles.py
@@ -28,6 +28,7 @@
import logging
import sqlalchemy
+from c2cgeoportal_commons.models import DBSession, main
from pyramid.httpexceptions import HTTPNotFound
from pyramid.request import Request
from pyramid.response import Response
@@ -35,7 +36,6 @@
from tilecloud import TileCoord
from tilecloud.grid.free import FreeTileGrid
-from c2cgeoportal_commons.models import DBSession, main
from c2cgeoportal_geoportal.lib.common_headers import Cache, set_common_headers
_LOG = logging.getLogger(__name__)
diff --git a/geoportal/tests/__init__.py b/geoportal/tests/__init__.py
index 465a966acb6..b981949bc61 100644
--- a/geoportal/tests/__init__.py
+++ b/geoportal/tests/__init__.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2023, Camptocamp SA
+# Copyright (c) 2011-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -26,9 +26,7 @@
# either expressed or implied, of the FreeBSD Project.
-"""
-Pyramid application test package.
-"""
+"""Pyramid application test package."""
import logging
import os
@@ -36,9 +34,8 @@
import warnings
import sqlalchemy.exc
-from pyramid.testing import DummyRequest as PyramidDummyRequest
-
from c2cgeoportal_geoportal.lib import caching
+from pyramid.testing import DummyRequest as PyramidDummyRequest
with warnings.catch_warnings():
warnings.simplefilter("ignore", category=sqlalchemy.exc.SAWarning)
diff --git a/geoportal/tests/functional/__init__.py b/geoportal/tests/functional/__init__.py
index 1c20f4a1950..232e980d37f 100644
--- a/geoportal/tests/functional/__init__.py
+++ b/geoportal/tests/functional/__init__.py
@@ -26,27 +26,25 @@
# either expressed or implied, of the FreeBSD Project.
-"""
-Pyramid application test package.
-"""
+"""Pyramid application test package."""
import logging
from configparser import ConfigParser
from typing import Any
+import c2cgeoportal_geoportal
+import c2cgeoportal_geoportal.lib
import pyramid.registry
import pyramid.request
import sqlalchemy.exc
-import tests
import transaction
import webob.acceptparse
from c2c.template.config import config as configuration
-from pyramid import testing
-
-import c2cgeoportal_geoportal
-import c2cgeoportal_geoportal.lib
from c2cgeoportal_commons import models
from c2cgeoportal_geoportal.lib import caching
+from pyramid import testing
+
+import tests
_LOG = logging.getLogger(__name__)
mapserv_url = "http://mapserver:8080/"
@@ -61,9 +59,7 @@ class DummyRoute:
def cleanup_db() -> None:
- """
- Cleanup the database.
- """
+ """Cleanup the database."""
from c2cgeoportal_commons import models
from c2cgeoportal_commons.models.main import (
FullTextSearch,
@@ -100,9 +96,7 @@ def cleanup_db() -> None:
def setup_db() -> None:
- """
- Cleanup the database.
- """
+ """Cleanup the database."""
cleanup_db()
from c2cgeoportal_commons.models import DBSession
@@ -204,8 +198,12 @@ def init_registry(registry=None):
def testing_legacySecurityPolicy(
config, userid=None, groupids=(), permissive=True, remember_result=None, forget_result=None
):
- """Compatibility mode for deprecated AuthorizationPolicy and AuthenticationPolicy in our tests"""
- from pyramid.interfaces import IAuthenticationPolicy, IAuthorizationPolicy, ISecurityPolicy
+ """Compatibility mode for deprecated AuthorizationPolicy and AuthenticationPolicy in our tests."""
+ from pyramid.interfaces import (
+ IAuthenticationPolicy,
+ IAuthorizationPolicy,
+ ISecurityPolicy,
+ )
from pyramid.security import LegacySecurityPolicy
from pyramid.testing import DummySecurityPolicy
@@ -221,10 +219,9 @@ def testing_legacySecurityPolicy(
def create_dummy_request(
additional_settings=None, authentication=True, user=None, *args: Any, **kargs: Any
) -> pyramid.request.Request:
- from pyramid.interfaces import IAuthenticationPolicy
-
from c2cgeoportal_geoportal import create_get_user_from_request
from c2cgeoportal_geoportal.lib.authentication import create_authentication
+ from pyramid.interfaces import IAuthenticationPolicy
if additional_settings is None:
additional_settings = {}
diff --git a/geoportal/tests/functional/conftest.py b/geoportal/tests/functional/conftest.py
index 38cf36f378c..4e66c72f5a8 100644
--- a/geoportal/tests/functional/conftest.py
+++ b/geoportal/tests/functional/conftest.py
@@ -28,13 +28,10 @@
from unittest.mock import patch
import pytest
-import sqlalchemy.orm
-import transaction
from c2c.template.config import config as configuration
from pyramid.testing import DummyRequest
-from tests.functional import setup_common as setup_module
-from c2cgeoportal_geoportal.lib import caching
+from tests.functional import setup_common as setup_module
mapserv_url = "http://mapserver:8080/"
diff --git a/geoportal/tests/functional/test_authentication.py b/geoportal/tests/functional/test_authentication.py
index aad67c7a73b..c228fa529de 100644
--- a/geoportal/tests/functional/test_authentication.py
+++ b/geoportal/tests/functional/test_authentication.py
@@ -32,15 +32,14 @@
from unittest.mock import patch
import transaction
-from tests.functional import create_dummy_request
-from tests.functional import setup_common as setup_module # noqa
-from tests.functional import teardown_common as teardown_module # noqa
-
-from c2cgeoportal_geoportal.lib import authentication
from c2cgeoportal_geoportal.lib.authentication import UrlAuthenticationPolicy
from c2cgeoportal_geoportal.resources import defaultgroupsfinder
from c2cgeoportal_geoportal.scripts.urllogin import create_token
+from tests.functional import create_dummy_request
+from tests.functional import setup_common as setup_module # noqa
+from tests.functional import teardown_common as teardown_module # noqa
+
class TestUrlAuthenticationPolicy(TestCase):
def setup_method(self, _):
@@ -110,9 +109,7 @@ def test_wrong_key(self):
@patch("c2cgeoportal_geoportal.lib.authentication._LOG.error", side_effect=Exception())
def test_wrong_method(self, log_mock): # pylint: disable=unused-argument
- """
- POST requests with input named "auth" must not raise exceptions due to urllogin.
- """
+ """POST requests with input named "auth" must not raise exceptions due to urllogin."""
def _get_user(method):
request = create_dummy_request(params={"auth": "this is a wrong field value"}, method=method)
diff --git a/geoportal/tests/functional/test_dbreflection.py b/geoportal/tests/functional/test_dbreflection.py
index 01ac7b22d6e..30b004a13a4 100644
--- a/geoportal/tests/functional/test_dbreflection.py
+++ b/geoportal/tests/functional/test_dbreflection.py
@@ -30,11 +30,11 @@
from unittest import TestCase
+from c2cgeoportal_geoportal.lib.caching import init_region
+
from tests.functional import setup_common as setup_module
from tests.functional import teardown_common as teardown_module # noqa
-from c2cgeoportal_geoportal.lib.caching import init_region
-
class TestReflection(TestCase):
_tables = None
@@ -60,11 +60,10 @@ def _create_table(self, tablename):
Each test function should call this function only once. And there should not be two test functions
that call this function with the same ptable_name value.
"""
- from geoalchemy2 import Geometry
- from sqlalchemy import Column, ForeignKey, Table, types
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Base
+ from geoalchemy2 import Geometry
+ from sqlalchemy import Column, ForeignKey, Table, types
if self._tables is None:
self._tables = []
@@ -104,16 +103,14 @@ def _create_table(self, tablename):
self.metadata = Base.metadata
def test_get_class_nonexisting_table(self):
- from sqlalchemy.exc import NoSuchTableError
-
from c2cgeoportal_geoportal.lib.dbreflection import get_class
+ from sqlalchemy.exc import NoSuchTableError
self.assertRaises(NoSuchTableError, get_class, "nonexisting")
def test_get_class(self):
- from geoalchemy2 import Geometry
-
from c2cgeoportal_geoportal.lib.dbreflection import _AssociationProxy, get_class
+ from geoalchemy2 import Geometry
init_region({"backend": "dogpile.cache.memory"}, "std")
init_region({"backend": "dogpile.cache.memory"}, "obj")
@@ -142,8 +139,8 @@ def test_get_class(self):
assert modelclass.child2_id.info.get("association_proxy") == "child2"
child1_asso_proxy = getattr(modelclass, modelclass.child1_id.info["association_proxy"])
- assert "name" == child1_asso_proxy.value_attr
- assert "name" == child1_asso_proxy.order_by
+ assert child1_asso_proxy.value_attr == "name"
+ assert child1_asso_proxy.order_by == "name"
# test the Table object
table = modelclass.__table__
@@ -192,14 +189,11 @@ def test_get_class_dotted_notation(self):
assert modelclass.__table__.schema == "public"
def test_mixing_get_class_and_queries(self):
- """
- This test shows that we can mix the use of DBSession and the db reflection API.
- """
+ """This test shows that we can mix the use of DBSession and the db reflection API."""
import transaction
- from sqlalchemy import text
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_geoportal.lib.dbreflection import get_class
+ from sqlalchemy import text
self._create_table("table_c")
@@ -239,16 +233,16 @@ def test_get_class_enumerations_config(self):
assert enumerations_config == cls.__enumerations_config__
association_proxy = getattr(cls, cls.child1_id.info["association_proxy"])
- assert "id" == association_proxy.value_attr
- assert "name" == association_proxy.order_by
+ assert association_proxy.value_attr == "id"
+ assert association_proxy.order_by == "name"
# Without order_by.
enumerations_config = {"child1_id": {"value": "id"}}
cls = get_class("table_d", enumerations_config=enumerations_config)
association_proxy = getattr(cls, cls.child1_id.info["association_proxy"])
- assert "id" == association_proxy.value_attr
- assert "id" == association_proxy.order_by
+ assert association_proxy.value_attr == "id"
+ assert association_proxy.order_by == "id"
def test_get_class_readonly_attributes(self):
from c2cgeoportal_geoportal.lib.dbreflection import get_class
@@ -258,5 +252,5 @@ def test_get_class_readonly_attributes(self):
self._create_table("table_d")
cls = get_class("table_d", readonly_attributes=readonly_attributes)
- assert True == cls.child1_id.info.get("readonly")
- assert True == cls.point.info.get("readonly")
+ assert True is cls.child1_id.info.get("readonly")
+ assert True is cls.point.info.get("readonly")
diff --git a/geoportal/tests/functional/test_dynamicview.py b/geoportal/tests/functional/test_dynamicview.py
index 1c70b54af1e..367bb7ed0dc 100644
--- a/geoportal/tests/functional/test_dynamicview.py
+++ b/geoportal/tests/functional/test_dynamicview.py
@@ -31,23 +31,20 @@
from unittest import TestCase
import pyramid.url
+from c2cgeoportal_geoportal.lib.caching import init_region
from pyramid import testing
from pyramid.testing import testConfig
-from tests import DummyRequest
-from tests.functional import setup_common as setup_module # noqa, pylint: disable=unused-import
-from tests.functional import teardown_common as teardown_module # noqa, pylint: disable=unused-import
-from c2cgeoportal_geoportal.lib.caching import init_region
+from tests import DummyRequest
class TestDynamicView(TestCase):
def setup_method(self, _):
import transaction
- from geoalchemy2 import WKTElement
- from sqlalchemy import func
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import FullTextSearch
+ from geoalchemy2 import WKTElement
+ from sqlalchemy import func
entry1 = FullTextSearch()
entry1.label = "label 1"
@@ -81,7 +78,6 @@ def teardown_method(self, _):
testing.tearDown()
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import FullTextSearch
@@ -101,7 +97,9 @@ def _get_settings(settings):
}
@staticmethod
- def _request(query={}):
+ def _request(query=None):
+ if query is None:
+ query = {}
query_ = {"interface": "test"}
query_.update(query)
request = DummyRequest(query_)
diff --git a/geoportal/tests/functional/test_entry.py b/geoportal/tests/functional/test_entry.py
index 8f33eb729ff..d092f55b02d 100644
--- a/geoportal/tests/functional/test_entry.py
+++ b/geoportal/tests/functional/test_entry.py
@@ -35,10 +35,14 @@
import transaction
from geoalchemy2 import WKTElement
from pyramid import testing
-from tests.functional import cleanup_db, create_default_ogcserver, create_dummy_request, mapserv_url
-from tests.functional import setup_common as setup_module # noqa, pylint: disable=unused-import
-from tests.functional import setup_db
-from tests.functional import teardown_common as teardown_module # noqa, pylint: disable=unused-import
+
+from tests.functional import (
+ cleanup_db,
+ create_default_ogcserver,
+ create_dummy_request,
+ mapserv_url,
+ setup_db,
+)
_LOG = logging.getLogger(__name__)
@@ -50,10 +54,6 @@ def setup_method(self, _):
self.maxDiff = None # pylint: disable=invalid-name
self._tables = []
- from geoalchemy2 import Geometry
- from sqlalchemy import Column, Table, func, types
- from sqlalchemy.ext.declarative import declarative_base
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import (
OGCSERVER_AUTH_GEOSERVER,
@@ -69,6 +69,9 @@ def setup_method(self, _):
Theme,
)
from c2cgeoportal_commons.models.static import User
+ from geoalchemy2 import Geometry
+ from sqlalchemy import Column, Table, func, types
+ from sqlalchemy.ext.declarative import declarative_base
setup_db()
diff --git a/geoportal/tests/functional/test_fulltextsearch.py b/geoportal/tests/functional/test_fulltextsearch.py
index 5a399c27909..e59a5b29c02 100644
--- a/geoportal/tests/functional/test_fulltextsearch.py
+++ b/geoportal/tests/functional/test_fulltextsearch.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
import webob.acceptparse
from pyramid import testing
from pyramid.response import Response
+
from tests.functional import create_dummy_request
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -41,12 +42,11 @@
class TestFulltextsearchView(TestCase):
def setup_method(self, _):
import transaction
- from geoalchemy2 import WKTElement
- from sqlalchemy import func
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import FullTextSearch, Interface, Role
from c2cgeoportal_commons.models.static import User
+ from geoalchemy2 import WKTElement
+ from sqlalchemy import func
role1 = Role(name="__test_role1", description="__test_role1")
user1 = User(username="__test_user1", password="__test_user1", settings_role=role1, roles=[role1])
@@ -135,7 +135,6 @@ def teardown_method(self, _):
testing.tearDown()
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import FullTextSearch, Interface, Role
from c2cgeoportal_commons.models.static import User
@@ -176,9 +175,8 @@ def _create_dummy_request(username=None, params=None):
return request
def test_no_default_laguage(self):
- from pyramid.httpexceptions import HTTPInternalServerError
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from pyramid.httpexceptions import HTTPInternalServerError
request = self._create_dummy_request()
del request.registry.settings["default_locale_name"]
@@ -189,9 +187,8 @@ def test_no_default_laguage(self):
self.assertTrue(isinstance(response, HTTPInternalServerError))
def test_unknown_laguage(self):
- from pyramid.httpexceptions import HTTPInternalServerError
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from pyramid.httpexceptions import HTTPInternalServerError
request = self._create_dummy_request()
request.registry.settings["default_locale_name"] = "it"
@@ -201,9 +198,8 @@ def test_unknown_laguage(self):
self.assertTrue(isinstance(response, HTTPInternalServerError))
def test_badrequest_noquery(self):
- from pyramid.httpexceptions import HTTPBadRequest
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from pyramid.httpexceptions import HTTPBadRequest
request = self._create_dummy_request()
fts = FullTextSearchView(request)
@@ -211,9 +207,8 @@ def test_badrequest_noquery(self):
self.assertTrue(isinstance(response, HTTPBadRequest))
def test_badrequest_limit(self):
- from pyramid.httpexceptions import HTTPBadRequest
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from pyramid.httpexceptions import HTTPBadRequest
request = self._create_dummy_request(params=dict(query="text", limit="bad"))
fts = FullTextSearchView(request)
@@ -221,9 +216,8 @@ def test_badrequest_limit(self):
self.assertTrue(isinstance(response, HTTPBadRequest))
def test_badrequest_partitionlimit(self):
- from pyramid.httpexceptions import HTTPBadRequest
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from pyramid.httpexceptions import HTTPBadRequest
request = self._create_dummy_request(params=dict(query="text", partitionlimit="bad"))
fts = FullTextSearchView(request)
@@ -231,9 +225,8 @@ def test_badrequest_partitionlimit(self):
self.assertTrue(isinstance(response, HTTPBadRequest))
def test_limit(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="tra sol", limit=1))
fts = FullTextSearchView(request)
@@ -244,9 +237,8 @@ def test_limit(self):
assert response.features[0].properties["layer_name"] == "layer1"
def test_toobig_limit(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="tra sol", limit=2000))
fts = FullTextSearchView(request)
@@ -259,9 +251,8 @@ def test_toobig_limit(self):
assert response.features[1].properties["layer_name"] == "layer1"
def test_toobig_partitionlimit(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="tra sol", partitionlimit=2000))
fts = FullTextSearchView(request)
@@ -274,9 +265,8 @@ def test_toobig_partitionlimit(self):
assert response.features[1].properties["layer_name"] == "layer1"
def test_match(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="tra sol", limit=40))
fts = FullTextSearchView(request)
@@ -289,9 +279,8 @@ def test_match(self):
assert response.features[1].properties["layer_name"] == "layer1"
def test_nomatch(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="foo"))
fts = FullTextSearchView(request)
@@ -300,9 +289,8 @@ def test_nomatch(self):
assert len(response.features) == 0
def test_private_nomatch(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="pl sem", limit=40))
fts = FullTextSearchView(request)
@@ -311,9 +299,8 @@ def test_private_nomatch(self):
assert len(response.features) == 0
def test_private_match(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="pl sem", limit=40), username="__test_user1")
fts = FullTextSearchView(request)
@@ -324,9 +311,8 @@ def test_private_match(self):
assert response.features[0].properties["layer_name"] == "layer2"
def test_private_with_role_nomatch(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="ven nei", limit=40), username="__test_user1")
fts = FullTextSearchView(request)
@@ -335,9 +321,8 @@ def test_private_with_role_nomatch(self):
assert len(response.features) == 0
def test_private_with_role_match(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="ven nei", limit=40), username="__test_user2")
fts = FullTextSearchView(request)
@@ -348,9 +333,8 @@ def test_private_with_role_match(self):
assert response.features[0].properties["layer_name"] == "layer3"
def test_match_partitionlimit(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="tra sol", limit=40, partitionlimit=1))
fts = FullTextSearchView(request)
@@ -361,9 +345,8 @@ def test_match_partitionlimit(self):
assert response.features[0].properties["layer_name"] == "layer1"
def test_params_actions(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="lausanne", limit=10))
fts = FullTextSearchView(request)
@@ -377,9 +360,8 @@ def test_params_actions(self):
)
def test_interface(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="lausanne", limit=10, interface="main"))
fts = FullTextSearchView(request)
@@ -388,9 +370,8 @@ def test_interface(self):
self.assertEqual({feature.properties["label"] for feature in response.features}, {"label5", "label6"})
def test_rank_order_with_similarity(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="simi", limit=3))
fts = FullTextSearchView(request)
@@ -402,9 +383,8 @@ def test_rank_order_with_similarity(self):
assert response.features[2].properties["label"] == "A 71 simi"
def test_rank_order_with_ts_rank_cd(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="simi", limit=3, ranksystem="ts_rank_cd"))
fts = FullTextSearchView(request)
@@ -416,9 +396,8 @@ def test_rank_order_with_ts_rank_cd(self):
assert [f.properties["label"] for f in response.features] == ["A 7 simi", "A 70 simi", "A 71 simi"]
def test_extra_quote(self):
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.fulltextsearch import FullTextSearchView
+ from geojson.feature import FeatureCollection
request = self._create_dummy_request(params=dict(query="tra 'sol"))
fts = FullTextSearchView(request)
diff --git a/geoportal/tests/functional/test_functionalities.py b/geoportal/tests/functional/test_functionalities.py
index 78f19a76f74..f9975970f7a 100644
--- a/geoportal/tests/functional/test_functionalities.py
+++ b/geoportal/tests/functional/test_functionalities.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,6 @@
class TestFunctionalities(TestCase):
def setup_method(self, _):
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Functionality, Role
from c2cgeoportal_commons.models.static import User
@@ -67,7 +66,6 @@ def setup_method(self, _):
def teardown_method(self, _):
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Functionality, OGCServer, Role
from c2cgeoportal_commons.models.static import User
@@ -89,12 +87,12 @@ def teardown_method(self, _):
transaction.commit()
def test_functionalities(self):
- from tests.functional import create_dummy_request
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.static import User
from c2cgeoportal_geoportal.lib.functionality import get_functionality
+ from tests.functional import create_dummy_request
+
request = create_dummy_request()
request.user = None
request1 = create_dummy_request()
@@ -189,11 +187,11 @@ def test_functionalities(self):
self.assertEqual(set(get_functionality("__test_a", request2, False)), {"db1", "db2"})
def test_web_client_functionalities(self):
- from tests.functional import create_dummy_request
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.static import User
+ from tests.functional import create_dummy_request
+
request = create_dummy_request()
request.static_url = lambda url: "http://example.com/dummy/static/url"
request1 = create_dummy_request()
diff --git a/geoportal/tests/functional/test_geometry_processing.py b/geoportal/tests/functional/test_geometry_processing.py
index 1966ef9db5f..aa2273394a5 100644
--- a/geoportal/tests/functional/test_geometry_processing.py
+++ b/geoportal/tests/functional/test_geometry_processing.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -37,8 +37,6 @@
class TestGeometryProcessing(TestCase):
def test_difference(self):
- from shapely.geometry import Polygon
-
from c2cgeoportal_geoportal.views.geometry_processing import GeometryProcessing
request = create_dummy_request()
diff --git a/geoportal/tests/functional/test_groups_finder.py b/geoportal/tests/functional/test_groups_finder.py
index 9aaf9e9eddc..1602a5e42af 100644
--- a/geoportal/tests/functional/test_groups_finder.py
+++ b/geoportal/tests/functional/test_groups_finder.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2023, Camptocamp SA
+# Copyright (c) 2011-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -38,7 +38,6 @@
class TestGroupsFinder(TestCase):
def setup_method(self, _):
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Role
from c2cgeoportal_commons.models.static import User
@@ -51,7 +50,6 @@ def setup_method(self, _):
def teardown_method(self, _):
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Role
from c2cgeoportal_commons.models.static import User
diff --git a/geoportal/tests/functional/test_layers.py b/geoportal/tests/functional/test_layers.py
index 3e2ed6febcb..475793356bb 100644
--- a/geoportal/tests/functional/test_layers.py
+++ b/geoportal/tests/functional/test_layers.py
@@ -31,9 +31,13 @@
from typing import TYPE_CHECKING, Any
from unittest import TestCase
-from tests.functional import cleanup_db, create_default_ogcserver, create_dummy_request
+from tests.functional import (
+ cleanup_db,
+ create_default_ogcserver,
+ create_dummy_request,
+ setup_db,
+)
from tests.functional import setup_common as setup_module # noqa
-from tests.functional import setup_db
from tests.functional import teardown_common as teardown_module # noqa
if TYPE_CHECKING:
@@ -48,7 +52,6 @@ def setup_method(self, _: Any) -> None:
setup_module()
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Interface, Role
from c2cgeoportal_commons.models.static import User
@@ -77,7 +80,6 @@ def setup_method(self, _: Any) -> None:
def teardown_method(self, _: Any) -> None:
import transaction
-
from c2cgeoportal_commons.models import DBSession
transaction.abort()
@@ -105,13 +107,16 @@ def _create_layer(
It creates a layer with two features, and associates a restriction area to it.
"""
import transaction
+ from c2cgeoportal_commons.models import DBSession
+ from c2cgeoportal_commons.models.main import (
+ LayerWMS,
+ OGCServer,
+ RestrictionArea,
+ )
from geoalchemy2 import Geometry, WKTElement
from sqlalchemy import CheckConstraint, Column, ForeignKey, Table, types
from sqlalchemy.ext.declarative import declarative_base
- from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import LayerWMS, OGCServer, RestrictionArea
-
if self._tables is None:
self._tables = []
@@ -228,9 +233,8 @@ def _get_request(layerid, username=None) -> None:
return request
def test_read_public(self) -> None:
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
layer_id = self._create_layer(public=True)
request = self._get_request(layer_id)
@@ -240,9 +244,8 @@ def test_read_public(self) -> None:
self.assertEqual([f.properties["child"] for f in collection.features], ["c1é", "c2é"])
def test_read_many_no_auth(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id)
@@ -251,9 +254,8 @@ def test_read_many_no_auth(self) -> None:
self.assertRaises(HTTPForbidden, layers.read_many)
def test_read_many(self) -> None:
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
layer_id = self._create_layer()
request = self._get_request(layer_id, username="__test_user")
@@ -264,9 +266,8 @@ def test_read_many(self) -> None:
assert [f.properties["child"] for f in collection.features] == ["c1é"]
def test_read_many_layer_not_found(self) -> None:
- from pyramid.httpexceptions import HTTPNotFound
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPNotFound
self._create_layer()
request = self._get_request(10000, username="__test_user")
@@ -275,9 +276,8 @@ def test_read_many_layer_not_found(self) -> None:
self.assertRaises(HTTPNotFound, layers.read_many)
def test_read_many_multi(self) -> None:
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
layer_id1 = self._create_layer()
layer_id2 = self._create_layer()
@@ -294,9 +294,8 @@ def test_read_many_multi(self) -> None:
)
def test_read_one_public(self) -> None:
- from geojson.feature import Feature
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import Feature
layer_id = self._create_layer(public=True)
request = self._get_request(layer_id)
@@ -310,9 +309,8 @@ def test_read_one_public(self) -> None:
assert feature.properties["child"] == "c1é"
def test_read_one_public_notfound(self) -> None:
- from pyramid.httpexceptions import HTTPNotFound
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPNotFound
layer_id = self._create_layer(public=True)
request = self._get_request(layer_id)
@@ -323,9 +321,8 @@ def test_read_one_public_notfound(self) -> None:
self.assertTrue(isinstance(feature, HTTPNotFound))
def test_read_one_no_auth(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id)
@@ -335,9 +332,8 @@ def test_read_one_no_auth(self) -> None:
self.assertRaises(HTTPForbidden, layers.read_one)
def test_read_one_no_perm(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id, username="__test_user")
@@ -347,9 +343,8 @@ def test_read_one_no_perm(self) -> None:
self.assertRaises(HTTPForbidden, layers.read_one)
def test_read_one(self) -> None:
- from geojson.feature import Feature
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import Feature
layer_id = self._create_layer()
request = self._get_request(layer_id, username="__test_user")
@@ -373,9 +368,8 @@ def test_count(self) -> None:
assert response == 2
def test_create_no_auth(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id)
@@ -385,9 +379,8 @@ def test_create_no_auth(self) -> None:
self.assertRaises(HTTPForbidden, layers.create)
def test_create_no_perm(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id, username="__test_user")
@@ -397,9 +390,8 @@ def test_create_no_perm(self) -> None:
self.assertRaises(HTTPForbidden, layers.create)
def test_create(self) -> None:
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
layer_id = self._create_layer()
request = self._get_request(layer_id, username="__test_user")
@@ -427,12 +419,11 @@ def test_create_with_constraint_fail_integrity(self) -> None:
def test_create_log(self) -> None:
from datetime import datetime
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Metadata
from c2cgeoportal_commons.models.static import User
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
self.assertEqual(DBSession.query(User.username).all(), [("__test_user",)])
@@ -472,10 +463,9 @@ def test_create_validation_fails(self) -> None:
assert response["message"] == "Too few points in geometry component[5 45]"
def test_create_no_validation(self) -> None:
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_commons.models.main import Metadata
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
metadatas = [Metadata("geometryValidation", "False")]
layer_id = self._create_layer(metadatas=metadatas, geom_type=False)
@@ -489,9 +479,8 @@ def test_create_no_validation(self) -> None:
assert len(collection.features) == 2
def test_update_no_auth(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id)
@@ -502,9 +491,8 @@ def test_update_no_auth(self) -> None:
self.assertRaises(HTTPForbidden, layers.update)
def test_update_no_perm_dst_geom(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id, username="__test_user")
@@ -515,9 +503,8 @@ def test_update_no_perm_dst_geom(self) -> None:
self.assertRaises(HTTPForbidden, layers.update)
def test_update_no_perm_src_geom(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id, username="__test_user")
@@ -626,9 +613,8 @@ def test_update_no_validation(self) -> None:
assert feature.child == "c2é"
def test_delete_no_auth(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id)
@@ -638,9 +624,8 @@ def test_delete_no_auth(self) -> None:
self.assertRaises(HTTPForbidden, layers.delete)
def test_delete_no_perm(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id, username="__test_user")
@@ -661,9 +646,8 @@ def test_delete(self) -> None:
assert response.status_int == 204
def test_metadata_no_auth(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer()
request = self._get_request(layer_id)
@@ -742,9 +726,8 @@ def test_metadata_editing_enumeration_config(self) -> None:
# # # With None area # # #
def test_read_public_none_area(self) -> None:
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
layer_id = self._create_layer(public=True, none_area=True)
request = self._get_request(layer_id)
@@ -755,9 +738,8 @@ def test_read_public_none_area(self) -> None:
self.assertEqual([f.properties["child"] for f in collection.features], ["c1é", "c2é"])
def test_read_many_no_auth_none_area(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer(none_area=True)
request = self._get_request(layer_id)
@@ -766,9 +748,8 @@ def test_read_many_no_auth_none_area(self) -> None:
self.assertRaises(HTTPForbidden, layers.read_many)
def test_read_many_none_area(self) -> None:
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
layer_id = self._create_layer(none_area=True)
request = self._get_request(layer_id, username="__test_user")
@@ -781,9 +762,8 @@ def test_read_many_none_area(self) -> None:
assert collection.features[1].properties["child"] == "c2é"
def test_read_one_public_none_area(self) -> None:
- from geojson.feature import Feature
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import Feature
layer_id = self._create_layer(public=True, none_area=True)
request = self._get_request(layer_id)
@@ -797,9 +777,8 @@ def test_read_one_public_none_area(self) -> None:
assert feature.properties["child"] == "c1é"
def test_read_one_no_auth_none_area(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer(none_area=True)
request = self._get_request(layer_id)
@@ -809,9 +788,8 @@ def test_read_one_no_auth_none_area(self) -> None:
self.assertRaises(HTTPForbidden, layers.read_one)
def test_read_one_none_area(self) -> None:
- from geojson.feature import Feature
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import Feature
layer_id = self._create_layer(none_area=True)
request = self._get_request(layer_id, username="__test_user")
@@ -835,9 +813,8 @@ def test_count_none_area(self) -> None:
assert response == 2
def test_create_no_auth_none_area(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer(none_area=True)
request = self._get_request(layer_id)
@@ -847,9 +824,8 @@ def test_create_no_auth_none_area(self) -> None:
self.assertRaises(HTTPForbidden, layers.create)
def test_create_none_area(self) -> None:
- from geojson.feature import FeatureCollection
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from geojson.feature import FeatureCollection
layer_id = self._create_layer(none_area=True)
request = self._get_request(layer_id, username="__test_user")
@@ -861,9 +837,8 @@ def test_create_none_area(self) -> None:
assert len(collection.features) == 2
def test_update_no_auth_none_area(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer(none_area=True)
request = self._get_request(layer_id)
@@ -888,9 +863,8 @@ def test_update_none_area(self) -> None:
assert feature.child == "c2é"
def test_delete_no_auth_none_area(self) -> None:
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.layers import Layers
+ from pyramid.httpexceptions import HTTPForbidden
layer_id = self._create_layer(none_area=True)
request = self._get_request(layer_id)
diff --git a/geoportal/tests/functional/test_lingva_extractor_config.py b/geoportal/tests/functional/test_lingva_extractor_config.py
index b8abe805fe5..9d35bc64d62 100644
--- a/geoportal/tests/functional/test_lingva_extractor_config.py
+++ b/geoportal/tests/functional/test_lingva_extractor_config.py
@@ -32,10 +32,10 @@
import pytest
import yaml
from c2c.template.config import config as configuration
-from tests.functional import setup_common as setup_module
-
from c2cgeoportal_geoportal.lib.lingva_extractor import GeomapfishConfigExtractor
+from tests.functional import setup_common as setup_module
+
GMF_CONFIG = """
vars:
interfaces_config:
@@ -101,9 +101,8 @@ def transact(dbsession):
@pytest.fixture(scope="function")
def test_data(dbsession, transact):
- from sqlalchemy import text
-
from c2cgeoportal_commons.models import main
+ from sqlalchemy import text
dbsession.execute(
text(
diff --git a/geoportal/tests/functional/test_lingva_extractor_themes.py b/geoportal/tests/functional/test_lingva_extractor_themes.py
index fb13535bb12..52a2f5840ed 100644
--- a/geoportal/tests/functional/test_lingva_extractor_themes.py
+++ b/geoportal/tests/functional/test_lingva_extractor_themes.py
@@ -29,8 +29,6 @@
from unittest.mock import Mock
-import pytest
-
from c2cgeoportal_geoportal.lib.lingva_extractor import GeomapfishThemeExtractor
diff --git a/geoportal/tests/functional/test_login.py b/geoportal/tests/functional/test_login.py
index 597cfbd7aec..71eb3676d88 100644
--- a/geoportal/tests/functional/test_login.py
+++ b/geoportal/tests/functional/test_login.py
@@ -36,10 +36,14 @@
import transaction
from geoalchemy2 import WKTElement
from pyramid import testing
-from tests.functional import cleanup_db, create_dummy_request, fill_tech_user_functionality, mapserv_url
-from tests.functional import setup_common as setup_module # noqa, pylint: disable=unused-import
-from tests.functional import setup_db
-from tests.functional import teardown_common as teardown_module # noqa, pylint: disable=unused-import
+
+from tests.functional import (
+ cleanup_db,
+ create_dummy_request,
+ fill_tech_user_functionality,
+ mapserv_url,
+ setup_db,
+)
_LOG = logging.getLogger(__name__)
@@ -102,11 +106,10 @@ def _create_request_obj(username=None, params=None, **kwargs):
#
def test_login_success(self):
- from pyramid.httpexceptions import HTTPUnauthorized
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.static import User
from c2cgeoportal_geoportal.views.login import Login
+ from pyramid.httpexceptions import HTTPUnauthorized
user = DBSession.query(User).filter_by(username="__test_user1").one()
user.is_password_changed = True
@@ -136,9 +139,8 @@ def test_login_success(self):
self.assertRaises(HTTPUnauthorized, login.login)
def test_logout_no_auth(self):
- from pyramid.httpexceptions import HTTPUnauthorized
-
from c2cgeoportal_geoportal.views.login import Login
+ from pyramid.httpexceptions import HTTPUnauthorized
request = self._create_request_obj(path="/", params={"came_from": "/came_from"})
login = Login(request)
@@ -209,18 +211,16 @@ def test_reset_password(self):
self.assertNotEqual(len(user.password), 0)
def test_change_password_no_params(self):
- from pyramid.httpexceptions import HTTPBadRequest
-
from c2cgeoportal_geoportal.views.login import Login
+ from pyramid.httpexceptions import HTTPBadRequest
request = self._create_request_obj(username="__test_user1", params={"lang": "en"}, POST={})
login = Login(request)
self.assertRaises(HTTPBadRequest, login.change_password)
def test_change_password_wrong_old(self):
- from pyramid.httpexceptions import HTTPUnauthorized
-
from c2cgeoportal_geoportal.views.login import Login
+ from pyramid.httpexceptions import HTTPUnauthorized
request = self._create_request_obj(
username="__test_user1",
@@ -232,9 +232,8 @@ def test_change_password_wrong_old(self):
login.change_password()
def test_change_password_different(self):
- from pyramid.httpexceptions import HTTPBadRequest
-
from c2cgeoportal_geoportal.views.login import Login
+ from pyramid.httpexceptions import HTTPBadRequest
request = self._create_request_obj(
username="__test_user1",
@@ -361,10 +360,10 @@ class F:
assert request.response.headers["Vary"] == "Origin, Access-Control-Request-Headers, Cookie"
def test_intranet(self):
- from tests import DummyRequest
-
from c2cgeoportal_geoportal.views.login import Login
+ from tests import DummyRequest
+
request = DummyRequest()
request.registry.settings = {"intranet": {"networks": ["192.168.1.0/255.255.255.0"]}}
request.user = None
diff --git a/geoportal/tests/functional/test_login_2fa.py b/geoportal/tests/functional/test_login_2fa.py
index 164abfbbb55..c69db084ff8 100644
--- a/geoportal/tests/functional/test_login_2fa.py
+++ b/geoportal/tests/functional/test_login_2fa.py
@@ -37,10 +37,8 @@
import pytest
import transaction
from pyramid import testing
-from tests.functional import cleanup_db, create_dummy_request
-from tests.functional import setup_common as setup_module # noqa, pylint: disable=unused-import
-from tests.functional import setup_db
-from tests.functional import teardown_common as teardown_module # noqa, pylint: disable=unused-import
+
+from tests.functional import cleanup_db, create_dummy_request, setup_db
_LOG = logging.getLogger(__name__)
diff --git a/geoportal/tests/functional/test_mapserverproxy.py b/geoportal/tests/functional/test_mapserverproxy.py
index 4b3e536f5a8..b97da2e596b 100644
--- a/geoportal/tests/functional/test_mapserverproxy.py
+++ b/geoportal/tests/functional/test_mapserverproxy.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -62,15 +62,16 @@
import transaction
from geoalchemy2 import WKTElement
+
from tests.functional import (
cleanup_db,
create_default_ogcserver,
create_dummy_request,
fill_tech_user_functionality,
mapserv_url,
+ setup_db,
)
from tests.functional import setup_common as setup_module # noqa
-from tests.functional import setup_db
from tests.functional import teardown_common as teardown_module # noqa
from tests.functional.geodata_model import PointTest
@@ -1001,9 +1002,8 @@ def test_geoserver(self):
assert "testpoint_protected" in response.body.decode("utf-8")
def test_authentication_required(self):
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.mapserverproxy import MapservProxy
+ from pyramid.httpexceptions import HTTPForbidden
request = self._create_getcap_request()
request.params.update(
diff --git a/geoportal/tests/functional/test_mapserverproxy_capabilities.py b/geoportal/tests/functional/test_mapserverproxy_capabilities.py
index dc29fc973a9..90e2dc45d78 100644
--- a/geoportal/tests/functional/test_mapserverproxy_capabilities.py
+++ b/geoportal/tests/functional/test_mapserverproxy_capabilities.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,15 @@
from unittest import TestCase
import transaction
-from tests.functional import cleanup_db, create_default_ogcserver, create_dummy_request, mapserv_url
+
+from tests.functional import (
+ cleanup_db,
+ create_default_ogcserver,
+ create_dummy_request,
+ mapserv_url,
+ setup_db,
+)
from tests.functional import setup_common as setup_module # noqa
-from tests.functional import setup_db
from tests.functional import teardown_common as teardown_module # noqa
diff --git a/geoportal/tests/functional/test_mapserverproxy_group.py b/geoportal/tests/functional/test_mapserverproxy_group.py
index 80cfbe374f1..7410498f714 100644
--- a/geoportal/tests/functional/test_mapserverproxy_group.py
+++ b/geoportal/tests/functional/test_mapserverproxy_group.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
import transaction
from geoalchemy2 import WKTElement
+
from tests.functional import create_default_ogcserver, create_dummy_request
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -40,7 +41,12 @@
class TestMapserverproxyViewGroup(TestCase):
def setup_method(self, _):
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerWMS, RestrictionArea, Role
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerWMS,
+ RestrictionArea,
+ Role,
+ )
from c2cgeoportal_commons.models.static import User
ogc_server_internal = create_default_ogcserver()
@@ -72,7 +78,13 @@ def setup_method(self, _):
def teardown_method(self, _):
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerWMS, OGCServer, RestrictionArea, Role
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerWMS,
+ OGCServer,
+ RestrictionArea,
+ Role,
+ )
from c2cgeoportal_commons.models.static import User
DBSession.delete(DBSession.query(User).filter(User.username == "__test_user1").one())
diff --git a/geoportal/tests/functional/test_mobile_desktop.py b/geoportal/tests/functional/test_mobile_desktop.py
index 2d479ff1cea..22316e546a0 100644
--- a/geoportal/tests/functional/test_mobile_desktop.py
+++ b/geoportal/tests/functional/test_mobile_desktop.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request, mapserv_url
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -44,7 +45,12 @@ def setup_method(self, _):
self.maxDiff = None
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerGroup,
+ LayerWMS,
+ Theme,
+ )
create_default_ogcserver()
main = Interface(name="main")
@@ -102,7 +108,13 @@ def teardown_method(self, _):
testing.tearDown()
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, OGCServer, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerGroup,
+ LayerWMS,
+ OGCServer,
+ Theme,
+ )
for t in DBSession.query(Theme).all():
DBSession.delete(t)
diff --git a/geoportal/tests/functional/test_oauth2.py b/geoportal/tests/functional/test_oauth2.py
index 145de440977..5d925c63d66 100644
--- a/geoportal/tests/functional/test_oauth2.py
+++ b/geoportal/tests/functional/test_oauth2.py
@@ -37,9 +37,8 @@
import pyramid.testing
import pytest
import transaction
+
from tests.functional import cleanup_db, create_dummy_request, init_registry
-from tests.functional import setup_common as setup_module # pylint: disable=unused-import
-from tests.functional import teardown_common as teardown_module # pylint: disable=unused-import
_LOG = logging.getLogger(__name__)
@@ -588,7 +587,7 @@ def test_pkce_oauth2_protocol_test_login_get_token_refresh_token_is_login(self)
request.method = "POST"
request.body = ""
with pytest.raises(pyramid.httpexceptions.HTTPFound) as exc_info:
- assert False, Login(request).login().body
+ raise AssertionError(Login(request).login().body)
url = exc_info.value.headers["Location"]
url_split = urllib.parse.urlsplit(url)
query = dict(urllib.parse.parse_qsl(url_split.fragment))
@@ -684,7 +683,7 @@ def test_pkce_state_oauth2_protocol_test_login_get_token_refresh_token_is_login(
request.method = "POST"
request.body = ""
with pytest.raises(pyramid.httpexceptions.HTTPFound) as exc_info:
- assert False, Login(request).login().body
+ raise AssertionError(Login(request).login().body)
url = exc_info.value.headers["Location"]
url_split = urllib.parse.urlsplit(url)
query = dict(urllib.parse.parse_qsl(url_split.fragment))
@@ -766,7 +765,7 @@ def test_oauth2_protocol_test_login_no_state(self) -> None:
request.host = "127.0.0.1:7070"
request.method = "POST"
request.body = ""
- with pytest.raises(pyramid.httpexceptions.HTTPBadRequest) as exc_info:
+ with pytest.raises(pyramid.httpexceptions.HTTPBadRequest):
Login(request).login()
def test_oauth2_protocol_test_login_no_pkce(self) -> None:
@@ -814,7 +813,7 @@ def test_pkce_oauth2_protocol_test_login_no_state(self) -> None:
request.host = "127.0.0.1:7070"
request.method = "POST"
request.body = ""
- with pytest.raises(pyramid.httpexceptions.HTTPBadRequest) as exc_info:
+ with pytest.raises(pyramid.httpexceptions.HTTPBadRequest):
Login(request).login()
def test_pkce_oauth2_protocol_test_login_wrong_code(self) -> None:
@@ -846,7 +845,7 @@ def test_pkce_oauth2_protocol_test_login_wrong_code(self) -> None:
request.method = "POST"
request.body = ""
with pytest.raises(pyramid.httpexceptions.HTTPFound) as exc_info:
- assert False, Login(request).login().body
+ raise AssertionError(Login(request).login().body)
url = exc_info.value.headers["Location"]
url_split = urllib.parse.urlsplit(url)
query = dict(urllib.parse.parse_qsl(url_split.fragment))
diff --git a/geoportal/tests/functional/test_ogcproxy.py b/geoportal/tests/functional/test_ogcproxy.py
index d026f48e662..7e5c92c022e 100644
--- a/geoportal/tests/functional/test_ogcproxy.py
+++ b/geoportal/tests/functional/test_ogcproxy.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2022-2023, Camptocamp SA
+# Copyright (c) 2022-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,9 +31,9 @@
from unittest import TestCase
import transaction
-from tests.functional import cleanup_db, create_dummy_request
+
+from tests.functional import cleanup_db, create_dummy_request, setup_db
from tests.functional import setup_common as setup_module # noqa
-from tests.functional import setup_db
from tests.functional import teardown_common as teardown_module # noqa
diff --git a/geoportal/tests/functional/test_oidc.py b/geoportal/tests/functional/test_oidc.py
index 21e7e8d6888..6a6c92a5c65 100644
--- a/geoportal/tests/functional/test_oidc.py
+++ b/geoportal/tests/functional/test_oidc.py
@@ -7,14 +7,11 @@
import jwt
import responses
+from c2cgeoportal_geoportal.lib import oidc
from cryptography.hazmat.primitives.asymmetric import rsa
from pyramid import testing
-from tests.functional import cleanup_db, create_dummy_request
-from tests.functional import setup_common as setup_module # noqa, pylint: disable=unused-import
-from tests.functional import setup_db
-from tests.functional import teardown_common as teardown_module # noqa, pylint: disable=unused-import
-from c2cgeoportal_geoportal.lib import oidc
+from tests.functional import cleanup_db, create_dummy_request, setup_db
_OIDC_CONFIGURATION = {
"issuer": "https://sso.example.com",
diff --git a/geoportal/tests/functional/test_request_property.py b/geoportal/tests/functional/test_request_property.py
index 8b0f74bfaff..3f17926336a 100644
--- a/geoportal/tests/functional/test_request_property.py
+++ b/geoportal/tests/functional/test_request_property.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2023, Camptocamp SA
+# Copyright (c) 2011-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -39,7 +39,6 @@
class TestRequestProperty(TestCase):
def setup_method(self, _):
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Role
from c2cgeoportal_commons.models.static import User
@@ -52,7 +51,6 @@ def setup_method(self, _):
def teardown_method(self, _):
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import Role
from c2cgeoportal_commons.models.static import User
@@ -65,7 +63,7 @@ def teardown_method(self, _):
def test_request_no_auth(self):
request = create_dummy_request()
- assert request.user == None
+ assert request.user is None
def test_request_auth(self):
request = create_dummy_request(authentication=False, user="__test_user")
@@ -91,7 +89,7 @@ def test_request_wrong_auth(self):
}
)
- assert request.user == None
+ assert request.user is None
def test_request_auth_overwritten_property(self):
def setter(request):
diff --git a/geoportal/tests/functional/test_shortener.py b/geoportal/tests/functional/test_shortener.py
index 23b1b761899..3f27f21bfc5 100644
--- a/geoportal/tests/functional/test_shortener.py
+++ b/geoportal/tests/functional/test_shortener.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
from unittest import TestCase
from pyramid import testing
+
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -40,7 +41,6 @@ def teardown_method(self, _):
testing.tearDown()
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.static import Shorturl
@@ -48,10 +48,10 @@ def teardown_method(self, _):
transaction.commit()
def test_shortener(self):
+ from c2cgeoportal_geoportal.views.shortener import Shortener
from pyramid.httpexceptions import HTTPBadRequest, HTTPNotFound
- from tests import DummyRequest
- from c2cgeoportal_geoportal.views.shortener import Shortener
+ from tests import DummyRequest
def route_url(name, *args, **kwargs):
del name # Unused
@@ -78,10 +78,10 @@ def route_url(name, *args, **kwargs):
self.assertRaises(HTTPBadRequest, shortener.create)
def test_shortener_create_1(self):
+ from c2cgeoportal_geoportal.views.shortener import Shortener
from pyramid.httpexceptions import HTTPFound
- from tests import DummyRequest
- from c2cgeoportal_geoportal.views.shortener import Shortener
+ from tests import DummyRequest
def route_url(name, *elements, **kw):
return "https://example.com/short/" + kw["ref"]
@@ -106,10 +106,10 @@ def route_url(name, *elements, **kw):
assert result.location == "https://example.com/hi"
def test_shortener_create_2(self):
+ from c2cgeoportal_geoportal.views.shortener import Shortener
from pyramid.httpexceptions import HTTPFound
- from tests import DummyRequest
- from c2cgeoportal_geoportal.views.shortener import Shortener
+ from tests import DummyRequest
def route_url(name, *elements, **kw):
return "https://example.com/short/" + kw["ref"]
@@ -136,10 +136,10 @@ def route_url(name, *elements, **kw):
assert result.location == "https://example.com/hi"
def test_shortener_noreplace_1(self):
- from tests import DummyRequest
-
from c2cgeoportal_geoportal.views.shortener import Shortener
+ from tests import DummyRequest
+
def route_url(name, *elements, **kw):
return "https://example.com/short/" + kw["ref"]
@@ -156,10 +156,10 @@ def route_url(name, *elements, **kw):
assert result["short_url"] == "https://example.com/s/truite"
def test_shortener_noreplace_2(self):
- from tests import DummyRequest
-
from c2cgeoportal_geoportal.views.shortener import Shortener
+ from tests import DummyRequest
+
def route_url(name, *elements, **kw):
return "https://example.com/short/" + kw["ref"]
@@ -176,10 +176,10 @@ def route_url(name, *elements, **kw):
assert result["short_url"] == "https://example.com/s/truite"
def test_shortener_baseurl(self):
- from tests import DummyRequest
-
from c2cgeoportal_geoportal.views.shortener import Shortener
+ from tests import DummyRequest
+
def route_url(name, *elements, **kw):
return "https://example.com/short/" + kw["ref"]
@@ -197,10 +197,10 @@ def route_url(name, *elements, **kw):
assert result["short_url"][:index] == "http://my_host/my_short"
def test_shortener_dev(self):
- from tests import DummyRequest
-
from c2cgeoportal_geoportal.views.shortener import Shortener
+ from tests import DummyRequest
+
def route_url(name, *elements, **kw):
return "https://localhost:8484/s/" + kw["ref"]
diff --git a/geoportal/tests/functional/test_theme2fts.py b/geoportal/tests/functional/test_theme2fts.py
index 0729bb63c01..af0ff2d6288 100644
--- a/geoportal/tests/functional/test_theme2fts.py
+++ b/geoportal/tests/functional/test_theme2fts.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2020-2023, Camptocamp SA
+# Copyright (c) 2020-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@
import pytest
from c2c.template.config import config as configuration
-from sqlalchemy import func
+
from tests.functional import setup_common as setup_module
@@ -69,9 +69,7 @@ def transact(dbsession):
def add_parent(dbsession, item, group):
- """
- Utility function to add a TreeItem in a TreeGroup.
- """
+ """Utility function to add a TreeItem in a TreeGroup."""
from c2cgeoportal_commons.models import main
dbsession.add(main.LayergroupTreeitem(group=group, item=item, ordering=len(group.children_relation)))
diff --git a/geoportal/tests/functional/test_themes.py b/geoportal/tests/functional/test_themes.py
index eb7244589d6..d463d50f21d 100644
--- a/geoportal/tests/functional/test_themes.py
+++ b/geoportal/tests/functional/test_themes.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -123,7 +124,13 @@ def teardown_method(self, _):
testing.tearDown()
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Dimension, Interface, Metadata, OGCServer, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Dimension,
+ Interface,
+ Metadata,
+ OGCServer,
+ TreeItem,
+ )
DBSession.query(Metadata).delete()
DBSession.query(Dimension).delete()
diff --git a/geoportal/tests/functional/test_themes_dimensions.py b/geoportal/tests/functional/test_themes_dimensions.py
index 4e77a55f867..85e7cbf8d3e 100644
--- a/geoportal/tests/functional/test_themes_dimensions.py
+++ b/geoportal/tests/functional/test_themes_dimensions.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016-2023, Camptocamp SA
+# Copyright (c) 2016-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request, mapserv_url
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -152,7 +153,12 @@ def teardown_method(self, _):
testing.tearDown()
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Dimension, Interface, OGCServer, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Dimension,
+ Interface,
+ OGCServer,
+ TreeItem,
+ )
DBSession.query(Dimension).delete()
for item in DBSession.query(TreeItem).all():
diff --git a/geoportal/tests/functional/test_themes_edit_columns.py b/geoportal/tests/functional/test_themes_edit_columns.py
index e900a11a887..13a88bc5a7b 100644
--- a/geoportal/tests/functional/test_themes_edit_columns.py
+++ b/geoportal/tests/functional/test_themes_edit_columns.py
@@ -32,9 +32,13 @@
from unittest import TestCase
from urllib.parse import urlencode
-from tests.functional import cleanup_db, create_default_ogcserver, create_dummy_request
+from tests.functional import (
+ cleanup_db,
+ create_default_ogcserver,
+ create_dummy_request,
+ setup_db,
+)
from tests.functional import setup_common as setup_module # noqa
-from tests.functional import setup_db
from tests.functional import teardown_common as teardown_module # noqa
if TYPE_CHECKING:
@@ -54,7 +58,6 @@ def setup_method(self, _: Any) -> None:
self._tables = []
import transaction
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import (
OGCSERVER_AUTH_NOAUTH,
@@ -93,7 +96,6 @@ def setup_method(self, _: Any) -> None:
def teardown_method(self, _: Any) -> None:
import transaction
-
from c2cgeoportal_commons.models import DBSession
cleanup_db()
@@ -115,13 +117,12 @@ def _create_layer(
It creates a layer with two features, and associates a restriction area to it.
"""
import transaction
+ from c2cgeoportal_commons.models import DBSession
+ from c2cgeoportal_commons.models.main import LayerWMS, RestrictionArea
from geoalchemy2 import Geometry
from sqlalchemy import Column, ForeignKey, Table, types
from sqlalchemy.ext.declarative import declarative_base
- from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import LayerWMS, RestrictionArea
-
self.__class__._table_index += 1
id = self.__class__._table_index
@@ -224,7 +225,6 @@ def _get_request(layerid, username=None, params=None) -> None:
return request
def test_themes_edit_columns(self) -> None:
- from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_geoportal.views.theme import Theme
layer_id = self._create_layer(geom_type=True)
@@ -297,7 +297,7 @@ def test_themes_edit_columns_extras(self) -> None:
theme_view = Theme(self._get_request(layer_id, username="__test_user", params={"interface": "main"}))
themes = theme_view.themes()
- assert [] == themes["errors"]
+ assert themes["errors"] == []
layers = themes["themes"][0]["children"][0]["children"]
self.assertEqual(
diff --git a/geoportal/tests/functional/test_themes_editing.py b/geoportal/tests/functional/test_themes_editing.py
index 564c7741ee0..a231d51745a 100644
--- a/geoportal/tests/functional/test_themes_editing.py
+++ b/geoportal/tests/functional/test_themes_editing.py
@@ -33,9 +33,15 @@
import transaction
from geoalchemy2 import WKTElement
from pyramid import testing
-from tests.functional import cleanup_db, create_default_ogcserver, create_dummy_request, mapserv_url
+
+from tests.functional import (
+ cleanup_db,
+ create_default_ogcserver,
+ create_dummy_request,
+ mapserv_url,
+ setup_db,
+)
from tests.functional import setup_common as setup_module # noqa
-from tests.functional import setup_db
from tests.functional import teardown_common as teardown_module # noqa
@@ -46,10 +52,6 @@ def setup_method(self, _):
self.maxDiff = None
self._tables = []
- from geoalchemy2 import Geometry
- from sqlalchemy import Column, Table, types
- from sqlalchemy.ext.declarative import declarative_base
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import (
Interface,
@@ -60,6 +62,9 @@ def setup_method(self, _):
Theme,
)
from c2cgeoportal_commons.models.static import User
+ from geoalchemy2 import Geometry
+ from sqlalchemy import Column, Table, types
+ from sqlalchemy.ext.declarative import declarative_base
setup_db()
diff --git a/geoportal/tests/functional/test_themes_entry.py b/geoportal/tests/functional/test_themes_entry.py
index 207edd01d31..f490b48aca3 100644
--- a/geoportal/tests/functional/test_themes_entry.py
+++ b/geoportal/tests/functional/test_themes_entry.py
@@ -32,14 +32,17 @@
from unittest import TestCase
import transaction
+from c2cgeoportal_geoportal.lib.caching import invalidate_region
from geoalchemy2 import WKTElement
from pyramid import testing
-from tests.functional import cleanup_db, create_default_ogcserver, create_dummy_request, mapserv_url
-from tests.functional import setup_common as setup_module # noqa, pylint: disable=unused-import
-from tests.functional import setup_db
-from tests.functional import teardown_common as teardown_module # noqa, pylint: disable=unused-import
-from c2cgeoportal_geoportal.lib.caching import invalidate_region
+from tests.functional import (
+ cleanup_db,
+ create_default_ogcserver,
+ create_dummy_request,
+ mapserv_url,
+ setup_db,
+)
_LOG = logging.getLogger(__name__)
@@ -51,10 +54,6 @@ def setup_method(self, _):
self.maxDiff = None # pylint: disable=invalid-name
self._tables = []
- from geoalchemy2 import Geometry
- from sqlalchemy import Column, Table, func, types
- from sqlalchemy.ext.declarative import declarative_base
-
from c2cgeoportal_commons.models import DBSession
from c2cgeoportal_commons.models.main import (
OGCSERVER_AUTH_GEOSERVER,
@@ -70,6 +69,9 @@ def setup_method(self, _):
Theme,
)
from c2cgeoportal_commons.models.static import User
+ from geoalchemy2 import Geometry
+ from sqlalchemy import Column, Table, func, types
+ from sqlalchemy.ext.declarative import declarative_base
setup_db()
diff --git a/geoportal/tests/functional/test_themes_layermultinameerror.py b/geoportal/tests/functional/test_themes_layermultinameerror.py
index ad43f437334..1cc71260f09 100644
--- a/geoportal/tests/functional/test_themes_layermultinameerror.py
+++ b/geoportal/tests/functional/test_themes_layermultinameerror.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request, mapserv_url
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -44,7 +45,12 @@ def setup_method(self, _):
self.maxDiff = None
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerGroup,
+ LayerWMS,
+ Theme,
+ )
main = Interface(name="desktop")
diff --git a/geoportal/tests/functional/test_themes_loop.py b/geoportal/tests/functional/test_themes_loop.py
index 8657a5a8e29..045478fc2a1 100644
--- a/geoportal/tests/functional/test_themes_loop.py
+++ b/geoportal/tests/functional/test_themes_loop.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
import transaction
from pyramid import testing
+
from tests import DummyRequest
from tests.functional import create_default_ogcserver, mapserv_url
from tests.functional import setup_common as setup_module # noqa
@@ -45,7 +46,12 @@ def setup_method(self, _):
self.maxDiff = None
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerGroup,
+ LayerWMS,
+ Theme,
+ )
ogc_server = create_default_ogcserver()
main = Interface(name="desktop2")
@@ -69,7 +75,12 @@ def teardown_method(self, _):
testing.tearDown()
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import LayerGroup, LayerWMS, OGCServer, Theme
+ from c2cgeoportal_commons.models.main import (
+ LayerGroup,
+ LayerWMS,
+ OGCServer,
+ Theme,
+ )
for t in DBSession.query(Theme).filter(Theme.name == "__test_theme").all():
DBSession.delete(t)
diff --git a/geoportal/tests/functional/test_themes_metadata.py b/geoportal/tests/functional/test_themes_metadata.py
index e942c570c21..bd31c596a59 100644
--- a/geoportal/tests/functional/test_themes_metadata.py
+++ b/geoportal/tests/functional/test_themes_metadata.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -45,7 +46,13 @@ def setup_method(self, _):
self.maxDiff = None
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, Metadata, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerGroup,
+ LayerWMS,
+ Metadata,
+ Theme,
+ )
desktop = Interface(name="desktop")
diff --git a/geoportal/tests/functional/test_themes_mixed.py b/geoportal/tests/functional/test_themes_mixed.py
index fec589f5dae..c9127e70812 100644
--- a/geoportal/tests/functional/test_themes_mixed.py
+++ b/geoportal/tests/functional/test_themes_mixed.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2016-2023, Camptocamp SA
+# Copyright (c) 2016-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -33,6 +33,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request, mapserv_url
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -152,7 +153,13 @@ def teardown_method(self, _):
testing.tearDown()
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Dimension, Interface, Metadata, OGCServer, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Dimension,
+ Interface,
+ Metadata,
+ OGCServer,
+ TreeItem,
+ )
DBSession.query(Metadata).delete()
DBSession.query(Dimension).delete()
diff --git a/geoportal/tests/functional/test_themes_nameerror.py b/geoportal/tests/functional/test_themes_nameerror.py
index d9db1bc16ee..2249e627971 100644
--- a/geoportal/tests/functional/test_themes_nameerror.py
+++ b/geoportal/tests/functional/test_themes_nameerror.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -32,6 +32,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request, mapserv_url
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -44,7 +45,12 @@ def setup_method(self, _):
self.maxDiff = None
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerGroup,
+ LayerWMS,
+ Theme,
+ )
main = Interface(name="desktop")
@@ -69,7 +75,13 @@ def teardown_method(self, _):
testing.tearDown()
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, Layer, LayerGroup, OGCServer, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ Layer,
+ LayerGroup,
+ OGCServer,
+ Theme,
+ )
for layer in DBSession.query(Layer).all():
DBSession.delete(layer)
diff --git a/geoportal/tests/functional/test_themes_ogc_server_cache_clean.py b/geoportal/tests/functional/test_themes_ogc_server_cache_clean.py
index b93520a5cb8..b3b3d50aac3 100644
--- a/geoportal/tests/functional/test_themes_ogc_server_cache_clean.py
+++ b/geoportal/tests/functional/test_themes_ogc_server_cache_clean.py
@@ -34,13 +34,13 @@
import pytest
import responses
import transaction
+from c2cgeoportal_geoportal.lib import caching
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
-from c2cgeoportal_geoportal.lib import caching
-
CAP = """
@@ -215,7 +215,11 @@ def teardown_method(self, _):
testing.tearDown()
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Dimension, Interface, Metadata, OGCServer, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ OGCServer,
+ TreeItem,
+ )
for item in DBSession.query(TreeItem).all():
DBSession.delete(item)
diff --git a/geoportal/tests/functional/test_themes_private.py b/geoportal/tests/functional/test_themes_private.py
index 36f4a21db20..b3f54b05118 100644
--- a/geoportal/tests/functional/test_themes_private.py
+++ b/geoportal/tests/functional/test_themes_private.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -120,7 +121,13 @@ def tearDown(self): # noqa
@staticmethod
def clean():
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, OGCServer, RestrictionArea, Role, TreeItem
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ OGCServer,
+ RestrictionArea,
+ Role,
+ TreeItem,
+ )
from c2cgeoportal_commons.models.static import User
for obj in DBSession.query(RestrictionArea).all():
diff --git a/geoportal/tests/functional/test_themes_scale.py b/geoportal/tests/functional/test_themes_scale.py
index 934c4a77d26..77d9d71627d 100644
--- a/geoportal/tests/functional/test_themes_scale.py
+++ b/geoportal/tests/functional/test_themes_scale.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
import transaction
from pyramid import testing
+
from tests.functional import create_default_ogcserver, create_dummy_request, mapserv_url
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -43,7 +44,13 @@ def setup_method(self, _):
self.maxDiff = None
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, Metadata, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerGroup,
+ LayerWMS,
+ Metadata,
+ Theme,
+ )
main = Interface(name="desktop")
@@ -96,7 +103,13 @@ def teardown_method(self, _):
testing.tearDown()
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, Layer, LayerGroup, OGCServer, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ Layer,
+ LayerGroup,
+ OGCServer,
+ Theme,
+ )
for layer in DBSession.query(Layer).all():
DBSession.delete(layer)
diff --git a/geoportal/tests/functional/test_themes_time.py b/geoportal/tests/functional/test_themes_time.py
index e62cb872965..fdbd2b33678 100644
--- a/geoportal/tests/functional/test_themes_time.py
+++ b/geoportal/tests/functional/test_themes_time.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -38,6 +38,7 @@
from pyramid import testing
from sqlalchemy import Column
from sqlalchemy.types import DateTime, Integer, Unicode
+
from tests.functional import create_default_ogcserver, create_dummy_request, mapserv_url
from tests.functional import setup_common as setup_module # noqa
from tests.functional import teardown_common as teardown_module # noqa
@@ -61,7 +62,13 @@ def setup_method(self, _):
self.maxDiff = None
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerGroup, LayerWMS, LayerWMTS, Theme
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerGroup,
+ LayerWMS,
+ LayerWMTS,
+ Theme,
+ )
DBSession.query(PointTest).delete()
diff --git a/geoportal/tests/functional/test_tinyowsproxy.py b/geoportal/tests/functional/test_tinyowsproxy.py
index c0bd6f61571..62eeee0741a 100644
--- a/geoportal/tests/functional/test_tinyowsproxy.py
+++ b/geoportal/tests/functional/test_tinyowsproxy.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2015-2023, Camptocamp SA
+# Copyright (c) 2015-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -33,11 +33,15 @@
import responses
import transaction
from geoalchemy2 import WKTElement
-from pyramid.response import Response
+
from tests import load_file
-from tests.functional import cleanup_db, create_default_ogcserver, create_dummy_request
+from tests.functional import (
+ cleanup_db,
+ create_default_ogcserver,
+ create_dummy_request,
+ setup_db,
+)
from tests.functional import setup_common as setup_module # noqa
-from tests.functional import setup_db
from tests.functional import teardown_common as teardown_module # noqa
@@ -74,7 +78,12 @@ def setup_method(self, _):
self.maxDiff = None
from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_commons.models.main import Interface, LayerWMS, RestrictionArea, Role
+ from c2cgeoportal_commons.models.main import (
+ Interface,
+ LayerWMS,
+ RestrictionArea,
+ Role,
+ )
from c2cgeoportal_commons.models.static import User
setup_db()
@@ -124,9 +133,8 @@ def teardown_method(self, _):
cleanup_db()
def test_proxy_not_auth(self):
- from pyramid.httpexceptions import HTTPUnauthorized
-
from c2cgeoportal_geoportal.views.tinyowsproxy import TinyOWSProxy
+ from pyramid.httpexceptions import HTTPUnauthorized
request = _create_dummy_request()
@@ -150,7 +158,7 @@ def test_proxy_get_capabilities_user1(self):
load_file(self.capabilities_response_filtered_file1).strip(),
response.body.decode().replace(" \n", "").strip(),
)
- assert "200 OK" == response.status
+ assert response.status == "200 OK"
@responses.activate
def test_proxy_get_capabilities_user2(self):
@@ -169,7 +177,7 @@ def test_proxy_get_capabilities_user2(self):
load_file(self.capabilities_response_filtered_file2).strip(),
response.body.decode().replace(" \n", "").strip(),
)
- assert "200 OK" == response.status
+ assert response.status == "200 OK"
@responses.activate
def test_proxy_get_capabilities_get(self):
@@ -189,7 +197,7 @@ def test_proxy_get_capabilities_get(self):
load_file(self.capabilities_response_filtered_file1).strip(),
response.body.decode().replace(" \n", "").strip(),
)
- assert "200 OK" == response.status
+ assert response.status == "200 OK"
@responses.activate
def test_proxy_get_capabilities_post(self):
@@ -211,12 +219,11 @@ def test_proxy_get_capabilities_post(self):
response.body.decode().replace(" \n", "").strip(),
)
- assert "200 OK" == response.status
+ assert response.status == "200 OK"
def test_proxy_get_capabilities_post_invalid_body(self):
- from pyramid.httpexceptions import HTTPBadRequest
-
from c2cgeoportal_geoportal.views.tinyowsproxy import TinyOWSProxy
+ from pyramid.httpexceptions import HTTPBadRequest
request = _create_dummy_request(username="__test_user1")
request.method = "POST"
@@ -248,12 +255,11 @@ def test_proxy_describe_feature_type_get(self):
response = TinyOWSProxy(request).proxy()
- assert "200 OK" == response.status
+ assert response.status == "200 OK"
def test_proxy_describe_feature_type_invalid_layer(self):
- from pyramid.httpexceptions import HTTPForbidden
-
from c2cgeoportal_geoportal.views.tinyowsproxy import TinyOWSProxy
+ from pyramid.httpexceptions import HTTPForbidden
request = _create_dummy_request(username="__test_user1")
request.params.update(
@@ -278,12 +284,11 @@ def test_proxy_describe_feature_type_post(self):
response = TinyOWSProxy(request).proxy()
- assert "200 OK" == response.status
+ assert response.status == "200 OK"
def test_proxy_describe_feature_type_post_multiple_types(self):
- from pyramid.httpexceptions import HTTPBadRequest
-
from c2cgeoportal_geoportal.views.tinyowsproxy import TinyOWSProxy
+ from pyramid.httpexceptions import HTTPBadRequest
request = _create_dummy_request(username="__test_user1")
request.method = "POST"
@@ -322,7 +327,7 @@ def test_parse_body_getcapabilities(self):
(operation, typename) = TinyOWSProxy(request)._parse_body(request.body)
- assert "getcapabilities" == operation
+ assert operation == "getcapabilities"
assert set() == typename
def test_parse_body_describefeaturetype(self):
@@ -333,7 +338,7 @@ def test_parse_body_describefeaturetype(self):
(operation, typename) = TinyOWSProxy(request)._parse_body(request.body)
- assert "describefeaturetype" == operation
+ assert operation == "describefeaturetype"
assert {"layer_1"} == typename
def test_parse_body_getfeature(self):
@@ -344,7 +349,7 @@ def test_parse_body_getfeature(self):
(operation, typename) = TinyOWSProxy(request)._parse_body(request.body)
- assert "getfeature" == operation
+ assert operation == "getfeature"
assert {"parks"} == typename
def test_parse_body_lockfeature(self):
@@ -355,7 +360,7 @@ def test_parse_body_lockfeature(self):
(operation, typename) = TinyOWSProxy(request)._parse_body(request.body)
- assert "lockfeature" == operation
+ assert operation == "lockfeature"
assert {"parks"} == typename
def test_parse_body_transaction_update(self):
@@ -366,7 +371,7 @@ def test_parse_body_transaction_update(self):
(operation, typename) = TinyOWSProxy(request)._parse_body(request.body)
- assert "transaction" == operation
+ assert operation == "transaction"
assert {"parks"} == typename
def test_parse_body_transaction_delete(self):
@@ -377,7 +382,7 @@ def test_parse_body_transaction_delete(self):
(operation, typename) = TinyOWSProxy(request)._parse_body(request.body)
- assert "transaction" == operation
+ assert operation == "transaction"
assert {"parks"} == typename
def test_parse_body_transaction_insert(self):
@@ -388,5 +393,5 @@ def test_parse_body_transaction_insert(self):
(operation, typename) = TinyOWSProxy(request)._parse_body(request.body)
- assert "transaction" == operation
+ assert operation == "transaction"
assert {"parks"} == typename
diff --git a/geoportal/tests/functional/test_vector_tiles.py b/geoportal/tests/functional/test_vector_tiles.py
index 79585aa3591..43fa122aed7 100644
--- a/geoportal/tests/functional/test_vector_tiles.py
+++ b/geoportal/tests/functional/test_vector_tiles.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2021-2023, Camptocamp SA
+# Copyright (c) 2021-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
import pytest
from geoalchemy2 import WKTElement
from pyramid.httpexceptions import HTTPNotFound
+
from tests.functional.geodata_model import PointTest
@@ -110,6 +111,6 @@ def test_vector_tiles_layer_not_found(self, dummy_request, test_data):
request.matchdict["x"] = 0
request.matchdict["y"] = 0
- with pytest.raises(HTTPNotFound) as excinfo:
+ with pytest.raises(HTTPNotFound):
VectorTilesViews(request).vector_tiles()
assert "Not found any vector tile layer named not_existing_layer_name"
diff --git a/geoportal/tests/functional/test_xsd.py b/geoportal/tests/functional/test_xsd.py
index 18d65c9cb37..cb8bab0cb15 100644
--- a/geoportal/tests/functional/test_xsd.py
+++ b/geoportal/tests/functional/test_xsd.py
@@ -42,13 +42,12 @@ def setup_method(self, _):
setup_module()
import transaction
+ from c2cgeoportal_commons.models import DBSession
+ from c2cgeoportal_geoportal.lib.dbreflection import _AssociationProxy
from sqlalchemy import Column, ForeignKey, types
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship
- from c2cgeoportal_commons.models import DBSession
- from c2cgeoportal_geoportal.lib.dbreflection import _AssociationProxy
-
# Always see the diff
# https://docs.python.org/2/library/unittest.html#unittest.TestCase.maxDiff
self.maxDiff = None
@@ -90,7 +89,6 @@ class Parent(Base): # type: ignore
def teardown_method(self, _):
import transaction
-
from c2cgeoportal_commons.models import DBSession
transaction.commit()
@@ -116,9 +114,8 @@ def test_add_class_properties_xsd_column_order(self, column_mock):
@patch("c2cgeoportal_geoportal.lib.xsd.XSDGenerator.add_association_proxy_xsd")
@patch("c2cgeoportal_geoportal.lib.xsd.PapyrusXSDGenerator.add_column_property_xsd")
def test_add_column_property_xsd(self, column_mock, proxy_mock):
- from sqlalchemy.orm.util import class_mapper
-
from c2cgeoportal_geoportal.lib.xsd import XSDGenerator
+ from sqlalchemy.orm.util import class_mapper
gen = XSDGenerator(include_foreign_keys=True)
@@ -136,9 +133,8 @@ def test_add_column_property_xsd(self, column_mock, proxy_mock):
def test_add_column_readonly(self):
from xml.etree.ElementTree import TreeBuilder, tostring
- from sqlalchemy.orm.util import class_mapper
-
from c2cgeoportal_geoportal.lib.xsd import XSDGenerator
+ from sqlalchemy.orm.util import class_mapper
gen = XSDGenerator(include_foreign_keys=True)
mapper = class_mapper(self.cls)
@@ -162,9 +158,8 @@ def test_add_column_readonly(self):
def test_add_association_proxy_xsd(self):
from xml.etree.ElementTree import TreeBuilder, tostring
- from sqlalchemy.orm.util import class_mapper
-
from c2cgeoportal_geoportal.lib.xsd import XSDGenerator
+ from sqlalchemy.orm.util import class_mapper
gen = XSDGenerator(include_foreign_keys=True)
diff --git a/geoportal/tests/test_cachebuster.py b/geoportal/tests/test_cachebuster.py
index ff8017e7358..fd379b22a40 100644
--- a/geoportal/tests/test_cachebuster.py
+++ b/geoportal/tests/test_cachebuster.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2011-2023, Camptocamp SA
+# Copyright (c) 2011-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,10 +31,10 @@
from unittest import TestCase
import pyramid.registry
-from tests import DummyRequest
-
from c2cgeoportal_geoportal.lib.caching import init_region
+from tests import DummyRequest
+
def handler(request):
return request.response
diff --git a/geoportal/tests/test_caching.py b/geoportal/tests/test_caching.py
index 2e5b5a5ae7b..1261cdd3b7f 100644
--- a/geoportal/tests/test_caching.py
+++ b/geoportal/tests/test_caching.py
@@ -30,11 +30,15 @@
from unittest import TestCase
-from tests import DummyRequest
-
from c2cgeoportal_geoportal.lib.cacheversion import get_cache_version
from c2cgeoportal_geoportal.lib.caching import init_region, invalidate_region
-from c2cgeoportal_geoportal.lib.common_headers import CORS_METHODS, Cache, set_common_headers
+from c2cgeoportal_geoportal.lib.common_headers import (
+ CORS_METHODS,
+ Cache,
+ set_common_headers,
+)
+
+from tests import DummyRequest
class TestSetCorsHeaders(TestCase):
@@ -55,9 +59,7 @@ def _do(method, headers, credentials=False, settings=SETTINGS):
return dict(request.response.headers)
def test_simple(self):
- """
- Tests specified in http://www.w3.org/TR/cors/#resource-requests.
- """
+ """Tests specified in http://www.w3.org/TR/cors/#resource-requests."""
# 1. If the Origin header is not present terminate this set of steps.
# The request is outside the scope of this specification.
assert self._do("POST", {}) == {
@@ -102,9 +104,7 @@ def test_simple(self):
# Not implemented
def test_preflight(self):
- """
- Tests specified in http://www.w3.org/TR/cors/#resource-preflight-requests.
- """
+ """Tests specified in http://www.w3.org/TR/cors/#resource-preflight-requests."""
# 1. If the Origin header is not present terminate this set of steps.
# The request is outside the scope of this specification.
assert self._do("OPTIONS", {"Access-Control-Request-Method": "GET"}) == {
diff --git a/geoportal/tests/test_checker.py b/geoportal/tests/test_checker.py
index adcef256608..fb1b8fed19d 100644
--- a/geoportal/tests/test_checker.py
+++ b/geoportal/tests/test_checker.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -30,10 +30,10 @@
from unittest import TestCase
-from tests import DummyRequest
-
from c2cgeoportal_geoportal.lib.checker import build_url
+from tests import DummyRequest
+
class TestExportCSVView(TestCase):
def test_build_url_docker(self):
diff --git a/geoportal/tests/test_headerstween.py b/geoportal/tests/test_headerstween.py
index d8a815da883..64fe41d3512 100644
--- a/geoportal/tests/test_headerstween.py
+++ b/geoportal/tests/test_headerstween.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2018-2023, Camptocamp SA
+# Copyright (c) 2018-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,6 +31,7 @@
from unittest import TestCase
import pyramid.registry
+
from tests import DummyRequest
diff --git a/geoportal/tests/test_init.py b/geoportal/tests/test_init.py
index 996a5ceb5fa..1c94ef14da9 100644
--- a/geoportal/tests/test_init.py
+++ b/geoportal/tests/test_init.py
@@ -31,12 +31,9 @@
from unittest import TestCase
from unittest.mock import patch
+import c2cgeoportal_geoportal
import pytest
from c2c.template.config import config
-from pyramid import testing
-from tests import DummyRequest
-
-import c2cgeoportal_geoportal
from c2cgeoportal_geoportal import (
call_hook,
create_get_user_from_request,
@@ -44,6 +41,9 @@
is_valid_referrer,
set_user_validator,
)
+from pyramid import testing
+
+from tests import DummyRequest
class TestIncludeme(TestCase):
@@ -127,9 +127,7 @@ def test_is_valid_referrer(authorized, value, expected):
class TestReferer(TestCase):
- """
- Check that accessing something with a bad HTTP referrer is equivalent to a not authenticated query.
- """
+ """Check that accessing something with a bad HTTP referrer is equivalent to a not authenticated query."""
BASE1 = "http://example.com/app"
BASE2 = "http://friend.com/app2"
diff --git a/geoportal/tests/test_locale_negociator.py b/geoportal/tests/test_locale_negociator.py
index a26b8f8b3a9..5bb76ca24ca 100644
--- a/geoportal/tests/test_locale_negociator.py
+++ b/geoportal/tests/test_locale_negociator.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -42,11 +42,10 @@ def test_lang_param(self):
assert lang == "fr"
def test_lang_is_not_available(self):
+ from c2cgeoportal_geoportal import locale_negotiator
from pyramid.request import Request
from pyramid.threadlocal import get_current_registry
- from c2cgeoportal_geoportal import locale_negotiator
-
request = Request.blank("/")
request.registry = get_current_registry()
request.registry.settings = {"default_locale_name": "de", "available_locale_names": ["de", "es"]}
@@ -56,11 +55,10 @@ def test_lang_is_not_available(self):
assert lang == "de"
def test_lang_is_available(self):
+ from c2cgeoportal_geoportal import locale_negotiator
from pyramid.request import Request
from pyramid.threadlocal import get_current_registry
- from c2cgeoportal_geoportal import locale_negotiator
-
request = Request.blank("/")
request.registry = get_current_registry()
request.registry.settings = {"default_locale_name": "de", "available_locale_names": ["de", "es"]}
diff --git a/geoportal/tests/test_mapserverproxy_route_predicate.py b/geoportal/tests/test_mapserverproxy_route_predicate.py
index 37113657647..9d0ced65f5e 100644
--- a/geoportal/tests/test_mapserverproxy_route_predicate.py
+++ b/geoportal/tests/test_mapserverproxy_route_predicate.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -30,11 +30,10 @@
from unittest import TestCase
+from c2cgeoportal_geoportal import MapserverproxyRoutePredicate
from pyramid.request import Request
from pyramid.threadlocal import get_current_registry
-from c2cgeoportal_geoportal import MapserverproxyRoutePredicate
-
class TestMapserverproxyRoutePredicate(TestCase):
predicate = MapserverproxyRoutePredicate(None, None)
diff --git a/geoportal/tests/test_raster.py b/geoportal/tests/test_raster.py
index 56b23ff3d86..d81ea9b1619 100644
--- a/geoportal/tests/test_raster.py
+++ b/geoportal/tests/test_raster.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -35,10 +35,10 @@ class TestRasterViews(TestCase):
def test_raster(self):
from decimal import Decimal
+ from c2cgeoportal_geoportal.views.raster import Raster
from pyramid.httpexceptions import HTTPNotFound
- from tests import DummyRequest
- from c2cgeoportal_geoportal.views.raster import Raster
+ from tests import DummyRequest
request = DummyRequest()
request.registry.settings = {
@@ -53,9 +53,9 @@ def test_raster(self):
request.params["lon"] = "565000"
request.params["lat"] = "218000"
result = raster.raster()
- assert result["dem1"] == None
- assert result["dem2"] == None
- assert result["dem3"] == None
+ assert result["dem1"] is None
+ assert result["dem2"] is None
+ assert result["dem3"] is None
request.params["lon"] = "548000"
request.params["lat"] = "216000"
@@ -77,10 +77,10 @@ def test_raster(self):
def test_raster_angle(self):
from decimal import Decimal
- from tests import DummyRequest
-
from c2cgeoportal_geoportal.views.raster import Raster
+ from tests import DummyRequest
+
request = DummyRequest()
request.registry.settings = {
"raster": {
@@ -117,15 +117,15 @@ def test_raster_angle(self):
request.params["lon"] = "547997.4"
request.params["lat"] = "216003.5"
result = raster.raster()
- assert result["dem5"] == None
+ assert result["dem5"] is None
def test_raster_vrt(self):
from decimal import Decimal
- from tests import DummyRequest
-
from c2cgeoportal_geoportal.views.raster import Raster
+ from tests import DummyRequest
+
request = DummyRequest()
request.registry.settings = {
"raster": {
@@ -158,10 +158,10 @@ def test_absolute_path(self):
def test_profile_json(self):
from decimal import Decimal
+ from c2cgeoportal_geoportal.views.profile import Profile
from pyramid.httpexceptions import HTTPNotFound
- from tests import DummyRequest
- from c2cgeoportal_geoportal.views.profile import Profile
+ from tests import DummyRequest
request = DummyRequest()
request.registry.settings = {
diff --git a/geoportal/tests/test_wmstparsing.py b/geoportal/tests/test_wmstparsing.py
index e4ccca04eb8..9e0eb294299 100644
--- a/geoportal/tests/test_wmstparsing.py
+++ b/geoportal/tests/test_wmstparsing.py
@@ -1,4 +1,4 @@
-# Copyright (c) 2013-2023, Camptocamp SA
+# Copyright (c) 2013-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -42,7 +42,10 @@ def test_parse_values(self):
self.assertTrue(isinstance(extent, TimeExtentValue))
def test_parse_interval(self):
- from c2cgeoportal_geoportal.lib.wmstparsing import TimeExtentInterval, parse_extent
+ from c2cgeoportal_geoportal.lib.wmstparsing import (
+ TimeExtentInterval,
+ parse_extent,
+ )
extent = parse_extent(["2000/2005/P1Y"], "2002")
self.assertTrue(isinstance(extent, TimeExtentInterval))
@@ -80,7 +83,10 @@ def test_merge_values(self):
)
def test_merge_interval(self):
- from c2cgeoportal_geoportal.lib.wmstparsing import TimeExtentInterval, parse_extent
+ from c2cgeoportal_geoportal.lib.wmstparsing import (
+ TimeExtentInterval,
+ parse_extent,
+ )
e1 = parse_extent(["2000/2005/P1Y"], "2000/2005")
e2 = parse_extent(["2006/2010/P1Y"], "2006/2010")
@@ -121,35 +127,35 @@ def test_parse_date_year(self):
from c2cgeoportal_geoportal.lib.wmstparsing import _parse_date
date = _parse_date("2010")
- assert "year" == date[0]
+ assert date[0] == "year"
self.assertEqual(datetime.datetime(2010, 0o1, 0o1, tzinfo=isodate.UTC), date[1])
def test_parse_date_month(self):
from c2cgeoportal_geoportal.lib.wmstparsing import _parse_date
date = _parse_date("2010-02")
- assert "month" == date[0]
+ assert date[0] == "month"
self.assertEqual(datetime.datetime(2010, 0o2, 0o1, tzinfo=isodate.UTC), date[1])
def test_parse_date(self):
from c2cgeoportal_geoportal.lib.wmstparsing import _parse_date
date = _parse_date("2010-02-03")
- assert "day" == date[0]
+ assert date[0] == "day"
self.assertEqual(datetime.datetime(2010, 0o2, 0o3, tzinfo=isodate.UTC), date[1])
def test_parse_datetime(self):
from c2cgeoportal_geoportal.lib.wmstparsing import _parse_date
date = _parse_date("2010-02-03T12:34")
- assert "second" == date[0]
+ assert date[0] == "second"
self.assertEqual(datetime.datetime(2010, 0o2, 0o3, 12, 34, tzinfo=isodate.UTC), date[1])
def test_parse_datetime_tz(self):
from c2cgeoportal_geoportal.lib.wmstparsing import _parse_date
date = _parse_date("2010-02-03T12:34Z")
- assert "second" == date[0]
+ assert date[0] == "second"
self.assertEqual(datetime.datetime(2010, 0o2, 0o3, 12, 34, tzinfo=isodate.UTC), date[1])
def test_unsupported_format(self):
@@ -163,13 +169,13 @@ def test_format(self):
from c2cgeoportal_geoportal.lib.wmstparsing import _format_date
dt = datetime.datetime(2010, 0o2, 0o1, 00, 00)
- assert "2010-02-01T00:00:00Z" == _format_date(dt)
+ assert _format_date(dt) == "2010-02-01T00:00:00Z"
def test_format_tz(self):
from c2cgeoportal_geoportal.lib.wmstparsing import _format_date, _parse_date
dt = _parse_date("2010-02-03T12:34:00+01:00")
- assert "2010-02-03T12:34:00+01:00" == _format_date(dt[1])
+ assert _format_date(dt[1]) == "2010-02-03T12:34:00+01:00"
class TestParseDuration(TestCase):
@@ -204,9 +210,8 @@ def test_second(self):
self.assertEqual((0, 0, 0, 10), _parse_duration("PT10S"))
def test_invalid(self):
- from isodate import ISO8601Error
-
from c2cgeoportal_geoportal.lib.wmstparsing import _parse_duration
+ from isodate import ISO8601Error
self.assertRaises(ISO8601Error, _parse_duration, "10S")
diff --git a/poetry.lock b/poetry.lock
index 1c52cffe095..413a316cdec 100644
--- a/poetry.lock
+++ b/poetry.lock
@@ -1,4 +1,4 @@
-# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand.
+# This file is automatically @generated by Poetry 1.8.4 and should not be changed by hand.
[[package]]
name = "affine"
@@ -2640,6 +2640,7 @@ pylint-flask = "0.6"
pyroma = {version = ">=2.4", optional = true, markers = "extra == \"with-pyroma\" or extra == \"with_everything\""}
PyYAML = "*"
requirements-detector = ">=1.3.2"
+ruff = {version = "*", optional = true, markers = "extra == \"with-ruff\" or extra == \"with_everything\""}
setoptconf-tmp = ">=0.3.1,<0.4.0"
toml = ">=0.10.2,<0.11.0"
@@ -2654,24 +2655,24 @@ with-vulture = ["vulture (>=1.5)"]
[[package]]
name = "prospector-profile-duplicated"
-version = "1.8.0"
+version = "1.9.0"
description = "Profile that can be used to disable the duplicated or conflict rules between Prospector and other tools"
optional = false
python-versions = "*"
files = [
- {file = "prospector_profile_duplicated-1.8.0-py2.py3-none-any.whl", hash = "sha256:c36ca647848739e1ca52cf220b00ba1fbdf7105217d5534a5bf2e65279ad6011"},
- {file = "prospector_profile_duplicated-1.8.0.tar.gz", hash = "sha256:1565109b016fac05c61dbce38b952bfce3ff054d0c5493d1acad1fc8e9909704"},
+ {file = "prospector_profile_duplicated-1.9.0-py2.py3-none-any.whl", hash = "sha256:7b7a665e6fa8b44fac597d2bbef1a91de5b6f090b8d64890a5f38ee60e8473c2"},
+ {file = "prospector_profile_duplicated-1.9.0.tar.gz", hash = "sha256:bb0b0d0946232d570ada944ee4a180fd142529db0978579b58e766d28f3c2a27"},
]
[[package]]
name = "prospector-profile-utils"
-version = "1.13.0"
+version = "1.14.1"
description = "Some utility Prospector profiles."
optional = false
python-versions = "<4.0,>=3.9"
files = [
- {file = "prospector_profile_utils-1.13.0-py3-none-any.whl", hash = "sha256:f991f8f2709c5a2c693d0e0a672a8f3ce2db3f1767b4dc2fbe167395c7dbdbb3"},
- {file = "prospector_profile_utils-1.13.0.tar.gz", hash = "sha256:2f98ddda31c0fa024134fe687e9828855f3597ea52de7a710d1aa508de8fda0a"},
+ {file = "prospector_profile_utils-1.14.1-py3-none-any.whl", hash = "sha256:1b7d79e4293c76f9ea5107b691c888e76933aa29d33e8f8b8750dc0aeea3b657"},
+ {file = "prospector_profile_utils-1.14.1.tar.gz", hash = "sha256:5447086f9a7ddba02d8ee7322baa30c80c1376328677a6593165fab23e2e4bf2"},
]
[package.dependencies]
@@ -3967,6 +3968,33 @@ files = [
{file = "ruamel.yaml.clib-0.2.12.tar.gz", hash = "sha256:6c8fbb13ec503f99a91901ab46e0b07ae7941cd527393187039aec586fdfd36f"},
]
+[[package]]
+name = "ruff"
+version = "0.8.1"
+description = "An extremely fast Python linter and code formatter, written in Rust."
+optional = false
+python-versions = ">=3.7"
+files = [
+ {file = "ruff-0.8.1-py3-none-linux_armv6l.whl", hash = "sha256:fae0805bd514066f20309f6742f6ee7904a773eb9e6c17c45d6b1600ca65c9b5"},
+ {file = "ruff-0.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8a4f7385c2285c30f34b200ca5511fcc865f17578383db154e098150ce0a087"},
+ {file = "ruff-0.8.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cd054486da0c53e41e0086e1730eb77d1f698154f910e0cd9e0d64274979a209"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2029b8c22da147c50ae577e621a5bfbc5d1fed75d86af53643d7a7aee1d23871"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2666520828dee7dfc7e47ee4ea0d928f40de72056d929a7c5292d95071d881d1"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:333c57013ef8c97a53892aa56042831c372e0bb1785ab7026187b7abd0135ad5"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:288326162804f34088ac007139488dcb43de590a5ccfec3166396530b58fb89d"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b12c39b9448632284561cbf4191aa1b005882acbc81900ffa9f9f471c8ff7e26"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:364e6674450cbac8e998f7b30639040c99d81dfb5bbc6dfad69bc7a8f916b3d1"},
+ {file = "ruff-0.8.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b22346f845fec132aa39cd29acb94451d030c10874408dbf776af3aaeb53284c"},
+ {file = "ruff-0.8.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:b2f2f7a7e7648a2bfe6ead4e0a16745db956da0e3a231ad443d2a66a105c04fa"},
+ {file = "ruff-0.8.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:adf314fc458374c25c5c4a4a9270c3e8a6a807b1bec018cfa2813d6546215540"},
+ {file = "ruff-0.8.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a885d68342a231b5ba4d30b8c6e1b1ee3a65cf37e3d29b3c74069cdf1ee1e3c9"},
+ {file = "ruff-0.8.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:d2c16e3508c8cc73e96aa5127d0df8913d2290098f776416a4b157657bee44c5"},
+ {file = "ruff-0.8.1-py3-none-win32.whl", hash = "sha256:93335cd7c0eaedb44882d75a7acb7df4b77cd7cd0d2255c93b28791716e81790"},
+ {file = "ruff-0.8.1-py3-none-win_amd64.whl", hash = "sha256:2954cdbe8dfd8ab359d4a30cd971b589d335a44d444b6ca2cb3d1da21b75e4b6"},
+ {file = "ruff-0.8.1-py3-none-win_arm64.whl", hash = "sha256:55873cc1a473e5ac129d15eccb3c008c096b94809d693fc7053f588b67822737"},
+ {file = "ruff-0.8.1.tar.gz", hash = "sha256:3583db9a6450364ed5ca3f3b4225958b24f78178908d5c4bc0f46251ccca898f"},
+]
+
[[package]]
name = "semver"
version = "3.0.2"
@@ -4865,4 +4893,4 @@ test = ["zope.testing"]
[metadata]
lock-version = "2.0"
python-versions = ">=3.10,<3.13"
-content-hash = "7ccfc30f32b7d2dd4599a350c35aea8bda0321ed0831225da7fb247ce3dfa11c"
+content-hash = "80e474f923a3d4698658b1dd37c7992c113b525fac34bbd51abec1ce38526c13"
diff --git a/pyproject.toml b/pyproject.toml
index e22e1c6c845..97a05226155 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,25 +1,5 @@
-[tool.mypy]
-python_version = "3.10"
-warn_redundant_casts = true
-warn_unused_ignores = true
-warn_return_any = true
-ignore_missing_imports = true
-disallow_untyped_defs = true
-strict_optional = true
-strict = true
-
-[[tool.mypy.overrides]]
-module = "c2cgeoportal_admin.*"
-disallow_untyped_defs = false
-
-[tool.black]
-line-length = 110
-target-version = ['py310']
-
-[tool.isort]
-profile = "black"
-line_length = 110
-known_local_folder = ["c2cgeoportal_commons", "c2cgeoportal_geoportal", "c2cgeoportal_admin", "geomapfish_qgisserver", "{{cookiecutter.package}}_geoportal"]
+[tool.ruff]
+target-version = 'py310'
[tool.poetry]
name = "c2cgeoportal"
@@ -75,9 +55,9 @@ azure-storage-blob = "12.24.0"
simple_openid_connect = { git = "https://github.com/sbrunner/py_simple_openid_connect.git", branch = "allows-pkce" } # geoportal
pkce = '1.0.3' # geoportal
basicauth = "1.0.0"
-prospector = { extras = ["with_mypy", "with_bandit", "with_pyroma"], version = "1.13.3" }
-prospector-profile-duplicated = "1.8.0"
-prospector-profile-utils = "1.13.0"
+prospector = { version = "1.13.3", extras = ["with_mypy", "with_bandit", "with_pyroma", "with_ruff"] }
+prospector-profile-duplicated = "1.9.0"
+prospector-profile-utils = "1.14.1"
beautifulsoup4 = "4.12.3"
[tool.poetry.group.dev.dependencies]
diff --git a/scripts/get-version b/scripts/get-version
index 827ea37c3af..0f1eca4af98 100755
--- a/scripts/get-version
+++ b/scripts/get-version
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright (c) 2018-2023, Camptocamp SA
+# Copyright (c) 2018-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -31,7 +31,7 @@
import argparse
import os
import re
-import subprocess
+import subprocess # nosec
import sys
import requests
diff --git a/scripts/updated_version b/scripts/updated_version
index 02707db4d37..11dffcd58da 100755
--- a/scripts/updated_version
+++ b/scripts/updated_version
@@ -29,7 +29,7 @@
import argparse
import json
-import subprocess
+import subprocess # nosec
from packaging.version import Version
diff --git a/scripts/upgrade b/scripts/upgrade
index c5234109569..53801b87aa6 100755
--- a/scripts/upgrade
+++ b/scripts/upgrade
@@ -1,6 +1,6 @@
#!/usr/bin/env python3
-# Copyright (c) 2019-2023, Camptocamp SA
+# Copyright (c) 2019-2024, Camptocamp SA
# All rights reserved.
# Redistribution and use in source and binary forms, with or without
@@ -32,7 +32,7 @@ import argparse
import os
import platform
import re
-import subprocess
+import subprocess # nosec
import sys
parser = argparse.ArgumentParser(description="Upgrade the project")