diff --git a/.dockerignore b/.dockerignore index 829aadd5e9..d263cf713f 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,14 +1,10 @@ * !pyramid_oereb -!requirements.txt -!setup.py !README.rst !CHANGES.rst !docker !logo_*.jpg !tests !MANIFEST.in -!pytest.ini !.coveragerc -!tests-requirements.txt -!dev-requirements.txt +!pyproject.toml diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 008d975a69..8e4a771671 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -7,7 +7,7 @@ jobs: name: Check style (lint) runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - run: sudo rm /etc/apt/sources.list.d/*.list - run: sudo apt update - run: sudo apt-get install libpq-dev @@ -18,7 +18,7 @@ jobs: name: Check style (git-attributes) runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - run: sudo rm /etc/apt/sources.list.d/*.list - run: sudo apt update - run: sudo apt-get install libpq-dev @@ -50,8 +50,9 @@ jobs: - '3.9' - '3.10' - '3.11' + - '3.12' steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - name: Set up Python v${{ matrix.python-version }} uses: actions/setup-python@v5 with: @@ -63,7 +64,7 @@ jobs: - name: Run tests for Python ${{ matrix.python-version }} run: make tests - name: Upload coverage to Codecov - uses: codecov/codecov-action@v3 + uses: codecov/codecov-action@v4 with: token: ${{ secrets.CODECOV_TOKEN }} env_vars: OS,PYTHON @@ -77,7 +78,7 @@ jobs: name: Check federal data definitions runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - run: sudo rm /etc/apt/sources.list.d/*.list - run: sudo apt update - run: sudo apt-get install xsltproc @@ -94,7 +95,7 @@ jobs: if: github.ref == 'refs/heads/master' runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - name: Make documentation run: | sudo rm /etc/apt/sources.list.d/*.list @@ -102,7 +103,7 @@ jobs: sudo apt-get install libpq-dev make doc-html - name: Deploy 🚀 - uses: JamesIves/github-pages-deploy-action@v4.5.0 + uses: JamesIves/github-pages-deploy-action@v4.6.1 with: branch: gh-pages # The branch the action should deploy to. folder: doc/build/html # The folder the action should deploy. @@ -113,10 +114,10 @@ jobs: needs: [lint, gitattributes] steps: - uses: actions/checkout@master - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: 3.11 + python-version: 3.12 - name: Install pypa/build run: >- python -m diff --git a/.github/workflows/daily_check.yaml b/.github/workflows/daily_check.yaml index 991de87987..c1bd4c9fdd 100644 --- a/.github/workflows/daily_check.yaml +++ b/.github/workflows/daily_check.yaml @@ -8,7 +8,7 @@ jobs: name: Check federal data definitions runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - run: sudo rm /etc/apt/sources.list.d/*.list - run: sudo apt update - run: sudo apt-get install xsltproc @@ -45,8 +45,9 @@ jobs: - python3.9 - python3.10 - python3.11 + - python3.12 steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 + - uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4 - run: sudo rm /etc/apt/sources.list.d/*.list - run: sudo apt update - run: sudo apt-get install libpq-dev @@ -54,10 +55,10 @@ jobs: env: PYTHON_TEST_VERSION: ${{ matrix.python-version }} run: make tests - - name: Set up Python 3.11 + - name: Set up Python 3.12 uses: actions/setup-python@v5 with: - python-version: 3.11 + python-version: 3.12 - name: Install pypa/build run: >- python -m diff --git a/CHANGES.rst b/CHANGES.rst index ee72c69aff..c8946d4ae8 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -1,6 +1,11 @@ Changelog ========= +2.5.0 +----- +- Use ST_DWithin instead of ST_Distance for performance reasons (#1930) +- Library upgrades (SQLAlchemy, geoalchemy2, urllib3, pypdf) + 2.4.8 ----- - Support new Oereblex API version (via geolink-formatter 2.0.5) diff --git a/Dockerfile b/Dockerfile index 097322c836..2c571d878b 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11-bullseye +FROM python:3.12.3-bullseye ENV DEBIAN_FRONTEND=noninteractive @@ -26,7 +26,5 @@ COPY . /workspace/ WORKDIR /workspace -RUN pip install -r requirements.txt -r tests-requirements.txt -r dev-requirements.txt - # keep container running until killed - For DEV use only CMD [ "pserve", "development.ini", "--reload"] diff --git a/MANIFEST.in b/MANIFEST.in index 563c9bf690..7180208abe 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,4 +1,4 @@ -include README.rst CHANGES.rst requirements.txt +include README.rst CHANGES.rst recursive-include pyramid_oereb/standard *.mako recursive-include pyramid_oereb/standard *.xml recursive-include pyramid_oereb/core/renderer *.xml diff --git a/Makefile b/Makefile index 2b469c717e..f4c088c1b8 100644 --- a/Makefile +++ b/Makefile @@ -64,9 +64,10 @@ ${VENV_ROOT}/timestamp: python3 -m venv ${VENV_ROOT} touch $@ -${VENV_ROOT}/requirements-timestamp: ${VENV_ROOT}/timestamp setup.py requirements.txt tests-requirements.txt dev-requirements.txt +${VENV_ROOT}/requirements-timestamp: ${VENV_ROOT}/timestamp pyproject.toml $(VENV_BIN)/$(PIP_COMMAND) install --upgrade pip wheel - $(VENV_BIN)/$(PIP_COMMAND) install -r requirements.txt -r tests-requirements.txt -r dev-requirements.txt + $(VENV_BIN)/$(PIP_COMMAND) install .[recommend] .[testing] .[dev] + $(VENV_BIN)/$(PIP_COMMAND) install --editable . touch $@ ########## @@ -260,8 +261,7 @@ clean_dev_db_scripts: .PHONY: install install: ${VENV_ROOT}/requirements-timestamp -$(DEV_CREATE_MAIN_TABLES_SCRIPT) $(DEV_CREATE_STANDARD_TABLES_SCRIPT) $(DEV_CREATE_OEREBLEX_TABLES_SCRIPT) $(DEV_CREATE_STANDARD_YML_SCRIPT): setup.py $(BUILD_DEPS) - $(VENV_BIN)/python $< develop +$(DEV_CREATE_MAIN_TABLES_SCRIPT) $(DEV_CREATE_STANDARD_TABLES_SCRIPT) $(DEV_CREATE_OEREBLEX_TABLES_SCRIPT) $(DEV_CREATE_STANDARD_YML_SCRIPT): pyproject.toml $(BUILD_DEPS) development.ini: install $(VENV_BIN)/mako-render --var pyramid_oereb_port=$(PYRAMID_OEREB_PORT) --var pyramid_stats_url=$(STATS_URL) development.ini.mako > development.ini @@ -273,14 +273,20 @@ build: install $(DEV_CREATE_MAIN_TABLES_SCRIPT) $(DEV_CREATE_STANDARD_TABLES_SCR clean: clean_fed_data clean_dev_db_scripts rm -f $(DEV_CONFIGURATION_YML) rm -f coverage.core.xml + rm -f coverage.core_adapter.xml rm -f coverage.contrib-data_sources-standard.xml rm -f coverage.contrib-data_sources-interlis.xml + rm -f coverage.contrib-data_sources-oereblex.xml + rm -f coverage.contrib-data_sources-swisstopo.xml rm -f coverage.contrib-print_proxy-mapfish_print.xml rm -f coverage.contrib-stats.xml + rm -f .coverage + rm -rf tmp .PHONY: clean-all clean-all: clean rm -rf ${VENV_ROOT} + rm -rf build rm -f development.ini rm -rf $(PACKAGE).egg-info @@ -310,6 +316,7 @@ test-core_adapter: ${VENV_ROOT}/requirements-timestamp .PHONY: test-contrib-print_proxy-mapfish_print test-contrib-print_proxy-mapfish_print: ${VENV_ROOT}/requirements-timestamp + mkdir ./tmp $(VENV_BIN)/py.test -vv $(PYTEST_OPTS) --cov-config .coveragerc.contrib-print_proxy-mapfish_print --cov $(PACKAGE) --cov-report xml:coverage.contrib-print_proxy-mapfish_print.xml tests/contrib.print_proxy.mapfish_print .PHONY: test-contrib-data_sources-standard diff --git a/dev-requirements.txt b/dev-requirements.txt deleted file mode 100644 index cf271f9afc..0000000000 --- a/dev-requirements.txt +++ /dev/null @@ -1,10 +0,0 @@ -flake8==7.0.0 -pyflakes==3.2.0 -pycodestyle==2.11.1 -Sphinx==7.2.6 -sphinx_rtd_theme==2.0.0 -psycopg2==2.9.9 -mccabe==0.7.0 -c2c.template==2.3.0 -yappi --e . diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 9f3b3edf73..f5c6a9ad72 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -6,6 +6,13 @@ Changes/Hints for migration This chapter will give you hints on how to handle version migration, in particular regarding what you may need to adapt in your project configuration, database etc. when upgrading to a new version. +Version 2.5.0 +------------- +Performance optimization release: + +* Use ST_DWithin instead of ST_Distance for performance reasons (#1930) +* Library upgrades (SQLAlchemy, geoalchemy2, urllib3, pypdf) + Version 2.4.8 ------------- Maintenance release: diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000000..f9f50cc2c5 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,117 @@ +[build-system] +requires = [ + "setuptools >= 69.5.1", + "wheel" +] +build-backend = "setuptools.build_meta" + +[project] +name = "pyramid_oereb" +version = "2.5.0" +description = "pyramid_oereb, extension for pyramid web frame work to provide a basic server part for the oereb project" + +classifiers=[ + "Development Status :: 5 - Production/Stable", + "Intended Audience :: Developers", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Framework :: Pyramid", + "Topic :: Internet :: WWW/HTTP", + "Topic :: Internet :: WWW/HTTP :: WSGI :: Application" + ] +license = {file = "LICENSE.txt"} +authors = [ + {name = "François Voisard", email = "francois.voisard@ne.ch"}, +] +keywords = ["pyramid oereb"] +readme = "README.rst" + +[project.urls] +Repository = "https://github.com/openoereb/pyramid_oereb" +Changelog = "https://github.com/openoereb/pyramid_oereb/blob/master/CHANGES.rst" + +[project.optional-dependencies] +# Dependencies listed in "recommend" must be included in "no-version" without explicit version number +recommend = [ + "pypdf==4.2.0", + "filetype==1.2.0", + "geoalchemy2==0.15.1", + "pyramid==2.0.2", + "pyramid-debugtoolbar==4.12.1", + "qrcode==7.4.2", + "image==1.5.33", + "shapely==2.0.4", + "SQLAlchemy==2.0.30", + "pyaml-env==1.2.1", + "urllib3==2.2.1", + "waitress==3.0.0", + "pyreproj==3.0.0", + "mako-render==0.1.0", + "requests==2.32.2", + "geolink-formatter==2.0.5", + "pyconizer==0.1.4", + "c2cwsgiutils[standard]==6.0.8"] +no-version = [ + "pypdf", + "filetype", + "geoalchemy2", + "pyramid", + "pyramid-debugtoolbar", + "qrcode", + "image", + "shapely", + "SQLAlchemy", + "pyaml-env", + "urllib3", + "waitress", + "pyreproj", + "mako-render", + "requests", + "geolink-formatter", + "pyconizer", + "c2cwsgiutils[standard]"] +testing = [ + "jsonschema==4.22.0", + "lxml==5.2.2", + "pytest==8.2.1", + "pytest-cov==5.0.0", + "pytest-ordering==0.6", + "requests-mock==1.12.1", + "responses==0.25.0", + "webtest==3.0.0", + "pillow==10.3.0"] +dev = [ + "flake8==7.0.0", + "Flake8-pyproject==1.2.3", + "pyflakes==3.2.0", + "pycodestyle==2.11.1", + "Sphinx==7.3.7", + "sphinx_rtd_theme==2.0.0", + "psycopg2==2.9.9", + "mccabe==0.7.0", + "c2c.template==2.4.2", + "yappi"] + +[tool.setuptools.packages.find] + +[project.entry-points."paste.app_factory"] +main = "pyramid_oereb:main" + +[project.scripts] +create_standard_tables = "pyramid_oereb.contrib.data_sources.standard.create_tables:create_standard_tables" +create_oereblex_tables = "pyramid_oereb.contrib.data_sources.oereblex.create_tables:create_oereblex_tables" +create_main_schema_tables = "pyramid_oereb.contrib.data_sources.create_tables:create_main_schema_tables" +create_example_yaml = "dev.config.create_yaml:create_yaml" +create_theme_tables = "pyramid_oereb.contrib.data_sources.create_tables:create_theme_tables" +create_legend_entries = "pyramid_oereb.contrib.data_sources.standard.load_legend_entries:run" +create_stats_tables = "pyramid_oereb.contrib.stats.scripts.create_stats_tables:create_stats_tables" + +[tool.flake8] +exclude = [".venv", "tests/init_db.py"] +max-line-length = 110 + +[tool.pytest.ini_options] +testpaths = ["tests"] +python_files = ["test_*.py"] diff --git a/pyramid_oereb/contrib/data_sources/interlis_2_3/sources/plr.py b/pyramid_oereb/contrib/data_sources/interlis_2_3/sources/plr.py index c26858199f..0306a86b29 100644 --- a/pyramid_oereb/contrib/data_sources/interlis_2_3/sources/plr.py +++ b/pyramid_oereb/contrib/data_sources/interlis_2_3/sources/plr.py @@ -8,6 +8,7 @@ GeometryCollection from sqlalchemy import or_ from sqlalchemy.orm import selectinload +from geoalchemy2.functions import ST_DWithin from pyramid_oereb import Config from pyramid_oereb.core import b64 @@ -433,15 +434,21 @@ def collect_related_geometries_by_real_estate(self, session, real_estate): else: query = session.query(self._model_).filter( or_( - self._model_.point.ST_Distance( - from_shape(real_estate.limit, srid=Config.get('srid')) - ) < self._tolerances.get('ALL', self._tolerances.get('Point', 0)), - self._model_.line.ST_Distance( - from_shape(real_estate.limit, srid=Config.get('srid')) - ) < self._tolerances.get('ALL', self._tolerances.get('LineString', 0)), - self._model_.surface.ST_Distance( - from_shape(real_estate.limit, srid=Config.get('srid')) - ) < self._tolerances.get('ALL', self._tolerances.get('Polygon', 0)) + ST_DWithin( + self._model_.point, + from_shape(real_estate.limit, srid=Config.get('srid')), + self._tolerances.get('ALL', self._tolerances.get('Point', 0)) + ), + ST_DWithin( + self._model_.line, + from_shape(real_estate.limit, srid=Config.get('srid')), + self._tolerances.get('ALL', self._tolerances.get('LineString', 0)) + ), + ST_DWithin( + self._model_.surface, + from_shape(real_estate.limit, srid=Config.get('srid')), + self._tolerances.get('ALL', self._tolerances.get('Polygon', 0)) + ) )) return query.distinct(self._model_.public_law_restriction_id).options( selectinload(self.models.Geometry.public_law_restriction) diff --git a/pyramid_oereb/contrib/data_sources/standard/sources/plr.py b/pyramid_oereb/contrib/data_sources/standard/sources/plr.py index 15c7422857..729c2c882c 100644 --- a/pyramid_oereb/contrib/data_sources/standard/sources/plr.py +++ b/pyramid_oereb/contrib/data_sources/standard/sources/plr.py @@ -3,6 +3,7 @@ import importlib from geoalchemy2.shape import to_shape, from_shape +from geoalchemy2.functions import ST_DWithin, ST_Intersects from shapely.geometry import Point, LineString, Polygon, MultiPoint, MultiLineString, MultiPolygon, \ GeometryCollection from sqlalchemy import text, or_ @@ -523,7 +524,7 @@ def extract_geometry_collection_db(db_path, real_estate_geometry, tolerances=Non ] clause_blocks = [ text(f'ST_Intersects({extract}, {geometry_string})') if tolerance is None - else text(f'ST_Distance({extract}, {geometry_string}) < {tolerance}') + else text(f'ST_DWithin({extract}, {geometry_string}, {tolerance})') for extract, tolerance in zip([extract_point, extract_line, extract_polygon], tolerance_extracts) ] return or_(*clause_blocks) @@ -560,17 +561,28 @@ def handle_collection(self, session, geometry_to_check): else: # The PLR is not problematic at all cause we do not have a collection type here if (self._tolerances is not None) and ('ALL' in self._tolerances): - query = session.query(self._model_).filter(self._model_.geom.ST_Distance( - from_shape(geometry_to_check, srid=Config.get('srid')) - ) < self._tolerances['ALL']) + query = session.query(self._model_).filter( + ST_DWithin( + self._model_.geom, + from_shape(geometry_to_check, srid=Config.get('srid')), + self._tolerances['ALL'] + ) + ) elif (self._tolerances is not None) and (geometry_to_check.geom_type in self._tolerances): - query = session.query(self._model_).filter(self._model_.geom.ST_Distance( - from_shape(geometry_to_check, srid=Config.get('srid')) - ) < self._tolerances[geometry_to_check.geom_type]) + query = session.query(self._model_).filter( + ST_DWithin( + self._model_.geom, + from_shape(geometry_to_check, srid=Config.get('srid')), + self._tolerances[geometry_to_check.geom_type] + ) + ) else: - query = session.query(self._model_).filter(self._model_.geom.ST_Intersects( - from_shape(geometry_to_check, srid=Config.get('srid')) - )) + query = session.query(self._model_).filter( + ST_Intersects( + self._model_.geom, + from_shape(geometry_to_check, srid=Config.get('srid')) + ) + ) return query def collect_related_geometries_by_real_estate(self, session, real_estate): diff --git a/pytest.ini b/pytest.ini deleted file mode 100644 index 27eec68ed7..0000000000 --- a/pytest.ini +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -testpaths = tests -python_files = test_*.py diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 1aac089986..0000000000 --- a/requirements.txt +++ /dev/null @@ -1,18 +0,0 @@ -pypdf==3.17.4 -filetype==1.2.0 -geoalchemy2==0.14.3 -pyramid==2.0.2 -pyramid-debugtoolbar==4.10 -qrcode==7.4.2 -image==1.5.33 -shapely==2.0.2 -SQLAlchemy==2.0.25 -pyaml-env==1.2.1 -urllib3==2.1.0 -waitress==2.1.2 -pyreproj==3.0.0 -mako-render==0.1.0 -requests==2.31.0 -geolink-formatter==2.0.5 -pyconizer==0.1.4 -c2cwsgiutils[standard]==6.0.7 diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index da3ec25f07..0000000000 --- a/setup.cfg +++ /dev/null @@ -1,6 +0,0 @@ -[bdist_wheel] -universal = 1 - -[flake8] -exclude = .venv tests/init_db.py -max-line-length = 110 diff --git a/setup.py b/setup.py deleted file mode 100644 index 4b6ba3143a..0000000000 --- a/setup.py +++ /dev/null @@ -1,65 +0,0 @@ -# -*- coding: utf-8 -*- - -import os -import re -from setuptools import setup, find_packages - -HERE = os.path.abspath(os.path.dirname(__file__)) -with open(os.path.join(HERE, 'README.rst')) as f: - README = f.read() -with open(os.path.join(HERE, 'CHANGES.rst')) as f: - CHANGES = f.read() -with open('requirements.txt') as f: - re_ = a = re.compile(r'(.+)==') - recommend = f.read().splitlines() -requires = [re_.match(r).group(1) for r in recommend] - -with open('tests-requirements.txt') as f: - re_ = a = re.compile(r'(.+)==') - tests_require = f.read().splitlines() - -setup( - name='pyramid_oereb', - version='2.4.8', - description='pyramid_oereb, extension for pyramid web frame work to provide ' - 'a basic server part for the oereb project', - long_description='{readme}\n\n{changes}'.format(readme=README, changes=CHANGES), - long_description_content_type='text/x-rst', - classifiers=[ - "Development Status :: 5 - Production/Stable", - "Intended Audience :: Developers", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Framework :: Pyramid", - "Topic :: Internet :: WWW/HTTP", - "Topic :: Internet :: WWW/HTTP :: WSGI :: Application" - ], - license='BSD 2', - author='François Voisard', - author_email='francois.voisard@ne.ch', - url='https://github.com/openoereb/pyramid_oereb', - keywords='pyramid oereb', - packages=find_packages(), - include_package_data=True, - zip_safe=False, - extras_require={ - 'recommend': recommend, - 'no-version': requires, - 'testing': tests_require - }, - entry_points={ - 'paste.app_factory': [ - 'main = pyramid_oereb:main' - ], - 'console_scripts': [ - 'create_standard_tables = pyramid_oereb.contrib.data_sources.standard.create_tables:create_standard_tables', # noqa: E501 - 'create_oereblex_tables = pyramid_oereb.contrib.data_sources.oereblex.create_tables:create_oereblex_tables', # noqa: E501 - 'create_main_schema_tables = pyramid_oereb.contrib.data_sources.create_tables:create_main_schema_tables', # noqa: E501 - 'create_example_yaml = dev.config.create_yaml:create_yaml', - 'create_theme_tables = pyramid_oereb.contrib.data_sources.create_tables:create_theme_tables', - 'create_legend_entries = pyramid_oereb.contrib.data_sources.standard.load_legend_entries:run', - 'create_stats_tables = pyramid_oereb.contrib.stats.scripts.create_stats_tables:create_stats_tables' # noqa: E501 - ] - } -) diff --git a/tests-requirements.txt b/tests-requirements.txt deleted file mode 100644 index 1b22d80d3c..0000000000 --- a/tests-requirements.txt +++ /dev/null @@ -1,9 +0,0 @@ -jsonschema==4.21.1 -lxml==5.1.0 -pytest==7.4.4 -pytest-cov==4.1.0 -pytest-ordering==0.6 -requests-mock==1.11.0 -responses==0.24.1 -webtest==3.0.0 -pillow==10.2.0 diff --git a/tests/contrib.data_sources.standard/sources/test_plr.py b/tests/contrib.data_sources.standard/sources/test_plr.py index a8e280e0ec..33fe945136 100644 --- a/tests/contrib.data_sources.standard/sources/test_plr.py +++ b/tests/contrib.data_sources.standard/sources/test_plr.py @@ -1,4 +1,5 @@ import datetime +import math import pytest from unittest.mock import patch @@ -820,28 +821,28 @@ def test_handle_collection_tolerance(tolerances, with_collection, config_config, # check results for 8 combinations of with_collection + tolerances from sqlalchemy.sql.annotation import AnnotatedColumn - from sqlalchemy.sql.elements import BinaryExpression, BooleanClauseList, TextClause - from geoalchemy2.functions import ST_Intersects, ST_Distance, ST_GeomFromWKB + from sqlalchemy.sql.elements import BooleanClauseList, TextClause, BindParameter + from geoalchemy2.functions import ST_Intersects, ST_DWithin, ST_GeomFromWKB if with_collection: assert type(query.received_clause) is BooleanClauseList for clause in query.received_clause.clauses: assert type(clause) is TextClause if tolerances: - assert 'ST_Distance' in clause.text + assert 'ST_DWithin' in clause.text else: assert 'ST_Intersects' in clause.text else: if tolerances: - assert type(query.received_clause) is BinaryExpression - test_clause = query.received_clause.left - assert type(test_clause) is ST_Distance - query.received_clause.right.value == 0.1 + assert type(query.received_clause) is ST_DWithin + assert { + type(el) for el in query.received_clause.clause_expr.element.clauses + } == {AnnotatedColumn, ST_GeomFromWKB, BindParameter} + assert math.isclose(query.received_clause.clauses.clauses[2].value, 0.1, rel_tol=1e-9) else: - test_clause = query.received_clause - assert type(test_clause) is ST_Intersects - assert { - type(el) for el in test_clause.clause_expr.element.clauses - } == {AnnotatedColumn, ST_GeomFromWKB} + assert type(query.received_clause) is ST_Intersects + assert { + type(el) for el in query.received_clause.clause_expr.element.clauses + } == {AnnotatedColumn, ST_GeomFromWKB} @pytest.mark.parametrize('geom,length,geom_type', [ diff --git a/tests/contrib.print_proxy.mapfish_print/test_mapfish_print.py b/tests/contrib.print_proxy.mapfish_print/test_mapfish_print.py index 9dc4a0a4df..92ec3ac9e9 100644 --- a/tests/contrib.print_proxy.mapfish_print/test_mapfish_print.py +++ b/tests/contrib.print_proxy.mapfish_print/test_mapfish_print.py @@ -738,7 +738,7 @@ def test_archive_pdf(DummyRenderInfo): 'CreationDate': '2023-08-21T13:48:07' } renderer.set_global_datetime(extract['CreationDate']) - path_and_filename = renderer.archive_pdf_file('/tmp', bytes(), extract) + path_and_filename = renderer.archive_pdf_file('./tmp', bytes(), extract) partial_filename = str('_') + extract['RealEstate_EGRID'] + '.pdf' assert partial_filename in path_and_filename assert os.path.isfile(path_and_filename) @@ -752,7 +752,7 @@ def test_archive_pdf_identdn(DummyRenderInfo): 'CreationDate': '2023-08-21T13:48:07' } renderer.set_global_datetime(extract['CreationDate']) - path_and_filename = renderer.archive_pdf_file('/tmp', bytes(), extract) + path_and_filename = renderer.archive_pdf_file('./tmp', bytes(), extract) partial_filename = extract['RealEstate_IdentDN'] + str('_') + extract['RealEstate_Number'] + '.pdf' assert partial_filename in path_and_filename assert os.path.isfile(path_and_filename)