From ab7a388942bc3939b362283455ee5b644fcc5f29 Mon Sep 17 00:00:00 2001 From: Adam Johnson Date: Mon, 10 Jan 2022 16:13:09 +0000 Subject: [PATCH] Drop Python 3.6 support (#222) Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> --- .github/workflows/main.yml | 1 - .pre-commit-config.yaml | 2 +- HISTORY.rst | 2 + README.rst | 2 +- pyproject.toml | 2 +- requirements/compile.py | 5 -- requirements/py36.txt | 116 ----------------------------------- setup.cfg | 3 +- src/_time_machine.c | 47 +------------- src/time_machine/__init__.py | 62 ++++++------------- tests/test_time_machine.py | 15 +---- 11 files changed, 27 insertions(+), 230 deletions(-) delete mode 100644 requirements/py36.txt diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index b900e1d..8db76b9 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,7 +14,6 @@ jobs: strategy: matrix: python-version: - - 3.6 - 3.7 - 3.8 - 3.9 diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e19db47..cc857a0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -17,7 +17,7 @@ repos: rev: v2.31.0 hooks: - id: pyupgrade - args: [--py36-plus] + args: [--py37-plus] - repo: https://github.com/psf/black rev: 21.12b0 hooks: diff --git a/HISTORY.rst b/HISTORY.rst index 6feb3cc..2edf88c 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -2,6 +2,8 @@ History ======= +* Drop Python 3.6 support. + 2.5.0 (2021-12-14) ------------------ diff --git a/README.rst b/README.rst index c0e60cb..3d579e6 100644 --- a/README.rst +++ b/README.rst @@ -46,7 +46,7 @@ Use **pip**: python -m pip install time-machine -Python 3.6 to 3.10 supported. +Python 3.7 to 3.10 supported. Only CPython is supported at this time because time-machine directly hooks into the C-level API. ---- diff --git a/pyproject.toml b/pyproject.toml index ea4908e..df5cba7 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -3,7 +3,7 @@ requires = ["setuptools >= 40.6.0", "wheel"] build-backend = "setuptools.build_meta" [tool.black] -target-version = ['py36'] +target-version = ['py37'] [tool.isort] profile = "black" diff --git a/requirements/compile.py b/requirements/compile.py index 2b3b368..f15e845 100755 --- a/requirements/compile.py +++ b/requirements/compile.py @@ -15,11 +15,6 @@ "--generate-hashes", "--allow-unsafe", ] + sys.argv[1:] - subprocess.run( - ["python3.6", *common_args, "-o", "py36.txt"], - check=True, - capture_output=True, - ) subprocess.run( ["python3.7", *common_args, "-o", "py37.txt"], check=True, diff --git a/requirements/py36.txt b/requirements/py36.txt deleted file mode 100644 index 4a402c9..0000000 --- a/requirements/py36.txt +++ /dev/null @@ -1,116 +0,0 @@ -# -# This file is autogenerated by pip-compile with python 3.6 -# To update, run: -# -# requirements/compile.py -# -attrs==21.4.0 \ - --hash=sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4 \ - --hash=sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd - # via pytest -coverage==6.2 \ - --hash=sha256:01774a2c2c729619760320270e42cd9e797427ecfddd32c2a7b639cdc481f3c0 \ - --hash=sha256:03b20e52b7d31be571c9c06b74746746d4eb82fc260e594dc662ed48145e9efd \ - --hash=sha256:0a7726f74ff63f41e95ed3a89fef002916c828bb5fcae83b505b49d81a066884 \ - --hash=sha256:1219d760ccfafc03c0822ae2e06e3b1248a8e6d1a70928966bafc6838d3c9e48 \ - --hash=sha256:13362889b2d46e8d9f97c421539c97c963e34031ab0cb89e8ca83a10cc71ac76 \ - --hash=sha256:174cf9b4bef0db2e8244f82059a5a72bd47e1d40e71c68ab055425172b16b7d0 \ - --hash=sha256:17e6c11038d4ed6e8af1407d9e89a2904d573be29d51515f14262d7f10ef0a64 \ - --hash=sha256:215f8afcc02a24c2d9a10d3790b21054b58d71f4b3c6f055d4bb1b15cecce685 \ - --hash=sha256:22e60a3ca5acba37d1d4a2ee66e051f5b0e1b9ac950b5b0cf4aa5366eda41d47 \ - --hash=sha256:2641f803ee9f95b1f387f3e8f3bf28d83d9b69a39e9911e5bfee832bea75240d \ - --hash=sha256:276651978c94a8c5672ea60a2656e95a3cce2a3f31e9fb2d5ebd4c215d095840 \ - --hash=sha256:3f7c17209eef285c86f819ff04a6d4cbee9b33ef05cbcaae4c0b4e8e06b3ec8f \ - --hash=sha256:3feac4084291642165c3a0d9eaebedf19ffa505016c4d3db15bfe235718d4971 \ - --hash=sha256:49dbff64961bc9bdd2289a2bda6a3a5a331964ba5497f694e2cbd540d656dc1c \ - --hash=sha256:4e547122ca2d244f7c090fe3f4b5a5861255ff66b7ab6d98f44a0222aaf8671a \ - --hash=sha256:5829192582c0ec8ca4a2532407bc14c2f338d9878a10442f5d03804a95fac9de \ - --hash=sha256:5d6b09c972ce9200264c35a1d53d43ca55ef61836d9ec60f0d44273a31aa9f17 \ - --hash=sha256:600617008aa82032ddeace2535626d1bc212dfff32b43989539deda63b3f36e4 \ - --hash=sha256:619346d57c7126ae49ac95b11b0dc8e36c1dd49d148477461bb66c8cf13bb521 \ - --hash=sha256:63c424e6f5b4ab1cf1e23a43b12f542b0ec2e54f99ec9f11b75382152981df57 \ - --hash=sha256:6dbc1536e105adda7a6312c778f15aaabe583b0e9a0b0a324990334fd458c94b \ - --hash=sha256:6e1394d24d5938e561fbeaa0cd3d356207579c28bd1792f25a068743f2d5b282 \ - --hash=sha256:86f2e78b1eff847609b1ca8050c9e1fa3bd44ce755b2ec30e70f2d3ba3844644 \ - --hash=sha256:8bdfe9ff3a4ea37d17f172ac0dff1e1c383aec17a636b9b35906babc9f0f5475 \ - --hash=sha256:8e2c35a4c1f269704e90888e56f794e2d9c0262fb0c1b1c8c4ee44d9b9e77b5d \ - --hash=sha256:92b8c845527eae547a2a6617d336adc56394050c3ed8a6918683646328fbb6da \ - --hash=sha256:9365ed5cce5d0cf2c10afc6add145c5037d3148585b8ae0e77cc1efdd6aa2953 \ - --hash=sha256:9a29311bd6429be317c1f3fe4bc06c4c5ee45e2fa61b2a19d4d1d6111cb94af2 \ - --hash=sha256:9a2b5b52be0a8626fcbffd7e689781bf8c2ac01613e77feda93d96184949a98e \ - --hash=sha256:a4bdeb0a52d1d04123b41d90a4390b096f3ef38eee35e11f0b22c2d031222c6c \ - --hash=sha256:a9c8c4283e17690ff1a7427123ffb428ad6a52ed720d550e299e8291e33184dc \ - --hash=sha256:b637c57fdb8be84e91fac60d9325a66a5981f8086c954ea2772efe28425eaf64 \ - --hash=sha256:bf154ba7ee2fd613eb541c2bc03d3d9ac667080a737449d1a3fb342740eb1a74 \ - --hash=sha256:c254b03032d5a06de049ce8bca8338a5185f07fb76600afff3c161e053d88617 \ - --hash=sha256:c332d8f8d448ded473b97fefe4a0983265af21917d8b0cdcb8bb06b2afe632c3 \ - --hash=sha256:c7912d1526299cb04c88288e148c6c87c0df600eca76efd99d84396cfe00ef1d \ - --hash=sha256:cfd9386c1d6f13b37e05a91a8583e802f8059bebfccde61a418c5808dea6bbfa \ - --hash=sha256:d5d2033d5db1d58ae2d62f095e1aefb6988af65b4b12cb8987af409587cc0739 \ - --hash=sha256:dca38a21e4423f3edb821292e97cec7ad38086f84313462098568baedf4331f8 \ - --hash=sha256:e2cad8093172b7d1595b4ad66f24270808658e11acf43a8f95b41276162eb5b8 \ - --hash=sha256:e3db840a4dee542e37e09f30859f1612da90e1c5239a6a2498c473183a50e781 \ - --hash=sha256:edcada2e24ed68f019175c2b2af2a8b481d3d084798b8c20d15d34f5c733fa58 \ - --hash=sha256:f467bbb837691ab5a8ca359199d3429a11a01e6dfb3d9dcc676dc035ca93c0a9 \ - --hash=sha256:f506af4f27def639ba45789fa6fde45f9a217da0be05f8910458e4557eed020c \ - --hash=sha256:f614fc9956d76d8a88a88bb41ddc12709caa755666f580af3a688899721efecd \ - --hash=sha256:f9afb5b746781fc2abce26193d1c817b7eb0e11459510fba65d2bd77fe161d9e \ - --hash=sha256:fb8b8ee99b3fffe4fd86f4c81b35a6bf7e4462cba019997af2fe679365db0c49 - # via -r requirements.in -importlib-metadata==4.8.3 \ - --hash=sha256:65a9576a5b2d58ca44d133c42a241905cc45e34d2c06fd5ba2bafa221e5d7b5e \ - --hash=sha256:766abffff765960fcc18003801f7044eb6755ffae4521c8e8ce8e83b9c9b0668 - # via - # pluggy - # pytest - # pytest-randomly -iniconfig==1.1.1 \ - --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \ - --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32 - # via pytest -packaging==21.3 \ - --hash=sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb \ - --hash=sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522 - # via pytest -pluggy==1.0.0 \ - --hash=sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159 \ - --hash=sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3 - # via pytest -py==1.11.0 \ - --hash=sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719 \ - --hash=sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378 - # via pytest -pyparsing==3.0.6 \ - --hash=sha256:04ff808a5b90911829c55c4e26f75fa5ca8a2f5f36aa3a51f68e27033341d3e4 \ - --hash=sha256:d9bdec0013ef1eb5a84ab39a3b3868911598afa494f5faa038647101504e2b81 - # via packaging -pytest==6.2.5 \ - --hash=sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89 \ - --hash=sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134 - # via - # -r requirements.in - # pytest-randomly -pytest-randomly==3.10.3 \ - --hash=sha256:22154cdcff7ba44e0599596490e6b75278ca973a33812ea6a54bf14d0b042ef1 \ - --hash=sha256:b05a7a45f54cae2b5095752c6a10cb559df84448421b0420ae492dd2fb1727ef - # via -r requirements.in -python-dateutil==2.8.2 \ - --hash=sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86 \ - --hash=sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9 - # via -r requirements.in -six==1.16.0 \ - --hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \ - --hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254 - # via python-dateutil -toml==0.10.2 \ - --hash=sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b \ - --hash=sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f - # via pytest -typing-extensions==4.0.1 \ - --hash=sha256:4ca091dea149f945ec56afb48dae714f21e8692ef22a395223bcd328961b6a0e \ - --hash=sha256:7f001e5ac290a0c0401508864c7ec868be4e701886d5b573a9528ed3973d9d3b - # via importlib-metadata -zipp==3.6.0 \ - --hash=sha256:71c644c5369f4a6e07636f0aa966270449561fcea2e3d6747b8d23efaa9d7832 \ - --hash=sha256:9fe5ea21568a0a70e50f273397638d39b03353731e6cbbb3fd8502a33fec40bc - # via importlib-metadata diff --git a/setup.cfg b/setup.cfg index 3602551..f82a26a 100644 --- a/setup.cfg +++ b/setup.cfg @@ -21,7 +21,6 @@ classifiers = Operating System :: OS Independent Programming Language :: Python :: 3 :: Only Programming Language :: Python :: 3 - Programming Language :: Python :: 3.6 Programming Language :: Python :: 3.7 Programming Language :: Python :: 3.8 Programming Language :: Python :: 3.9 @@ -35,7 +34,7 @@ packages = find: include_package_data = True install_requires = python-dateutil -python_requires = >=3.6 +python_requires = >=3.7 zip_safe = False [options.packages.find] diff --git a/src/_time_machine.c b/src/_time_machine.c index e11c32e..7e6bb99 100644 --- a/src/_time_machine.c +++ b/src/_time_machine.c @@ -4,23 +4,15 @@ // Module state typedef struct { -#if PY_VERSION_HEX >= 0x03070000 _PyCFunctionFastWithKeywords original_now; -#else - _PyCFunctionFast original_now; -#endif PyCFunction original_utcnow; PyCFunction original_clock_gettime; -#if PY_VERSION_HEX >= 0x03070000 PyCFunction original_clock_gettime_ns; -#endif PyCFunction original_gmtime; PyCFunction original_localtime; PyCFunction original_strftime; PyCFunction original_time; -#if PY_VERSION_HEX >= 0x03070000 PyCFunction original_time_ns; -#endif } _time_machine_state; static inline _time_machine_state* @@ -34,15 +26,12 @@ get_time_machine_state(PyObject *module) /* datetime.datetime.now() */ /* - This one is the only function using 'vectorcall' on Python 3.8. + This one is the only function using 'vectorcall' on Python 3.8+ */ static PyObject* -#if PY_VERSION_HEX >= 0x03070000 _time_machine_now(PyTypeObject *type, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -#else -_time_machine_now(PyTypeObject *type, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) -#endif + { PyObject *result = NULL; @@ -60,15 +49,9 @@ _time_machine_now(PyTypeObject *type, PyObject **args, Py_ssize_t nargs, PyObjec static _PyArg_Parser _parser = {"|O:now", _keywords, 0}; PyObject *tz = Py_None; -#if PY_VERSION_HEX >= 0x03070000 if (!_PyArg_ParseStackAndKeywords(args, nargs, kwnames, &_parser, &tz)) { goto exit; } -#else - if (!_PyArg_ParseStack(args, nargs, kwnames, &_parser, &tz)) { - goto exit; - } -#endif /* Call with a new tuple */ PyObject* now_args = PyTuple_Pack(1, tz); @@ -85,11 +68,7 @@ _time_machine_now(PyTypeObject *type, PyObject **args, Py_ssize_t nargs, PyObjec } static PyObject* -#if PY_VERSION_HEX >= 0x03070000 _time_machine_original_now(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) -#else -_time_machine_original_now(PyObject *module, PyObject **args, Py_ssize_t nargs, PyObject *kwnames) -#endif { _time_machine_state *state = get_time_machine_state(module); @@ -179,7 +158,6 @@ PyDoc_STRVAR(original_clock_gettime_doc, Call time.clock_gettime() after patching."); /* time.clock_gettime_ns() */ -#if PY_VERSION_HEX >= 0x03070000 static PyObject* _time_machine_clock_gettime_ns(PyObject *self, PyObject *args) @@ -213,8 +191,6 @@ PyDoc_STRVAR(original_clock_gettime_ns_doc, \n\ Call time.clock_gettime_ns() after patching."); -#endif - /* time.gmtime() */ static PyObject* @@ -352,7 +328,6 @@ PyDoc_STRVAR(original_time_doc, Call time.time() after patching."); /* time.time_ns() */ -#if PY_VERSION_HEX >= 0x03070000 static PyObject* _time_machine_time_ns(PyObject *self, PyObject *args) @@ -386,8 +361,6 @@ PyDoc_STRVAR(original_time_ns_doc, \n\ Call time.time_ns() after patching."); -#endif - static PyObject* _time_machine_patch_if_needed(PyObject *module, PyObject *unused) { @@ -403,11 +376,7 @@ _time_machine_patch_if_needed(PyObject *module, PyObject *unused) PyObject *datetime_class = PyObject_GetAttrString(datetime_module, "datetime"); PyCFunctionObject *datetime_datetime_now = (PyCFunctionObject *) PyObject_GetAttrString(datetime_class, "now"); -#if PY_VERSION_HEX >= 0x03070000 state->original_now = (_PyCFunctionFastWithKeywords) datetime_datetime_now->m_ml->ml_meth; -#else - state->original_now = (_PyCFunctionFast) datetime_datetime_now->m_ml->ml_meth; -#endif datetime_datetime_now->m_ml->ml_meth = (PyCFunction) _time_machine_now; Py_DECREF(datetime_datetime_now); @@ -434,14 +403,12 @@ _time_machine_patch_if_needed(PyObject *module, PyObject *unused) Py_DECREF(time_clock_gettime); } -#if PY_VERSION_HEX >= 0x03070000 PyCFunctionObject *time_clock_gettime_ns = (PyCFunctionObject *) PyObject_GetAttrString(time_module, "clock_gettime_ns"); if (time_clock_gettime_ns != NULL) { state->original_clock_gettime_ns = time_clock_gettime_ns->m_ml->ml_meth; time_clock_gettime_ns->m_ml->ml_meth = _time_machine_clock_gettime_ns; Py_DECREF(time_clock_gettime_ns); } -#endif PyCFunctionObject *time_gmtime = (PyCFunctionObject *) PyObject_GetAttrString(time_module, "gmtime"); state->original_gmtime = time_gmtime->m_ml->ml_meth; @@ -463,12 +430,10 @@ _time_machine_patch_if_needed(PyObject *module, PyObject *unused) time_time->m_ml->ml_meth = _time_machine_time; Py_DECREF(time_time); -#if PY_VERSION_HEX >= 0x03070000 PyCFunctionObject *time_time_ns = (PyCFunctionObject *) PyObject_GetAttrString(time_module, "time_ns"); state->original_time_ns = time_time_ns->m_ml->ml_meth; time_time_ns->m_ml->ml_meth = _time_machine_time_ns; Py_DECREF(time_time_ns); -#endif Py_DECREF(time_module); @@ -484,23 +449,15 @@ Swap in helpers."); PyDoc_STRVAR(module_doc, "_time_machine module"); static PyMethodDef module_functions[] = { -#if PY_VERSION_HEX >= 0x03070000 {"original_now", (PyCFunction)_time_machine_original_now, METH_FASTCALL|METH_KEYWORDS, original_now_doc}, -#else - {"original_now", (PyCFunction)_time_machine_original_now, METH_FASTCALL, original_now_doc}, -#endif {"original_utcnow", (PyCFunction)_time_machine_original_utcnow, METH_NOARGS, original_utcnow_doc}, {"original_clock_gettime", (PyCFunction)_time_machine_original_clock_gettime, METH_VARARGS, original_clock_gettime_doc}, -#if PY_VERSION_HEX >= 0x03070000 {"original_clock_gettime_ns", (PyCFunction)_time_machine_original_clock_gettime_ns, METH_VARARGS, original_clock_gettime_ns_doc}, -#endif {"original_gmtime", (PyCFunction)_time_machine_original_gmtime, METH_VARARGS, original_gmtime_doc}, {"original_localtime", (PyCFunction)_time_machine_original_localtime, METH_VARARGS, original_localtime_doc}, {"original_strftime", (PyCFunction)_time_machine_original_strftime, METH_VARARGS, original_strftime_doc}, {"original_time", (PyCFunction)_time_machine_original_time, METH_NOARGS, original_time_doc}, -#if PY_VERSION_HEX >= 0x03070000 {"original_time_ns", (PyCFunction)_time_machine_original_time_ns, METH_NOARGS, original_time_ns_doc}, -#endif {"patch_if_needed", (PyCFunction)_time_machine_patch_if_needed, METH_NOARGS, patch_if_needed_doc}, {NULL, NULL} /* sentinel */ }; diff --git a/src/time_machine/__init__.py b/src/time_machine/__init__.py index 5a55d03..4379ce0 100644 --- a/src/time_machine/__init__.py +++ b/src/time_machine/__init__.py @@ -138,7 +138,7 @@ def time_ns(self) -> int: return self._destination_timestamp_ns base = SYSTEM_EPOCH_TIMESTAMP_NS + self._destination_timestamp_ns - now_ns = self._time_ns() + now_ns = _time_machine.original_time_ns() if not self._requested: self._requested = True @@ -147,16 +147,6 @@ def time_ns(self) -> int: return base + (now_ns - self._real_start_timestamp_ns) - if sys.version_info >= (3, 7): - - def _time_ns(self) -> int: - return _time_machine.original_time_ns() - - else: - - def _time_ns(self) -> int: - return _time_machine.original_time() * NANOSECONDS_PER_SECOND - def shift(self, delta: Union[dt.timedelta, int, float]) -> None: if isinstance(delta, dt.timedelta): total_seconds = delta.total_seconds() @@ -201,22 +191,14 @@ def _stop(self) -> None: # None, which makes it use time.time(). Otherwise it makes a system call to # find the current datetime. The time it finds is stored in generated UUID1 # values. -if sys.version_info >= (3, 7): - uuid_generate_time_attr = "_generate_time_safe" -else: - uuid_generate_time_attr = "_uuid_generate_time" +uuid_generate_time_attr = "_generate_time_safe" uuid_generate_time_patcher = mock.patch.object(uuid, uuid_generate_time_attr, new=None) uuid_uuid_create_patcher = mock.patch.object(uuid, "_UuidCreate", new=None) # We need to cause the functions to be loaded before we try patch them out, # which is done by this internal function in Python 3.7+ -if sys.version_info >= (3, 7): - uuid_idempotent_load_system_functions = ( - uuid._load_system_functions # type: ignore[attr-defined] - ) -else: - - def uuid_idempotent_load_system_functions(): - pass +uuid_idempotent_load_system_functions = ( + uuid._load_system_functions # type: ignore[attr-defined] +) class travel: @@ -372,12 +354,10 @@ def clock_gettime(clk_id: int) -> float: return time() -if sys.version_info >= (3, 7): - - def clock_gettime_ns(clk_id: int) -> int: - if not coordinates_stack or clk_id != CLOCK_REALTIME: - return _time_machine.original_clock_gettime_ns(clk_id) - return time_ns() +def clock_gettime_ns(clk_id: int) -> int: + if not coordinates_stack or clk_id != CLOCK_REALTIME: + return _time_machine.original_clock_gettime_ns(clk_id) + return time_ns() def gmtime(secs: Optional[float] = None) -> struct_time: @@ -406,13 +386,11 @@ def time() -> float: return coordinates_stack[-1].time() -if sys.version_info >= (3, 7): - - def time_ns() -> int: - if not coordinates_stack: - return _time_machine.original_time_ns() - else: - return coordinates_stack[-1].time_ns() +def time_ns() -> int: + if not coordinates_stack: + return _time_machine.original_time_ns() + else: + return coordinates_stack[-1].time_ns() # pytest plugin @@ -474,10 +452,8 @@ class _EscapeHatchTime: def clock_gettime(self, clk_id: int) -> float: return _time_machine.original_clock_gettime(clk_id) - if sys.version_info >= (3, 7): - - def clock_gettime_ns(self, clk_id: int) -> int: - return _time_machine.original_clock_gettime_ns(clk_id) + def clock_gettime_ns(self, clk_id: int) -> int: + return _time_machine.original_clock_gettime_ns(clk_id) def gmtime(self, secs: Optional[float] = None) -> struct_time: return _time_machine.original_gmtime(secs) @@ -496,10 +472,8 @@ def strftime( def time(self) -> float: return _time_machine.original_time() - if sys.version_info >= (3, 7): - - def time_ns(self) -> int: - return _time_machine.original_time_ns() + def time_ns(self) -> int: + return _time_machine.original_time_ns() class _EscapeHatch: diff --git a/tests/test_time_machine.py b/tests/test_time_machine.py index 8cb4f63..1656cb5 100644 --- a/tests/test_time_machine.py +++ b/tests/test_time_machine.py @@ -1,7 +1,6 @@ import asyncio import datetime as dt import os -import sys import time import uuid from importlib.util import module_from_spec, spec_from_file_location @@ -27,7 +26,6 @@ LIBRARY_EPOCH_DATETIME = dt.datetime(2020, 4, 29) # The day this library was made LIBRARY_EPOCH = LIBRARY_EPOCH_DATETIME.timestamp() -py_3_7_plus = pytest.mark.skipif(sys.version_info < (3, 7), reason="Python 3.7+") py_have_clock_gettime = pytest.mark.skipif( not hasattr(time, "clock_gettime"), reason="Doesn't have clock_gettime" ) @@ -145,7 +143,6 @@ def test_time_clock_gettime_monotonic_unaffected(): assert now > frozen -@py_3_7_plus @py_have_clock_gettime def test_time_clock_gettime_ns_realtime(): with time_machine.travel(EPOCH + 190.0): @@ -160,7 +157,6 @@ def test_time_clock_gettime_ns_realtime(): assert now >= int(LIBRARY_EPOCH * NANOSECONDS_PER_SECOND) -@py_3_7_plus @py_have_clock_gettime def test_time_clock_gettime_ns_monotonic_unaffected(): start = time.clock_gettime_ns(time.CLOCK_MONOTONIC) @@ -278,7 +274,6 @@ def test_time_time_no_tick(): assert time.time() == EPOCH -@py_3_7_plus def test_time_time_ns(): with time_machine.travel(EPOCH + 150.0): first = time.time_ns() @@ -292,7 +287,6 @@ def test_time_time_ns(): assert now >= int(LIBRARY_EPOCH * NANOSECONDS_PER_SECOND) -@py_3_7_plus def test_time_time_ns_no_tick(): with time_machine.travel(EPOCH, tick=False): assert time.time_ns() == int(EPOCH * NANOSECONDS_PER_SECOND) @@ -477,12 +471,7 @@ async def record_time(): nonlocal recorded_time recorded_time = time.time() - if sys.version_info < (3, 7): - loop = asyncio.get_event_loop() - loop.run_until_complete(record_time()) - loop.close() - else: - asyncio.run(record_time()) + asyncio.run(record_time()) assert recorded_time == EPOCH + 140.0 @@ -760,7 +749,6 @@ def test_time_clock_gettime(self): eh_now = time_machine.escape_hatch.time.clock_gettime(time.CLOCK_REALTIME) assert eh_now >= now - @py_3_7_plus @py_have_clock_gettime def test_time_clock_gettime_ns(self): now = time.clock_gettime_ns(time.CLOCK_REALTIME) @@ -808,7 +796,6 @@ def test_time_time(self): eh_now = time_machine.escape_hatch.time.time() assert eh_now >= now - @py_3_7_plus def test_time_time_ns(self): now = time.time_ns()