summaryrefslogtreecommitdiff
path: root/dev-python/time-machine
diff options
context:
space:
mode:
authorroot <root@alpha.trunkmasters.com>2026-08-01 03:04:37 -0500
committerroot <root@alpha.trunkmasters.com>2026-08-01 03:04:37 -0500
commit6344ec0d45ab5c6dc7f52b9c7ba2a4fdfa37fb17 (patch)
tree782b1dfa8abee9f15c2fff2aca667b4abd32e5f8 /dev-python/time-machine
parent3f283d6a71e35a9c6d89dc73d76f01aec1c1a6b3 (diff)
downloadbaldeagleos-repo-6344ec0d45ab5c6dc7f52b9c7ba2a4fdfa37fb17.tar.gz
baldeagleos-repo-6344ec0d45ab5c6dc7f52b9c7ba2a4fdfa37fb17.tar.xz
baldeagleos-repo-6344ec0d45ab5c6dc7f52b9c7ba2a4fdfa37fb17.zip
Adding metadata
Diffstat (limited to 'dev-python/time-machine')
-rw-r--r--dev-python/time-machine/Manifest1
-rw-r--r--dev-python/time-machine/files/time-machine-3.2.0-py3.15.patch237
-rw-r--r--dev-python/time-machine/time-machine-3.2.0-r1.ebuild40
-rw-r--r--dev-python/time-machine/time-machine-3.3.0.ebuild36
4 files changed, 314 insertions, 0 deletions
diff --git a/dev-python/time-machine/Manifest b/dev-python/time-machine/Manifest
index 45a538265faf..7c9a57613faf 100644
--- a/dev-python/time-machine/Manifest
+++ b/dev-python/time-machine/Manifest
@@ -1 +1,2 @@
DIST time-machine-3.2.0.gh.tar.gz 85884 BLAKE2B dc771f17c8089a6f121cf99ad8dcf5f0e9aaec345dbdfb0be4ccfc9123b10561cebc116dd9db6d1b4c939cf49fa80e16d8be75e9adfe394ad5392dc1dfe2c12c SHA512 84ff8d2e9c9bdde90efe3548bc151f38f812a4ba624cc9556dd2a89f72d664d73dca8be64a65ca2a5019393e5a8f91e130804313685b23dccc4932a9e05f973b
+DIST time-machine-3.3.0.gh.tar.gz 97144 BLAKE2B e1bc1dd87196a060ff55ab92f720e47bb4d66a4475863cfd6e53d7e18bc3d8c80c9df1fb7be70f93d5282287a95676b66a9542d6662a3c43729c8619adf60102 SHA512 593910cb9690c413724babd1d86547515bbcd4291683dd06a2181b6900c67893b8d97f7345f7e1f76349ea7fdd4840a093245131cf2462a1780db345acc5c182
diff --git a/dev-python/time-machine/files/time-machine-3.2.0-py3.15.patch b/dev-python/time-machine/files/time-machine-3.2.0-py3.15.patch
new file mode 100644
index 000000000000..3c45ec3aff0b
--- /dev/null
+++ b/dev-python/time-machine/files/time-machine-3.2.0-py3.15.patch
@@ -0,0 +1,237 @@
+https://github.com/adamchainz/time-machine/issues/610
+https://github.com/adamchainz/time-machine/pull/618
+https://github.com/adamchainz/time-machine/commit/83c385186424c920228cd38d819f2488de617be2
+
+From 83c385186424c920228cd38d819f2488de617be2 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Lum=C3=ADr=20=27Frenzy=27=20Balhar?=
+ <frenzy.madness@gmail.com>
+Date: Wed, 29 Jul 2026 23:52:51 +0200
+Subject: [PATCH] Mock `datetime.date.today()` directly (#618)
+
+Co-authored-by: Adam Johnson <me@adamj.eu>
+--- a/docs/usage.rst
++++ b/docs/usage.rst
+@@ -89,7 +89,9 @@ Main API
+
+ All datetime functions in the standard library are mocked to move to the destination current datetime:
+
++ * ``datetime.date.today()``
+ * ``datetime.datetime.now()``
++ * ``datetime.datetime.today()``
+ * ``datetime.datetime.utcnow()``
+ * ``time.clock_gettime()`` (only for ``CLOCK_REALTIME``)
+ * ``time.clock_gettime_ns()`` (only for ``CLOCK_REALTIME``)
+@@ -355,6 +357,8 @@ Main API
+ with time_machine.travel(...):
+ ...
+
++.. _escape-hatch:
++
+ Escape hatch API
+ ================
+
+@@ -373,10 +377,18 @@ The functions are:
+
+ Returns ``True`` if ``time_machine.travel()`` is active, ``False`` otherwise.
+
++* ``escape_hatch.datetime.date.today()``
++
++ Wraps the real ``datetime.date.today()``.
++
+ * ``escape_hatch.datetime.datetime.now()``
+
+ Wraps the real ``datetime.datetime.now()``.
+
++* ``escape_hatch.datetime.datetime.today()``
++
++ Wraps the real ``datetime.datetime.today()``.
++
+ * ``escape_hatch.datetime.datetime.utcnow()``
+
+ Wraps the real ``datetime.datetime.utcnow()``.
+--- a/src/_time_machine.c
++++ b/src/_time_machine.c
+@@ -10,6 +10,7 @@ typedef struct {
+ PyObject *datetime_class;
+ PyCFunctionObject *datetime_datetime_now;
+ PyCFunctionObject *datetime_datetime_utcnow;
++ PyCFunctionObject *date_today;
+ PyCFunctionObject *time_clock_gettime;
+ PyCFunctionObject *time_clock_gettime_ns;
+ PyCFunctionObject *time_gmtime;
+@@ -24,6 +25,7 @@ typedef struct {
+ _PyCFunctionFastWithKeywords original_now;
+ #endif
+ PyCFunction original_utcnow;
++ PyCFunction original_date_today;
+ PyCFunction original_clock_gettime;
+ PyCFunction original_clock_gettime_ns;
+ PyCFunction original_gmtime;
+@@ -130,6 +132,33 @@ PyDoc_STRVAR(original_utcnow_doc,
+ \n\
+ Call datetime.datetime.utcnow() after patching.");
+
++/* datetime.date.today() and datetime.datetime.today()
++ * Note: datetime.datetime doesn't define its own today(), it inherits from date.
++ * So we patch date.today() with a wrapper that calls cls.fromtimestamp(), which
++ * returns the right type for date, datetime, and subclasses of either.
++ */
++
++static PyObject *
++_time_machine_today(PyObject *cls, PyObject *args)
++{
++ PyObject *time_machine_module = PyImport_ImportModule("time_machine");
++ if (time_machine_module == NULL) {
++ return NULL; // Propagate ImportError
++ }
++
++ PyObject *timestamp = PyObject_CallMethod(time_machine_module, "time", NULL);
++ Py_DECREF(time_machine_module);
++ if (timestamp == NULL) {
++ return NULL;
++ }
++
++ PyObject *result = PyObject_CallMethod(cls, "fromtimestamp", "O", timestamp);
++
++ Py_DECREF(timestamp);
++
++ return result;
++}
++
+ /* time.clock_gettime() */
+
+ static PyObject *
+@@ -446,6 +475,9 @@ _time_machine_patch(PyObject *module, PyObject *unused)
+ if (state->original_time)
+ Py_RETURN_NONE;
+
++ state->original_date_today = state->date_today->m_ml->ml_meth;
++ state->date_today->m_ml->ml_meth = _time_machine_today;
++
+ #if PY_VERSION_HEX >= 0x030d00a4
+ state->original_now =
+ (PyCFunctionFastWithKeywords)state->datetime_datetime_now->m_ml->ml_meth;
+@@ -517,6 +549,9 @@ _time_machine_unpatch(PyObject *module, PyObject *unused)
+ state->datetime_datetime_utcnow->m_ml->ml_meth = state->original_utcnow;
+ state->original_utcnow = NULL;
+
++ state->date_today->m_ml->ml_meth = state->original_date_today;
++ state->original_date_today = NULL;
++
+ /*
+ time.clock_gettime(), only available on Unix platforms.
+ */
+@@ -637,6 +672,17 @@ _time_machine_exec(PyObject *module)
+ goto error;
+ }
+
++ PyObject *date_class = PyObject_GetAttrString(state->datetime_module, "date");
++ if (date_class == NULL) {
++ goto error;
++ }
++
++ state->date_today = (PyCFunctionObject *)PyObject_GetAttrString(date_class, "today");
++ Py_DECREF(date_class);
++ if (state->date_today == NULL) {
++ goto error;
++ }
++
+ state->time_module = PyImport_ImportModule("time");
+ if (state->time_module == NULL) {
+ goto error;
+@@ -702,6 +748,7 @@ _time_machine_exec(PyObject *module)
+ Py_CLEAR(state->datetime_class);
+ Py_CLEAR(state->datetime_datetime_now);
+ Py_CLEAR(state->datetime_datetime_utcnow);
++ Py_CLEAR(state->date_today);
+ Py_CLEAR(state->time_module);
+ Py_CLEAR(state->time_clock_gettime);
+ Py_CLEAR(state->time_clock_gettime_ns);
+@@ -721,6 +768,7 @@ _time_machine_traverse(PyObject *module, visitproc visit, void *arg)
+ Py_VISIT(state->datetime_class);
+ Py_VISIT(state->datetime_datetime_now);
+ Py_VISIT(state->datetime_datetime_utcnow);
++ Py_VISIT(state->date_today);
+ Py_VISIT(state->time_module);
+ Py_VISIT(state->time_clock_gettime);
+ Py_VISIT(state->time_clock_gettime_ns);
+@@ -740,6 +788,7 @@ _time_machine_clear(PyObject *module)
+ Py_CLEAR(state->datetime_class);
+ Py_CLEAR(state->datetime_datetime_now);
+ Py_CLEAR(state->datetime_datetime_utcnow);
++ Py_CLEAR(state->date_today);
+ Py_CLEAR(state->time_module);
+ Py_CLEAR(state->time_clock_gettime);
+ Py_CLEAR(state->time_clock_gettime_ns);
+--- a/src/time_machine/__init__.py
++++ b/src/time_machine/__init__.py
+@@ -535,11 +535,23 @@ def time_machine_fixture(
+ # escape hatch
+
+
++class _EscapeHatchDatetimeDate:
++ def today(self) -> dt.date:
++ # date.today() is equivalent to datetime.now().date().
++ result: dt.datetime = _time_machine.original_now(None)
++ return result.date()
++
++
+ class _EscapeHatchDatetimeDatetime:
+ def now(self, tz: dt.tzinfo | None = None) -> dt.datetime:
+ result: dt.datetime = _time_machine.original_now(tz)
+ return result
+
++ def today(self) -> dt.datetime:
++ # datetime.today() is equivalent to datetime.now() without a timezone.
++ result: dt.datetime = _time_machine.original_now(None)
++ return result
++
+ def utcnow(self) -> dt.datetime:
+ result: dt.datetime = _time_machine.original_utcnow()
+ return result
+@@ -547,6 +559,7 @@ def utcnow(self) -> dt.datetime:
+
+ class _EscapeHatchDatetime:
+ def __init__(self) -> None:
++ self.date = _EscapeHatchDatetimeDate()
+ self.datetime = _EscapeHatchDatetimeDatetime()
+
+
+--- a/tests/test_time_machine.py
++++ b/tests/test_time_machine.py
+@@ -1317,6 +1317,17 @@ def test_is_travelling_true(self):
+ with time_machine.travel(EPOCH):
+ assert time_machine.escape_hatch.is_travelling() is True
+
++ def test_date_today(self):
++ real_today = dt.date.today()
++
++ with time_machine.travel(EPOCH):
++ eh_today = time_machine.escape_hatch.datetime.date.today()
++ assert eh_today >= real_today
++
++ with pytest.raises(ValueError) as excinfo:
++ time_machine.escape_hatch.datetime.date.today()
++ assert excinfo.value.args == ("Not currently time-travelling.",)
++
+ def test_datetime_now(self):
+ real_now = dt.datetime.now()
+
+@@ -1335,6 +1346,17 @@ def test_datetime_now_tz(self):
+ eh_now = time_machine.escape_hatch.datetime.datetime.now(tz=dt.timezone.utc)
+ assert eh_now >= real_now
+
++ def test_datetime_today(self):
++ real_today = dt.datetime.today()
++
++ with time_machine.travel(EPOCH):
++ eh_today = time_machine.escape_hatch.datetime.datetime.today()
++ assert eh_today >= real_today
++
++ with pytest.raises(ValueError) as excinfo:
++ time_machine.escape_hatch.datetime.datetime.today()
++ assert excinfo.value.args == ("Not currently time-travelling.",)
++
+ def test_datetime_utcnow(self):
+ real_now = dt.datetime.utcnow()
+
diff --git a/dev-python/time-machine/time-machine-3.2.0-r1.ebuild b/dev-python/time-machine/time-machine-3.2.0-r1.ebuild
new file mode 100644
index 000000000000..ee1d7ac32bf5
--- /dev/null
+++ b/dev-python/time-machine/time-machine-3.2.0-r1.ebuild
@@ -0,0 +1,40 @@
+# Copyright 2022-2026 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DISTUTILS_EXT=1
+DISTUTILS_USE_PEP517=setuptools
+PYTHON_COMPAT=( python3_{13..14} )
+
+inherit distutils-r1
+
+DESCRIPTION="Travel through time in your tests"
+HOMEPAGE="
+ https://github.com/adamchainz/time-machine/
+ https://pypi.org/project/time-machine/
+"
+SRC_URI="
+ https://github.com/adamchainz/time-machine/archive/${PV}.tar.gz
+ -> ${P}.gh.tar.gz
+"
+
+LICENSE="MIT"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86"
+
+BDEPEND="
+ test? (
+ dev-python/freezegun[${PYTHON_USEDEP}]
+ dev-python/python-dateutil[${PYTHON_USEDEP}]
+ dev-python/tokenize-rt[${PYTHON_USEDEP}]
+ )
+"
+
+EPYTEST_PLUGIN_LOAD_VIA_ENV=1
+EPYTEST_PLUGINS=( "${PN}" )
+distutils_enable_tests pytest
+
+PATCHES=(
+ "${FILESDIR}"/time-machine-3.2.0-py3.15.patch
+)
diff --git a/dev-python/time-machine/time-machine-3.3.0.ebuild b/dev-python/time-machine/time-machine-3.3.0.ebuild
new file mode 100644
index 000000000000..289ffff60406
--- /dev/null
+++ b/dev-python/time-machine/time-machine-3.3.0.ebuild
@@ -0,0 +1,36 @@
+# Copyright 2022-2026 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+EAPI=8
+
+DISTUTILS_EXT=1
+DISTUTILS_USE_PEP517=setuptools
+PYTHON_COMPAT=( python3_{13..14} )
+
+inherit distutils-r1
+
+DESCRIPTION="Travel through time in your tests"
+HOMEPAGE="
+ https://github.com/adamchainz/time-machine/
+ https://pypi.org/project/time-machine/
+"
+SRC_URI="
+ https://github.com/adamchainz/time-machine/archive/${PV}.tar.gz
+ -> ${P}.gh.tar.gz
+"
+
+LICENSE="MIT"
+SLOT="0"
+KEYWORDS="~alpha ~amd64 ~arm ~arm64 ~hppa ~loong ~m68k ~mips ~ppc ~ppc64 ~riscv ~s390 ~sparc ~x86"
+
+BDEPEND="
+ test? (
+ dev-python/freezegun[${PYTHON_USEDEP}]
+ dev-python/python-dateutil[${PYTHON_USEDEP}]
+ dev-python/tokenize-rt[${PYTHON_USEDEP}]
+ )
+"
+
+EPYTEST_PLUGIN_LOAD_VIA_ENV=1
+EPYTEST_PLUGINS=( "${PN}" )
+distutils_enable_tests pytest