public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
From: Benjamin A. Beasley <code@musicinmybrain.net>
To: git-commits@fedoraproject.org
Subject: [rpms/python-pint] rpmlint-etc: Update to 0.24
Date: Sat, 12 Sep 2026 10:21:56 GMT [thread overview]
Message-ID: <178920851628.1.13442125263129469321.rpms-python-pint-d33feadeb361@fedoraproject.org> (raw)
A new commit has been pushed.
Repo : rpms/python-pint
Branch : rpmlint-etc
Commit : d33feadeb3610027ed3a343734461f539c07c0e7
Author : Benjamin A. Beasley <code@musicinmybrain.net>
Date : 2024-06-14T09:20:23-04:00
Stats : +181/-284 in 9 file(s)
URL : https://src.fedoraproject.org/rpms/python-pint/c/d33feadeb3610027ed3a343734461f539c07c0e7?branch=rpmlint-etc
Log:
Update to 0.24
- Unbundle python-flexparser
---
diff --git a/.gitignore b/.gitignore
index af50669..7a7e6db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,10 @@
/Pint-0.17.tar.gz
/Pint-0.19.tar.gz
/Pint-0.19.2.tar.gz
+/Pint-0.20.tar.gz
+/Pint-0.20.1.tar.gz
+/Pint-0.21.tar.gz
+/Pint-0.21.1.tar.gz
+/Pint-0.22.tar.gz
+/Pint-0.23.tar.gz
+/pint-0.24.tar.gz
diff --git a/0001-Downstream-only-Backport-fix-for-importlib.resources.patch b/0001-Downstream-only-Backport-fix-for-importlib.resources.patch
deleted file mode 100644
index c17d6b0..0000000
--- a/0001-Downstream-only-Backport-fix-for-importlib.resources.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 3cce96928581d5888f4f0b8a7b4ed07e49bcb2e7 Mon Sep 17 00:00:00 2001
-From: "Benjamin A. Beasley" <code@musicinmybrain.net>
-Date: Thu, 4 Jan 2024 08:32:17 -0500
-Subject: [PATCH] Downstream-only: Backport fix for importlib.resources.path
- removal
-
-Imitate current versions of flexparser, which was split out as a
-separate library in later releases of pint.
----
- pint/parser.py | 4 +++-
- 1 file changed, 3 insertions(+), 1 deletion(-)
-
-diff --git a/pint/parser.py b/pint/parser.py
-index e73e578..e1127a2 100644
---- a/pint/parser.py
-+++ b/pint/parser.py
-@@ -261,7 +261,9 @@ class Parser:
- it will use python importlib.resources.read_binary
- """
-
-- with resources.path(__package__, resource_name) as p:
-+ with resources.as_file(
-+ resources.files(__package__).joinpath(resource_name)
-+ )as p:
- filepath = p.resolve()
-
- if filepath.exists():
---
-2.43.0
-
diff --git a/0001-Minimal-patch-for-compatibility-with-pytest-8.patch b/0001-Minimal-patch-for-compatibility-with-pytest-8.patch
deleted file mode 100644
index 71cac90..0000000
--- a/0001-Minimal-patch-for-compatibility-with-pytest-8.patch
+++ /dev/null
@@ -1,67 +0,0 @@
-From 855ccd6448d06977f2911d9182d946e8206bae6c Mon Sep 17 00:00:00 2001
-From: =?UTF-8?q?Tom=C3=A1=C5=A1=20Hrn=C4=8Diar?= <thrnciar@redhat.com>
-Date: Thu, 18 Apr 2024 11:47:23 +0200
-Subject: [PATCH] Minimal patch for compatibility with pytest 8
-
-Inspired from upstream commit which does not apply to pint version we
-have in Fedora
-https://github.com/hgrecco/pint/commit/ba5fb6566dcefc1d7d34dfde48e498d69da05347
----
- pint/quantity.py | 9 ++++-----
- pint/testing.py | 8 ++++----
- 2 files changed, 8 insertions(+), 9 deletions(-)
-
-diff --git a/pint/quantity.py b/pint/quantity.py
-index 1207b94..2cdb699 100644
---- a/pint/quantity.py
-+++ b/pint/quantity.py
-@@ -824,12 +824,11 @@ class Quantity(PrettyIPython, SharedRegistryObject, Generic[_MagnitudeType]):
- """
-
- if not isinstance(self.magnitude, numbers.Number):
-- msg = (
-- "to_compact applied to non numerical types "
-- "has an undefined behavior."
-+ warnings.warn(
-+ "to_compact applied to non numerical types has an undefined behavior.",
-+ RuntimeWarning,
-+ stacklevel=2,
- )
-- w = RuntimeWarning(msg)
-- warnings.warn(w, stacklevel=2)
- return self
-
- if (
-diff --git a/pint/testing.py b/pint/testing.py
-index 3334675..485a29d 100644
---- a/pint/testing.py
-+++ b/pint/testing.py
-@@ -42,10 +42,10 @@ def assert_equal(first, second, msg=None):
- if isinstance(m1, ndarray) or isinstance(m2, ndarray):
- np.testing.assert_array_equal(m1, m2, err_msg=msg)
- elif not isinstance(m1, Number):
-- warnings.warn(RuntimeWarning)
-+ warnings.warn("In assert_equal, m1 is not a number ", RuntimeWarning)
- return
- elif not isinstance(m2, Number):
-- warnings.warn(RuntimeWarning)
-+ warnings.warn("In assert_equal, m2 is not a number ", RuntimeWarning)
- return
- elif math.isnan(m1):
- assert math.isnan(m2), msg
-@@ -71,10 +71,10 @@ def assert_allclose(first, second, rtol=1e-07, atol=0, msg=None):
- if isinstance(m1, ndarray) or isinstance(m2, ndarray):
- np.testing.assert_allclose(m1, m2, rtol=rtol, atol=atol, err_msg=msg)
- elif not isinstance(m1, Number):
-- warnings.warn(RuntimeWarning)
-+ warnings.warn("In assert_equal, m1 is not a number ", RuntimeWarning)
- return
- elif not isinstance(m2, Number):
-- warnings.warn(RuntimeWarning)
-+ warnings.warn("In assert_equal, m2 is not a number ", RuntimeWarning)
- return
- elif math.isnan(m1):
- assert math.isnan(m2), msg
---
-2.44.0
-
diff --git a/0001-add-min-and-max-to-the-array-function-overrides.patch b/0001-add-min-and-max-to-the-array-function-overrides.patch
deleted file mode 100644
index 90d4b19..0000000
--- a/0001-add-min-and-max-to-the-array-function-overrides.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 9ace880dfa2a57772f1c2cac1316338995baf1fb Mon Sep 17 00:00:00 2001
-From: Justus Magin <keewis@posteo.de>
-Date: Tue, 7 Mar 2023 13:24:37 +0100
-Subject: [PATCH] add `min` and `max` to the array function overrides
-
----
- pint/numpy_func.py | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/pint/numpy_func.py b/pint/numpy_func.py
-index e09decb..ccc99b9 100644
---- a/pint/numpy_func.py
-+++ b/pint/numpy_func.py
-@@ -805,6 +805,8 @@ for func_str, unit_arguments, wrap_output in [
- ("broadcast_to", ["array"], True),
- ("amax", ["a", "initial"], True),
- ("amin", ["a", "initial"], True),
-+ ("max", ["a", "initial"], True),
-+ ("min", ["a", "initial"], True),
- ("searchsorted", ["a", "v"], False),
- ("isclose", ["a", "b"], False),
- ("nan_to_num", ["x", "nan", "posinf", "neginf"], True),
---
-2.41.0
-
diff --git a/955102b318a4ecc34afd0f366e826ef174fe647b.patch b/955102b318a4ecc34afd0f366e826ef174fe647b.patch
deleted file mode 100644
index 83fce2f..0000000
--- a/955102b318a4ecc34afd0f366e826ef174fe647b.patch
+++ /dev/null
@@ -1,59 +0,0 @@
-From 955102b318a4ecc34afd0f366e826ef174fe647b Mon Sep 17 00:00:00 2001
-From: xtreak <tir.karthi@gmail.com>
-Date: Sat, 29 Jun 2019 04:58:59 +0000
-Subject: [PATCH] Use context manager for assertWarns and fix
- DeprecationWarning
-
----
- pint/testsuite/parameterized.py | 7 ++++++-
- pint/testsuite/test_quantity.py | 5 +++--
- 2 files changed, 9 insertions(+), 3 deletions(-)
-
-diff --git a/pint/testsuite/parameterized.py b/pint/testsuite/parameterized.py
-index 9b920373..7c459157 100644
---- a/pint/testsuite/parameterized.py
-+++ b/pint/testsuite/parameterized.py
-@@ -32,6 +32,11 @@
- import collections
- import unittest
-
-+try:
-+ from collections.abc import Callable
-+except ImportError:
-+ from collections import Callable
-+
- def add_metaclass(metaclass):
- """Class decorator for creating a class with a metaclass."""
- def wrapper(cls):
-@@ -69,7 +74,7 @@ def __new__(meta, classname, bases, class_dict):
- new_class_dict = {}
-
- for attr_name, attr_value in list(class_dict.items()):
-- if isinstance(attr_value, collections.Callable) and hasattr(attr_value, 'param_names'):
-+ if isinstance(attr_value, Callable) and hasattr(attr_value, 'param_names'):
- # print("Processing attr_name = %r; attr_value = %r" % (
- # attr_name, attr_value))
-
-diff --git a/pint/testsuite/test_quantity.py b/pint/testsuite/test_quantity.py
-index fdb24600..232eea2c 100644
---- a/pint/testsuite/test_quantity.py
-+++ b/pint/testsuite/test_quantity.py
-@@ -383,7 +383,7 @@ def test_from_sequence(self):
- self.assertFalse(u_array_2.u == u_array_ref_reversed.u)
-
- u_array_3 = self.Q_.from_sequence(u_seq_reversed, units='g')
-- self.assertTrue(all(u_array_3 == u_array_ref_reversed))
-+ self.assertTrue(all(u_array_3 == u_array_ref_reversed))
- self.assertTrue(u_array_3.u == u_array_ref_reversed.u)
-
- with self.assertRaises(ValueError):
-@@ -454,7 +454,8 @@ def test_limits_magnitudes(self):
- def test_nonnumeric_magnitudes(self):
- ureg = self.ureg
- x = "some string"*ureg.m
-- self.assertRaises(RuntimeError, self.compareQuantity_compact(x,x))
-+ with self.assertWarns(RuntimeWarning):
-+ self.compareQuantity_compact(x,x)
-
- class TestQuantityBasicMath(QuantityTestCase):
-
diff --git a/b3b18277ecc682bff7ca1fa9e48992f7ec68e47f.patch b/b3b18277ecc682bff7ca1fa9e48992f7ec68e47f.patch
deleted file mode 100644
index c1ff95d..0000000
--- a/b3b18277ecc682bff7ca1fa9e48992f7ec68e47f.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From b3b18277ecc682bff7ca1fa9e48992f7ec68e47f Mon Sep 17 00:00:00 2001
-From: Hernan Grecco <hgrecco@gmail.com>
-Date: Wed, 12 Jul 2023 20:39:13 -0300
-Subject: [PATCH] Fix test as NumPy 1.25 changes the rules for equality
- operator
-
----
- pint/testsuite/test_quantity.py | 5 ++++-
- 1 file changed, 4 insertions(+), 1 deletion(-)
-
-diff --git a/pint/testsuite/test_quantity.py b/pint/testsuite/test_quantity.py
-index 1843b69ca..7efe74f80 100644
---- a/pint/testsuite/test_quantity.py
-+++ b/pint/testsuite/test_quantity.py
-@@ -1906,7 +1906,10 @@ def test_equal_zero_nan_NP(self):
- self.Q_([0, 1, 2], "J") == np.array([0, 0, np.nan]),
- np.asarray([True, False, False]),
- )
-- assert not (self.Q_(np.arange(4), "J") == np.zeros(3))
-+
-+ # This raise an exception on NumPy 1.25 as dimensions
-+ # are different
-+ # assert not (self.Q_(np.arange(4), "J") == np.zeros(3))
-
- def test_offset_equal_zero(self):
- ureg = self.ureg
diff --git a/dataclass-frozen.patch b/dataclass-frozen.patch
new file mode 100644
index 0000000..2712027
--- /dev/null
+++ b/dataclass-frozen.patch
@@ -0,0 +1,104 @@
+diff --git a/pint/errors.py b/pint/errors.py
+index 59d3b45..f080f52 100644
+--- a/pint/errors.py
++++ b/pint/errors.py
+@@ -81,12 +81,12 @@ class WithDefErr:
+ return DefinitionError(self.name, self.__class__, msg)
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class PintError(Exception):
+ """Base exception for all Pint errors."""
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class DefinitionError(ValueError, PintError):
+ """Raised when a definition is not properly constructed."""
+
+@@ -102,7 +102,7 @@ class DefinitionError(ValueError, PintError):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class DefinitionSyntaxError(ValueError, PintError):
+ """Raised when a textual definition has a syntax error."""
+
+@@ -115,7 +115,7 @@ class DefinitionSyntaxError(ValueError, PintError):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class RedefinitionError(ValueError, PintError):
+ """Raised when a unit or prefix is redefined."""
+
+@@ -130,7 +130,7 @@ class RedefinitionError(ValueError, PintError):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class UndefinedUnitError(AttributeError, PintError):
+ """Raised when the units are not defined in the unit registry."""
+
+@@ -150,13 +150,13 @@ class UndefinedUnitError(AttributeError, PintError):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class PintTypeError(TypeError, PintError):
+ def __reduce__(self):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class DimensionalityError(PintTypeError):
+ """Raised when trying to convert between incompatible units."""
+
+@@ -183,7 +183,7 @@ class DimensionalityError(PintTypeError):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class OffsetUnitCalculusError(PintTypeError):
+ """Raised on ambiguous operations with offset units."""
+
+@@ -208,7 +208,7 @@ class OffsetUnitCalculusError(PintTypeError):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class LogarithmicUnitCalculusError(PintTypeError):
+ """Raised on inappropriate operations with logarithmic units."""
+
+@@ -233,7 +233,7 @@ class LogarithmicUnitCalculusError(PintTypeError):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class UnitStrippedWarning(UserWarning, PintError):
+ msg: str
+
+@@ -241,13 +241,13 @@ class UnitStrippedWarning(UserWarning, PintError):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class UnexpectedScaleInContainer(Exception):
+ def __reduce__(self):
+ return self.__class__, tuple(getattr(self, f.name) for f in fields(self))
+
+
+-@dataclass(frozen=False)
++@dataclass(frozen=True)
+ class UndefinedBehavior(UserWarning, PintError):
+ msg: str
diff --git a/python-pint.spec b/python-pint.spec
index 3307f42..7325ab8 100644
--- a/python-pint.spec
+++ b/python-pint.spec
@@ -1,51 +1,27 @@
+# Broken on Python 3.13: https://bugzilla.redhat.com/show_bug.cgi?id=2291978
+%bcond xarray %{expr: 0%{?fedora} != 41}
+# Broken on Python 3.13: https://bugzilla.redhat.com/show_bug.cgi?id=2291664
+%bcond dask %{expr: 0%{?fedora} != 41}
+# Not yet packaged: python-uncertainties
+%bcond uncertainties 0
+# Requires babel <= 2.8; F41 has 2.15.0
+%bcond babel 0
+# Not yet packaged: python-pint-pandas
+%bcond pandas 0
+# Not yet packaged: python-mip
+%bcond mip 0
+
Name: python-pint
-Version: 0.19.2
+Version: 0.24
Release: %autorelease
Summary: Physical quantities module
-# The entire source is BSD-3-Clause, except:
-# - pint/_vendor/appdirs.py is MIT, but is unbundled in %%prep
-# - pint/_vendor/flexcache.py is also BSD-3-Clause, but is unbundled in
-# %%prep
License: BSD-3-Clause
URL: https://github.com/hgrecco/pint
-Source0: %{pypi_source Pint}
-
-# Fix test as NumPy 1.25 changes the rules for equality operator
-# https://github.com/hgrecco/pint/commit/b3b18277ecc682bff7ca1fa9e48992f7ec68e47f
-#
-# Fixes:
-#
-# test_equal_zero_nan_NP fails with numpy 1.25.1
-# https://github.com/hgrecco/pint/issues/1825
-Patch: %{url}/commit/b3b18277ecc682bff7ca1fa9e48992f7ec68e47f.patch
-
-# add min and max to the array function overrides
-# https://github.com/hgrecco/pint/commit/1b2b0592f88a1c9fdf9b5649ebade19fa81adea4
-#
-# Fixes several failures in TestNumpyUnclassified
-#
-# Cherry-picked to 0.19.
-Patch: 0001-add-min-and-max-to-the-array-function-overrides.patch
-
-# Downstream-only: Backport fix for importlib.resources.path removal
-#
-# Imitate current versions of flexparser, which was split out as a
-# separate library in later releases of pint.
-#
-# This is resolved in current upstream releases of pint; see
-# https://src.fedoraproject.org/rpms/python-pint/pull-request/10.
-#
-# Fixes:
-#
-# python-pint fails to build with Python 3.13: AttributeError: module
-# 'importlib.resources' has no attribute 'path'
-# https://bugzilla.redhat.com/show_bug.cgi?id=2256746
-Patch: 0001-Downstream-only-Backport-fix-for-importlib.resources.patch
-
-# Compatibility with pytest 8
-# https://github.com/hgrecco/pint/commit/ba5fb6566d.patch
-Patch: 0001-Minimal-patch-for-compatibility-with-pytest-8.patch
+Source: %{pypi_source pint}
+
+# Workaround from https://github.com/hgrecco/pint/issues/1969
+Patch: dataclass-frozen.patch
BuildArch: noarch
@@ -64,55 +40,72 @@ Summary: %{summary}
%description -n python3-pint %{_description}
-# We omit the “uncertainties” extra because python-uncertainties is not yet
-# packaged.
%pyproject_extras_subpkg -n python3-pint numpy
+%if %{with xarray}
+%pyproject_extras_subpkg -n python3-pint xarray
+%endif
+%if %{with dask}
+%pyproject_extras_subpkg -n python3-pint dask
+%endif
+%if %{with uncertainties}
+%pyproject_extras_subpkg -n python3-pint uncertainties
+%endif
+%if %{with babel}
+%pyproject_extras_subpkg -n python3-pint babel
+%endif
+%if %{with pandas}
+%pyproject_extras_subpkg -n python3-pint pandas
+%endif
+%if %{with mip}
+%pyproject_extras_subpkg -n python3-pint mip
+%endif
%prep
-%autosetup -n Pint-%{version} -p1
-
-# We are not sure where this was bundled from, but we are pretty sure it was
-# bundled from somewhere! We are not building HTML documentation, so we do not
-# need it.
-rm -rvf docs/_themes
+%autosetup -n pint-%{version} -p1
# https://docs.fedoraproject.org/en-US/packaging-guidelines/Python/#_linters
-sed -r -i '/pytest-cov/d' setup.cfg
-
-# Unbundle python-appdirs
-# http://github.com/ActiveState/appdirs
-# Provides: bundled(python3dist(appdirs)) = 1.4.4
-rm -vf pint/_vendor/appdirs.py
-# Unbundle python-flexcache
-# https://github.com/hgrecco/flexcache
-# Provides: bundled(python3dist(flexcache)) = 0.2
-rm -vf pint/_vendor/flexcache.py
-# Add devendored dependencies back in as regular dependencies
-sed -r -i 's/^setup_requires/install_requires = appdirs; flexcache\n&/' \
- setup.cfg
-# The find-then-modify pattern keeps us from discarding mtimes on sources that
-# do not need modification.
-find pint -type f -exec \
- gawk '/^from (\.*|pint)\._vendor import (appdirs|flexcache)/ {
- print FILENAME; nextfile }' '{}' '+' |
- xargs -r -t sed -r -i \
- -e 's/^from (\.*|pint)\._vendor (import (appdirs))/\2/' \
- -e 's/^(from )(\.*|pint)\._vendor( import (flexcache))/\1\4\3/'
+sed -r -i '/pytest-cov/d' pyproject.toml
+
+# This module is executable in the source, and it might make sense for upstream
+# to run it directly as a script during development, but this package will
+# install it in site-packages without the executable bit set, so it doesn’t
+# make sense for it to have a shebang. Package users will run it via the
+# generated pint-convert entry point instead.
+sed -r -i '1{/^#!/d}' pint/pint_convert.py
%generate_buildrequires
-# We omit the “uncertainties” extra because python-uncertainties is not yet
-# packaged.
-%pyproject_buildrequires -x numpy,test
+%{pyproject_buildrequires \
+ -x numpy \
+%if %{with uncertainties}
+ -x uncertainties \
+%endif
+%if %{with babel}
+ -x babel \
+%endif
+%if %{with pandas}
+ -x pandas \
+%endif
+%if %{with xarray}
+ -x xarray \
+%endif
+%if %{with dask}
+ -x dask \
+%endif
+%if %{with mip}
+ -x mip \
+%endif
+ -x test}
%build
%pyproject_wheel
%install
%pyproject_install
-%pyproject_save_files pint
+%pyproject_save_files -l pint
%check
-%pytest
+# -rs: print reasons for skipped tests
+%pytest -rs
%files -n python3-pint -f %{pyproject_files}
%{_bindir}/pint-convert
diff --git a/sources b/sources
index f06e847..79c12b1 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (Pint-0.19.2.tar.gz) = 9f4a00142159d298bf09fdc8ed2c4367a9ef2328663466b43bb4fbc31361c4fa63b1f0d5dec6a71fc5e50ddff22cb86e37abac5e75a13569c5332bb52884c7ee
+SHA512 (pint-0.24.tar.gz) = dbc47d272d321a0ded6ec94a6913036b246fd4c24425f8a0fbd8a0df987c51ebe7db34295f4ff6960eb4fb91dc921af9b8f405f7c52996f66f349e3eded9be04
reply other threads:[~2026-09-12 10:21 UTC|newest]
Thread overview: [no followups] expand[flat|nested] mbox.gz Atom feed
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=178920851628.1.13442125263129469321.rpms-python-pint-d33feadeb361@fedoraproject.org \
--to=code@musicinmybrain.net \
--cc=git-commits@fedoraproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox