[Git][debian-gis-team/pyosmium][trixie-backports] 9 commits: Bump Standards-Version to 4.7.4, changes: priority.
Bas Couwenberg (@sebastic)
gitlab at salsa.debian.org
Wed Oct 21 04:53:57 BST 2026
Bas Couwenberg pushed to branch trixie-backports at Debian GIS Project / pyosmium
Commits:
5d63fe92 by Bas Couwenberg at 2026-04-04T10:19:33+02:00
Bump Standards-Version to 4.7.4, changes: priority.
- - - - -
725b28f8 by Bas Couwenberg at 2026-04-04T11:00:51+02:00
Fix changelog entry.
- - - - -
72fd2f53 by Bas Couwenberg at 2026-04-07T16:57:03+02:00
Require libosmium2-dev 2.23.1 from backports for replication fix.
- - - - -
a05e6942 by Bas Couwenberg at 2026-10-18T17:19:10+02:00
New upstream version 4.3.2
- - - - -
efcd38fc by Bas Couwenberg at 2026-10-18T17:19:16+02:00
Update upstream source from tag 'upstream/4.3.2'
Update to upstream version '4.3.2'
with Debian dir 898b53e64a79328ea2611b101582a38b2604fadc
- - - - -
f5fb6385 by Bas Couwenberg at 2026-10-18T17:19:40+02:00
New upstream release.
- - - - -
9f7ed903 by Bas Couwenberg at 2026-10-18T17:20:28+02:00
Set distribution to unstable.
- - - - -
7b99d4a7 by Bas Couwenberg at 2026-10-21T05:46:56+02:00
Merge tag 'debian/4.3.2-1' into trixie-backports
releasing package pyosmium version 4.3.2-1
- - - - -
88f6673b by Bas Couwenberg at 2026-10-21T05:47:05+02:00
Rebuild for trixie-backports.
- - - - -
19 changed files:
- .github/workflows/build_wheels.yml
- .github/workflows/ci.yml
- CHANGELOG.md
- CMakeLists.txt
- README.md
- cmake/FindOsmium.cmake
- debian/changelog
- debian/control
- docs/man/pyosmium-get-changes.1
- docs/man/pyosmium-up-to-date.1
- lib/merge_input_reader.cc
- lib/osm_base_objects.h
- pyproject.toml
- src/osmium/replication/server.py
- src/osmium/replication/utils.py
- + test/test_constructor_interruption.py
- test/test_merge_input_reader.py
- test/test_replication.py
- test/test_replication_utils.py
Changes:
=====================================
.github/workflows/build_wheels.yml
=====================================
@@ -4,6 +4,8 @@ on:
push:
tags:
- v**
+ paths:
+ - CHANGELOG.md
jobs:
build_wheels:
@@ -31,19 +33,19 @@ jobs:
run: python -m pip install cibuildwheel build
- name: Get dependencies via sdist
- run: python -m build --sdist
+ run: python -m build --sdist -C build-dir=build/sdist
- name: Build wheels
run: |
python -m cibuildwheel --output-dir wheelhouse
shell: bash
env:
- CIBW_ENABLE: cpython-freethreading
CIBW_ARCHS: "native"
CIBW_SKIP: "*musllinux*"
CIBW_TEST_REQUIRES: pytest pytest-httpserver
CIBW_TEST_COMMAND: pytest {project}/test
CIBW_BUILD_FRONTEND: build
+ CIBW_CONFIG_SETTINGS_WINDOWS: "build-dir=build/{wheel_tag}"
CIBW_BEFORE_BUILD_LINUX: yum install -y expat-devel zlib-devel bzip2-devel lz4-devel
CIBW_ENVIRONMENT_MACOS: MACOSX_DEPLOYMENT_TARGET=11.0 SKBUILD_CMAKE_ARGS=-DWITH_LZ4=OFF
CIBW_BEFORE_BUILD_WINDOWS: vcpkg install bzip2 expat zlib lz4
=====================================
.github/workflows/ci.yml
=====================================
@@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- name: Install packages
run: |
@@ -24,7 +24,7 @@ jobs:
run: mypy src
- name: Set up Python 3.8
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: 3.8
@@ -35,7 +35,7 @@ jobs:
shell: bash
- name: Set up Python 3.9
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: 3.9
@@ -46,7 +46,7 @@ jobs:
shell: bash
- name: Set up Python 3.10
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.10"
@@ -57,7 +57,7 @@ jobs:
shell: bash
- name: Set up Python 3.11
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.11"
@@ -68,7 +68,7 @@ jobs:
shell: bash
- name: Set up Python 3.12
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.12"
@@ -79,7 +79,7 @@ jobs:
shell: bash
- name: Set up Python 3.13
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.13"
@@ -90,10 +90,9 @@ jobs:
shell: bash
- name: Set up Python 3.14
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.14"
- allow-prereleases: true
- name: Build package 3.14
run: |
@@ -101,6 +100,18 @@ jobs:
python -m build
shell: bash
+ - name: Set up Python 3.15
+ uses: actions/setup-python at v7
+ with:
+ python-version: "3.15"
+ allow-prereleases: true
+
+ - name: Build package 3.15
+ run: |
+ pip install build wheel
+ python -m build
+ shell: bash
+
- name: Upload Artifact
uses: actions/upload-artifact at v7
with:
@@ -111,7 +122,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- name: Install packages
run: |
@@ -122,7 +133,7 @@ jobs:
pipx install flake8
- name: Set up Python 3.13t
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.13t"
@@ -133,7 +144,7 @@ jobs:
shell: bash
- name: Set up Python 3.14t
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.14t"
allow-prereleases: true
@@ -161,10 +172,10 @@ jobs:
python-version: [3.8, 3.9, "3.10", "3.11", "3.12", "3.13"]
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
@@ -196,13 +207,18 @@ jobs:
runs-on: ubuntu-24.04
needs: build-default
+ strategy:
+ fail-fast: false
+ matrix:
+ python-version: ["14", "15"]
+
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- - name: Set up Python 3.14
- uses: actions/setup-python at v6
+ - name: Set up Python 3.${{ matrix.python-version }}
+ uses: actions/setup-python at v7
with:
- python-version: 3.14
+ python-version: 3.${{ matrix.python-version }}
allow-prereleases: true
- uses: actions/download-artifact at v8
@@ -213,7 +229,7 @@ jobs:
run: |
pip install virtualenv
virtualenv osmium-test
- WHEEL=`ls osmium*314-*.whl`
+ WHEEL=`ls osmium*3${{ matrix.python-version }}-*.whl`
./osmium-test/bin/pip install ${WHEEL}
./osmium-test/bin/pip install pytest pytest-httpserver pytest-run-parallel
shell: bash
@@ -237,10 +253,10 @@ jobs:
python-version: ["3.13t", "3.14t"]
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
@@ -316,7 +332,7 @@ jobs:
CXX: ${{ matrix.cxx }}
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- name: Clean up build environment
run: |
@@ -337,7 +353,7 @@ jobs:
shell: bash
if: ${{ matrix.flavour == 'macos' }}
- - uses: actions/setup-python at v6
+ - uses: actions/setup-python at v7
with:
python-version: "${{ matrix.python }}"
allow-prereleases: true
@@ -394,9 +410,9 @@ jobs:
VCPKG_DEFAULT_BINARY_CACHE: C:/vcpkg_binary_cache
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- - uses: actions/cache at v5
+ - uses: actions/cache at v6
with:
path: |
C:/vcpkg_binary_cache
@@ -407,97 +423,110 @@ jobs:
shell: bash
- name: Install packages
- run: vcpkg install bzip2:x64-windows expat:x64-windows zlib:x64-windows lz4:x86-windows
+ run: vcpkg install bzip2 expat zlib lz4
shell: bash
- name: Set up Python 3.8
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: 3.8
- name: Build package 3.8
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Set up Python 3.9
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: 3.9
- name: Build package 3.9
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Set up Python 3.10
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.10"
- name: Build package 3.10
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Set up Python 3.11
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.11"
- name: Build package 3.11
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Set up Python 3.12
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.12"
- name: Build package 3.12
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Set up Python 3.13
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.13"
- name: Build package 3.13
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Set up Python 3.14
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.14"
- allow-prereleases: true
- name: Build package 3.14
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
+ shell: bash
+ env:
+ CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
+
+ - name: Set up Python 3.15
+ uses: actions/setup-python at v7
+ with:
+ python-version: "3.15"
+ allow-prereleases: true
+
+ - name: Build package 3.15
+ run: |
+ pip install build wheel
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
@@ -520,9 +549,9 @@ jobs:
VCPKG_DEFAULT_BINARY_CACHE: C:/vcpkg_binary_cache
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- - uses: actions/cache at v5
+ - uses: actions/cache at v6
with:
path: |
C:/vcpkg_binary_cache
@@ -534,24 +563,24 @@ jobs:
- name: Install packages
run: |
- vcpkg install bzip2:x64-windows expat:x64-windows zlib:x64-windows lz4:x86-windows
+ vcpkg install bzip2 expat zlib lz4
shell: bash
- name: Set up Python 3.13t
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.13t"
- name: Build package 3.13t
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
- name: Set up Python 3.14t
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: "3.14t"
allow-prereleases: true
@@ -559,7 +588,7 @@ jobs:
- name: Build package 3.14t
run: |
pip install build wheel
- python -m build
+ python -m build -C build-dir="$GITHUB_WORKSPACE/build/{state}-{wheel_tag}"
shell: bash
env:
CMAKE_TOOLCHAIN_FILE: C:/vcpkg/scripts/buildsystems/vcpkg.cmake
@@ -589,10 +618,10 @@ jobs:
PYTEST_ADDOPTS: ${{ matrix.test-args }}
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
@@ -647,10 +676,10 @@ jobs:
PYTEST_ADDOPTS: ${{ matrix.test-args }}
steps:
- - uses: actions/checkout at v6
+ - uses: actions/checkout at v7
- name: Set up Python ${{ matrix.python-version }}
- uses: actions/setup-python at v6
+ uses: actions/setup-python at v7
with:
python-version: ${{ matrix.python-version }}
allow-prereleases: true
@@ -668,7 +697,7 @@ jobs:
shell: bash
env:
PYVER: ${{ matrix.python-version }}
- if: matrix.python-version != '3.14t'
+ if: matrix.python-version != '3.13t'
- name: Install osmium (without shapely)
run: |
@@ -680,7 +709,7 @@ jobs:
shell: bash
env:
PYVER: ${{ matrix.python-version }}
- if: matrix.python-version == '3.14t'
+ if: matrix.python-version == '3.13t'
- name: Run tests
run: |
=====================================
CHANGELOG.md
=====================================
@@ -4,6 +4,23 @@
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
+## [4.3.2] - 2026-10-18
+
+### Added
+
+- support for Python 3.15
+
+### Fixed
+
+- MergeInputReader drops objects when IDs collide across OSM types
+- segfault when OSM object constructor is interrupted (thanks @t-miller)
+- bad variable in log output during replication (thanks @xovishnukosuri)
+
+### Changed
+
+- avoid double slashes in replication URLs (thanks @amandasaurus)
+- updated to protozero 1.8.2
+
## [4.3.1] - 2026-04-01
### Fixed
=====================================
CMakeLists.txt
=====================================
@@ -25,7 +25,7 @@ FetchContent_Declare(libosmium
GIT_SUBMODULES_RECURSE OFF)
FetchContent_Declare(protozero
GIT_REPOSITORY https://github.com/mapbox/protozero
- GIT_TAG 89a55ad2962cca3adbe8383a4b6d9a8411352ef2 # release 1.8.1
+ GIT_TAG af2f6e274e0a873a00e34d8c9ab99fca76898047 # release 1.8.2
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/contrib/protozero
SOURCE_SUBDIR cmake
GIT_SUBMODULES_RECURSE OFF)
=====================================
README.md
=====================================
@@ -79,7 +79,7 @@ Create a virtualenv with scikit-build-core and pybind11 preinstalled:
Now compile pyosmium with:
- /tmp/dev-venv/bin/pip --no-build-isolation --config-settings=editable.rebuild=true -Cbuild-dir=/tmp/build -ve.
+ /tmp/dev-venv/bin/pip install --no-build-isolation --config-settings=editable.rebuild=true -Cbuild-dir=/tmp/build -ve.
## Examples
=====================================
cmake/FindOsmium.cmake
=====================================
@@ -30,7 +30,6 @@
# pbf - include libraries needed for PBF input and output
# xml - include libraries needed for XML input and output
# io - include libraries needed for any type of input/output
-# geos - include if you want to use any of the GEOS functions
# gdal - include if you want to use any of the OGR functions
# lz4 - include support for LZ4 compression of PBF files
#
@@ -165,22 +164,6 @@ list(APPEND OSMIUM_LIBRARIES
${OSMIUM_IO_LIBRARIES}
)
-#----------------------------------------------------------------------
-# Component 'geos'
-if(Osmium_USE_GEOS)
- find_path(GEOS_INCLUDE_DIR geos/geom.h)
- find_library(GEOS_LIBRARY NAMES geos)
-
- list(APPEND OSMIUM_EXTRA_FIND_VARS GEOS_INCLUDE_DIR GEOS_LIBRARY)
- if(GEOS_INCLUDE_DIR AND GEOS_LIBRARY)
- SET(GEOS_FOUND 1)
- list(APPEND OSMIUM_LIBRARIES ${GEOS_LIBRARY})
- list(APPEND OSMIUM_INCLUDE_DIRS ${GEOS_INCLUDE_DIR})
- else()
- message(WARNING "Osmium: GEOS library is required but not found, please install it or configure the paths.")
- endif()
-endif()
-
#----------------------------------------------------------------------
# Component 'gdal' (alias 'ogr')
if(Osmium_USE_GDAL)
@@ -276,11 +259,7 @@ if(MSVC)
endif()
if(APPLE AND "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
-# following only available from cmake 2.8.12:
-# add_compile_options(-stdlib=libc++)
-# so using this instead:
- add_definitions(-stdlib=libc++)
- set(LDFLAGS ${LDFLAGS} -stdlib=libc++)
+ add_compile_options(-stdlib=libc++)
endif()
#----------------------------------------------------------------------
=====================================
debian/changelog
=====================================
@@ -1,3 +1,17 @@
+pyosmium (4.3.2-1~bpo13+1) trixie-backports; urgency=medium
+
+ * Rebuild for trixie-backports.
+
+ -- Bas Couwenberg <sebastic at debian.org> Wed, 21 Oct 2026 05:47:01 +0200
+
+pyosmium (4.3.2-1) unstable; urgency=medium
+
+ * New upstream release.
+ * Bump Standards-Version to 4.7.4, no changes.
+ * Require libosmium2-dev 2.23.1 for replication fix.
+
+ -- Bas Couwenberg <sebastic at debian.org> Sun, 18 Oct 2026 17:20:20 +0200
+
pyosmium (4.3.1-1~bpo13+1) trixie-backports; urgency=medium
* Rebuild for trixie-backports.
=====================================
debian/control
=====================================
@@ -19,7 +19,7 @@ Build-Depends: architecture-is-64-bit,
python3-scikit-build-core,
python3-shapely <!nocheck>,
python3-werkzeug <!nocheck>
-Standards-Version: 4.7.3
+Standards-Version: 4.7.4
Vcs-Browser: https://salsa.debian.org/debian-gis-team/pyosmium/
Vcs-Git: https://salsa.debian.org/debian-gis-team/pyosmium.git -b trixie-backports
Homepage: https://osmcode.org/pyosmium/
=====================================
docs/man/pyosmium-get-changes.1
=====================================
@@ -1,4 +1,4 @@
-.TH PYOSMIUM\-GET\-CHANGES "1" "2026\-04\-01" "pyosmium 4.3.1" "Generated Python Manual"
+.TH PYOSMIUM\-GET\-CHANGES "1" "2026\-10\-18" "pyosmium 4.3.2" "Generated Python Manual"
.SH NAME
pyosmium\-get\-changes
.SH SYNOPSIS
=====================================
docs/man/pyosmium-up-to-date.1
=====================================
@@ -1,4 +1,4 @@
-.TH PYOSMIUM\-UP\-TO\-DATE "1" "2026\-04\-01" "pyosmium 4.3.1" "Generated Python Manual"
+.TH PYOSMIUM\-UP\-TO\-DATE "1" "2026\-10\-18" "pyosmium 4.3.2" "Generated Python Manual"
.SH NAME
pyosmium\-up\-to\-date
.SH SYNOPSIS
=====================================
lib/merge_input_reader.cc
=====================================
@@ -33,6 +33,7 @@ namespace {
class copy_first_with_id {
osmium::io::Writer* writer;
osmium::object_id_type id = 0;
+ osmium::item_type type = osmium::item_type::undefined;
public:
using iterator_category = std::output_iterator_tag;
@@ -44,11 +45,12 @@ namespace {
}
void push_back(const osmium::OSMObject& obj) {
- if (obj.id() != id) {
+ if (obj.id() != id || obj.type() != type) {
if (obj.visible()) {
(*writer)(obj);
}
id = obj.id();
+ type = obj.type();
}
}
@@ -67,7 +69,7 @@ public:
osmium::item_type prev_type = osmium::item_type::undefined;
osmium::object_id_type prev_id = 0;
for (auto &item: objects) {
- if (item.type() != prev_type || item.id() != prev_id) {
+ if (item.id() != prev_id || item.type() != prev_type) {
prev_type = item.type();
prev_id = item.id();
pyosmium::apply_item(item, handler);
=====================================
lib/osm_base_objects.h
=====================================
@@ -2,7 +2,7 @@
*
* This file is part of pyosmium. (https://osmcode.org/pyosmium/)
*
- * Copyright (C) 2024 Sarah Hoffmann <lonvia at denofr.de> and others.
+ * Copyright (C) 2026 Sarah Hoffmann <lonvia at denofr.de> and others.
* For a full list of authors see the git log.
*/
#ifndef PYOSMIUM_OSM_BASE_OBJECTS_HPP
@@ -73,7 +73,6 @@ public:
pybind11::object get_or_create_python_object()
{
if (!m_valid) {
- m_valid = true;
if constexpr (std::is_same_v<T, osmium::Node>) {
m_pyobj = pybind11::module_::import("osmium.osm.types").attr("Node")(COSMNode{m_obj});
} else if constexpr (std::is_same_v<T, osmium::Way>) {
@@ -85,6 +84,7 @@ public:
} else if constexpr (std::is_same_v<T, osmium::Changeset>) {
m_pyobj = pybind11::module_::import("osmium.osm.types").attr("Changeset")(COSMChangeset{m_obj});
}
+ m_valid = true;
}
return m_pyobj;
=====================================
pyproject.toml
=====================================
@@ -4,7 +4,7 @@ build-backend = "scikit_build_core.build"
[project]
name = "osmium"
-version = "4.3.1"
+version = "4.3.2"
description = "Python bindings for libosmium, the data processing library for OSM data"
requires-python = ">=3.8"
readme = "README.rst"
=====================================
src/osmium/replication/server.py
=====================================
@@ -2,7 +2,7 @@
#
# This file is part of pyosmium. (https://osmcode.org/pyosmium/)
#
-# Copyright (C) 2025 Sarah Hoffmann <lonvia at denofr.de> and others.
+# Copyright (C) 2026 Sarah Hoffmann <lonvia at denofr.de> and others.
# For a full list of authors see the git log.
""" Helper functions to communicate with replication servers.
"""
@@ -64,8 +64,7 @@ class ReplicationServer:
state. If the replication service serves something other
than osc.gz files, set the `diff_type` to the given file suffix.
"""
-
- self.baseurl = url
+ self.baseurl = url.rstrip('/') + '/'
self.diff_type = diff_type
self.extra_request_params: Dict[str, Any] = dict(timeout=60, stream=True)
self.session: Optional[requests.Session] = None
@@ -484,15 +483,15 @@ class ReplicationServer:
service.
"""
if seq is None:
- return self.baseurl + '/state.txt'
+ return self.baseurl + 'state.txt'
- return '%s/%03i/%03i/%03i.state.txt' % \
+ return '%s%03i/%03i/%03i.state.txt' % \
(self.baseurl, seq / 1000000, (seq % 1000000) / 1000, seq % 1000)
def get_diff_url(self, seq: int) -> str:
""" Returns the URL to the diff file for the given sequence id.
"""
- return '%s/%03i/%03i/%03i.%s' % \
+ return '%s%03i/%03i/%03i.%s' % \
(self.baseurl,
seq / 1000000, (seq % 1000000) / 1000, seq % 1000,
self.diff_type)
=====================================
src/osmium/replication/utils.py
=====================================
@@ -2,7 +2,7 @@
#
# This file is part of pyosmium. (https://osmcode.org/pyosmium/)
#
-# Copyright (C) 2025 Sarah Hoffmann <lonvia at denofr.de> and others.
+# Copyright (C) 2026 Sarah Hoffmann <lonvia at denofr.de> and others.
# For a full list of authors see the git log.
""" Helper functions for change file handling. """
from typing import NamedTuple, Optional
@@ -57,7 +57,7 @@ def get_replication_header(fname: str) -> ReplicationHeader:
LOG.warning("Sequence id '%d' in OSM file header is negative. Ignored.", seq)
seq = None
except ValueError:
- LOG.warning("Sequence id '%s' in OSM file header is not a number. Ignored.", seq)
+ LOG.warning("Sequence id '%s' in OSM file header is not a number. Ignored.", seqstr)
seq = None
else:
seq = None
=====================================
test/test_constructor_interruption.py
=====================================
@@ -0,0 +1,54 @@
+# SPDX-License-Identifier: BSD-2-Clause
+#
+# This file is part of pyosmium. (https://osmcode.org/pyosmium/)
+# Copyright (C) 2026 Sarah Hoffmann <lonvia at denofr.de> and others.
+# For a full list of authors see the git log.
+import multiprocessing
+import sys
+
+import pytest
+import osmium
+
+
+def run_interrupted_read(pipe, object_type, opl, exception_type):
+ constructor = object_type.__init__.__code__
+
+ def fail_constructor(frame, event, arg):
+ if event == 'call' and frame.f_code is constructor:
+ sys.settrace(None)
+ raise exception_type('injected constructor failure')
+ return fail_constructor
+
+ sys.settrace(fail_constructor)
+ try:
+ list(osmium.FileProcessor(osmium.io.FileBuffer(opl.encode('utf-8'), 'opl')))
+ except exception_type:
+ sys.settrace(None)
+ pipe.send(str(exception_type))
+ else:
+ pipe.send('constructor was not reached')
+
+
+ at pytest.mark.thread_unsafe
+ at pytest.mark.parametrize('object_type', [osmium.osm.Node, osmium.osm.Way, osmium.osm.Relation])
+ at pytest.mark.parametrize('exception', [KeyboardInterrupt, MemoryError, RuntimeError])
+def test_constructor_exception_does_not_crash_cleanup(to_opl, object_type, exception):
+ data = to_opl("""\
+ n1 x5 y5
+ w1 Nn1,n2
+ r1 Mn1@
+ """)
+
+ parent_conn, child_conn = multiprocessing.Pipe()
+ ctx = multiprocessing.get_context('spawn')
+ p = ctx.Process(target=run_interrupted_read,
+ args=[child_conn, object_type, data, exception])
+ p.start()
+
+ assert parent_conn.poll(2)
+ assert parent_conn.recv() == str(exception)
+
+ p.join(2)
+
+ assert p.exitcode == 0, f"Segmentation fault ({-p.exitcode})" if p.exitcode < 0 \
+ else f"Test exited with error {p.exitcode}"
=====================================
test/test_merge_input_reader.py
=====================================
@@ -99,3 +99,79 @@ def test_multibuffer_simplify(adder, tmp_path):
mir.apply(h, simplify=True)
assert h.data == ['N1/1', 'N2/1', 'W3/2']
+
+
+def test_simplify_same_id_different_object(tmp_path):
+ mir = osmium.MergeInputReader()
+
+ opls = ["""\
+ n1 v1 x1 y1
+ n2 v1 x90 y45
+ w1 v1 Nn1,n2
+ r1 v1 Mw1@
+ """,
+ """\
+ r1 v2 Mw1@ Thello=world
+ """]
+
+ for opl in opls:
+ add_as_file(mir, opl, tmp_path)
+
+ h = ListHandler()
+ mir.apply(h, simplify=True)
+
+ assert h.data == ['N1/1', 'N2/1', 'W1/1', 'R1/2']
+
+
+def test_apply_to_reader_nohistory(test_data, tmp_path):
+ fn = test_data("""\
+ n1 v1 x1 y1
+ n2 v1 x90 y45
+ w1 v1 Nn1,n2
+ r1 v1 Mw1@
+ """)
+
+ outfn = tmp_path / 'outfile_apply_to_reader_nohistory.opl'
+
+ reader = osmium.io.Reader(fn)
+ writer = osmium.io.Writer(outfn)
+
+ mir = osmium.MergeInputReader()
+ add_as_buffer(mir, "r1 v2 Mw1@ Thello=world", tmp_path)
+
+ mir.apply_to_reader(reader, writer, False)
+
+ reader.close()
+ writer.close()
+
+ h = ListHandler()
+ osmium.apply(outfn, h)
+
+ assert h.data == ['N1/1', 'N2/1', 'W1/1', 'R1/2']
+
+
+def test_apply_to_reader_with_history(test_data, tmp_path):
+ fn = test_data("""\
+ n1 v1 x1 y1
+ n2 v1 x90 y45
+ w1 v1 Nn1,n2
+ r1 v1 Mw1@
+ """)
+
+ outfn = tmp_path / 'outfile_apply_to_reader_nohistory.opl'
+
+ reader = osmium.io.Reader(fn)
+ writer = osmium.io.Writer(outfn)
+
+ mir = osmium.MergeInputReader()
+ add_as_buffer(mir, "r1 v2 Mw1@ Thello=world", tmp_path)
+
+ mir.apply_to_reader(reader, writer, True)
+
+ reader.close()
+ writer.close()
+
+ h = ListHandler()
+ osmium.apply(outfn, h)
+
+ assert h.data == ['N1/1', 'N2/1', 'W1/1', 'R1/1', 'R1/2']
=====================================
test/test_replication.py
=====================================
@@ -2,7 +2,7 @@
#
# This file is part of pyosmium. (https://osmcode.org/pyosmium/)
#
-# Copyright (C) 2025 Sarah Hoffmann <lonvia at denofr.de> and others.
+# Copyright (C) 2026 Sarah Hoffmann <lonvia at denofr.de> and others.
# For a full list of authors see the git log.
import logging
import time
@@ -22,30 +22,52 @@ import osmium.replication
pytestmark = [pytest.mark.thread_unsafe, pytest.mark.iterations(1)]
- at pytest.mark.parametrize("inp,outp", [
- (None, 'https://text.org/state.txt'),
- (1, 'https://text.org/000/000/001.state.txt'),
- (999, 'https://text.org/000/000/999.state.txt'),
- (1000, 'https://text.org/000/001/000.state.txt'),
- (573923, 'https://text.org/000/573/923.state.txt'),
- (3290012, 'https://text.org/003/290/012.state.txt'),
+ at pytest.mark.parametrize("baseurl,inp,outp", [
+ ("https://text.org", None, 'https://text.org/state.txt'),
+ ("https://text.org", 1, 'https://text.org/000/000/001.state.txt'),
+ ("https://text.org", 999, 'https://text.org/000/000/999.state.txt'),
+ ("https://text.org", 1000, 'https://text.org/000/001/000.state.txt'),
+ ("https://text.org", 573923, 'https://text.org/000/573/923.state.txt'),
+ ("https://text.org", 3290012, 'https://text.org/003/290/012.state.txt'),
+
+ ("https://text.org/", None, 'https://text.org/state.txt'),
+ ("https://text.org/", 1, 'https://text.org/000/000/001.state.txt'),
+ ("https://text.org//", None, 'https://text.org/state.txt'),
+ ("https://text.org//", 1, 'https://text.org/000/000/001.state.txt'),
+
+ ("https://text.org/area-updates", None,
+ 'https://text.org/area-updates/state.txt'),
+ ("https://text.org/area-updates", 3290012,
+ 'https://text.org/area-updates/003/290/012.state.txt'),
+ ("https://text.org/area-updates/", None,
+ 'https://text.org/area-updates/state.txt'),
+ ("https://text.org/area-updates/", 3290012,
+ 'https://text.org/area-updates/003/290/012.state.txt'),
+ ("https://text.org/area-updates//", None,
+ 'https://text.org/area-updates/state.txt'),
+ ("https://text.org/area-updates//", 3290012,
+ 'https://text.org/area-updates/003/290/012.state.txt'),
+ ("https://text.org/area-updates///", 3290012,
+ 'https://text.org/area-updates/003/290/012.state.txt'),
])
-def test_get_state_url(inp, outp):
- svr = rserv.ReplicationServer("https://text.org")
+def test_get_state_url(baseurl, inp, outp):
+ svr = rserv.ReplicationServer(baseurl)
assert outp == svr.get_state_url(inp)
- at pytest.mark.parametrize("inp,outp", [
- (1, 'https://who.is/me//000/000/001.osc.gz'),
- (500, 'https://who.is/me//000/000/500.osc.gz'),
- (83750, 'https://who.is/me//000/083/750.osc.gz'),
- (999999999, 'https://who.is/me//999/999/999.osc.gz'),
+ at pytest.mark.parametrize("baseurl,inp,outp", [
+ ("https://who.is/me/", 1, 'https://who.is/me/000/000/001.osc.gz'),
+ ("https://who.is/me/", 500, 'https://who.is/me/000/000/500.osc.gz'),
+ ("https://who.is/me/", 83750, 'https://who.is/me/000/083/750.osc.gz'),
+ ("https://who.is/me/", 999999999, 'https://who.is/me/999/999/999.osc.gz'),
+
+ ("https://who.is/me", 999999999, 'https://who.is/me/999/999/999.osc.gz'),
])
-def test_get_diff_url(inp, outp):
- svr = rserv.ReplicationServer("https://who.is/me/")
+def test_get_diff_url(baseurl, inp, outp):
+ svr = rserv.ReplicationServer(baseurl)
- assert outp, svr.get_diff_url(inp)
+ assert outp == svr.get_diff_url(inp)
@pytest.mark.parametrize("as_string", [True, False])
=====================================
test/test_replication_utils.py
=====================================
@@ -2,8 +2,13 @@
#
# This file is part of pyosmium. (https://osmcode.org/pyosmium/)
#
-# Copyright (C) 2025 Sarah Hoffmann <lonvia at denofr.de> and others.
+# Copyright (C) 2026 Sarah Hoffmann <lonvia at denofr.de> and others.
# For a full list of authors see the git log.
+import logging
+
+import pytest
+
+import osmium
import osmium.replication.utils as rutil
from helpers import mkdate
@@ -20,8 +25,28 @@ def test_get_replication_header_empty(tmp_path):
def test_get_replication_header_full(test_data_dir):
- val = rutil.get_replication_header(str(test_data_dir / 'example-test.pbf'))
+ val = rutil.get_replication_header(test_data_dir / 'example-test.pbf')
assert val.url == 'http://download.geofabrik.de/europe/andorra-updates'
assert val.sequence == 2167
assert val.timestamp == mkdate(2019, 2, 23, 21, 15, 2)
+
+
+ at pytest.mark.parametrize("inseq, error", [("not-a-number", "OSM file header is not a number"),
+ ("-5", "OSM file header is negative")])
+def test_get_replication_header_invalid_sequence(test_data_dir, caplog, monkeypatch,
+ inseq, error):
+ h = osmium.io.Header()
+ h.set("osmosis_replication_base_url", "https://example.com/replication")
+ h.set("osmosis_replication_sequence_number", inseq)
+ h.set("osmosis_replication_timestamp", "2024-01-01T00:00:00Z")
+
+ monkeypatch.setattr(osmium.io.Reader, "header", lambda _: h)
+
+ with caplog.at_level(logging.WARNING, logger='pyosmium'):
+ val = rutil.get_replication_header(test_data_dir / 'example-test.pbf')
+
+ assert val.url == 'https://example.com/replication'
+ assert val.sequence is None
+ assert val.timestamp == mkdate(2024, 1, 1, 0, 0, 0)
+ assert error in caplog.text
View it on GitLab: https://salsa.debian.org/debian-gis-team/pyosmium/-/compare/f63390e45de1443e5c265afa273e5cb27e87d46f...88f6673bc901d6f19a033c01348e3f9dc7e7e611
--
View it on GitLab: https://salsa.debian.org/debian-gis-team/pyosmium/-/compare/f63390e45de1443e5c265afa273e5cb27e87d46f...88f6673bc901d6f19a033c01348e3f9dc7e7e611
You're receiving this email because of your account on salsa.debian.org. Manage all notifications: https://salsa.debian.org/-/profile/notifications | Help: https://salsa.debian.org/help
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://alioth-lists.debian.net/pipermail/pkg-grass-devel/attachments/20261021/8fddc3b5/attachment-0001.htm>
More information about the Pkg-grass-devel
mailing list