From f7914e29b0eb93d55205f42ba36fc8de5b36ef3f Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Wed, 5 Mar 2025 18:43:58 -0600 Subject: [PATCH 1/6] Remove support for Python 3.8 --- .github/workflows/build.yml | 4 +-- .github/workflows/run_unit_tests.yml | 2 +- CHANGELOG.md | 1 + CONTRIBUTING.md | 2 +- README.rst | 2 +- poetry.lock | 47 ++-------------------------- pyproject.toml | 7 ++--- tox.ini | 2 +- 8 files changed, 12 insertions(+), 55 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9039ae521..7405eebc9 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -14,8 +14,8 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - # The codegen scripts require Python 3.8 or later. - python-version: "3.8" + # The codegen scripts require Python 3.9 or later. + python-version: "3.9" - name: Set up Poetry uses: Gr1N/setup-poetry@v9 with: diff --git a/.github/workflows/run_unit_tests.yml b/.github/workflows/run_unit_tests.yml index d0f7a111c..8d6a6c7a5 100644 --- a/.github/workflows/run_unit_tests.yml +++ b/.github/workflows/run_unit_tests.yml @@ -11,7 +11,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"] + python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"] # Fail-fast skews the pass/fail ratio and seems to make pytest produce # incomplete JUnit XML results. fail-fast: false diff --git a/CHANGELOG.md b/CHANGELOG.md index 4269ee9f2..e890639b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ All notable changes to this project will be documented in this file. * ### Major Changes * Added support for mioDAQ configurable digital voltage. + * Removed support for Python 3.8. * ### Known Issues * ... diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 97b06700f..c297d2ac2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -26,7 +26,7 @@ through our [GitHub issues page](http://github.com/ni/nidaqmx-python/issues). 6. Make your change. 7. Once the necessary changes are done, update the auto-generated code using ``poetry run python src/codegen --dest generated/nidaqmx``. This will ensure that the latest files are present in the ``generated`` folder. > **Note** - > The codegen scripts require Python 3.8 or later. + > The codegen scripts require Python 3.9 or later. 8. Run all the regression tests again (including the tests you just added), and confirm that they all pass. 9. Run `poetry run ni-python-styleguide lint` to check that the updated code follows NI's Python coding diff --git a/README.rst b/README.rst index 38a87c679..dcadf6e3c 100644 --- a/README.rst +++ b/README.rst @@ -56,7 +56,7 @@ system. Python Version Support ---------------------- -**nidaqmx** supports CPython 3.8+ and PyPy3. +**nidaqmx** supports CPython 3.9+ and PyPy3. Installation ============ diff --git a/poetry.lock b/poetry.lock index fead5d6f4..b780f7e3f 100644 --- a/poetry.lock +++ b/poetry.lock @@ -22,40 +22,9 @@ files = [ {file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"}, ] -[package.dependencies] -pytz = {version = ">=2015.7", markers = "python_version < \"3.9\""} - [package.extras] dev = ["freezegun (>=1.0,<2.0)", "pytest (>=6.0)", "pytest-cov"] -[[package]] -name = "backports-zoneinfo" -version = "0.2.1" -description = "Backport of the standard library zoneinfo module" -optional = false -python-versions = ">=3.6" -files = [ - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:da6013fd84a690242c310d77ddb8441a559e9cb3d3d59ebac9aca1a57b2e18bc"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:89a48c0d158a3cc3f654da4c2de1ceba85263fafb861b98b59040a5086259722"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:1c5742112073a563c81f786e77514969acb58649bcdf6cdf0b4ed31a348d4546"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win32.whl", hash = "sha256:e8236383a20872c0cdf5a62b554b27538db7fa1bbec52429d8d106effbaeca08"}, - {file = "backports.zoneinfo-0.2.1-cp36-cp36m-win_amd64.whl", hash = "sha256:8439c030a11780786a2002261569bdf362264f605dfa4d65090b64b05c9f79a7"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:f04e857b59d9d1ccc39ce2da1021d196e47234873820cbeaad210724b1ee28ac"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:17746bd546106fa389c51dbea67c8b7c8f0d14b5526a579ca6ccf5ed72c526cf"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:5c144945a7752ca544b4b78c8c41544cdfaf9786f25fe5ffb10e838e19a27570"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win32.whl", hash = "sha256:e55b384612d93be96506932a786bbcde5a2db7a9e6a4bb4bffe8b733f5b9036b"}, - {file = "backports.zoneinfo-0.2.1-cp37-cp37m-win_amd64.whl", hash = "sha256:a76b38c52400b762e48131494ba26be363491ac4f9a04c1b7e92483d169f6582"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:8961c0f32cd0336fb8e8ead11a1f8cd99ec07145ec2931122faaac1c8f7fd987"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:e81b76cace8eda1fca50e345242ba977f9be6ae3945af8d46326d776b4cf78d1"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7b0a64cda4145548fed9efc10322770f929b944ce5cee6c0dfe0c87bf4c0c8c9"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win32.whl", hash = "sha256:1b13e654a55cd45672cb54ed12148cd33628f672548f373963b0bff67b217328"}, - {file = "backports.zoneinfo-0.2.1-cp38-cp38-win_amd64.whl", hash = "sha256:4a0f800587060bf8880f954dbef70de6c11bbe59c673c3d818921f042f9954a6"}, - {file = "backports.zoneinfo-0.2.1.tar.gz", hash = "sha256:fadbfe37f74051d024037f223b8e001611eac868b5c5b06144ef4d8b799862f2"}, -] - -[package.extras] -tzdata = ["tzdata"] - [[package]] name = "bandit" version = "1.7.10" @@ -2073,17 +2042,6 @@ files = [ {file = "python_decouple-3.8-py3-none-any.whl", hash = "sha256:d0d45340815b25f4de59c974b855bb38d03151d81b037d9e3f463b0c9f8cbd66"}, ] -[[package]] -name = "pytz" -version = "2024.2" -description = "World timezone definitions, modern and historical" -optional = true -python-versions = "*" -files = [ - {file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"}, - {file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"}, -] - [[package]] name = "pyyaml" version = "6.0.2" @@ -2504,7 +2462,6 @@ files = [ ] [package.dependencies] -"backports.zoneinfo" = {version = "*", markers = "python_version < \"3.9\""} tzdata = {version = "*", markers = "platform_system == \"Windows\""} [package.extras] @@ -2572,5 +2529,5 @@ grpc = ["grpcio", "protobuf"] [metadata] lock-version = "2.0" -python-versions = "^3.8" -content-hash = "21117d099dd86a9804ed665204bda77ad25089e925caf11d8462b5f0378f2b79" +python-versions = "^3.9" +content-hash = "4b7c6903a3bf6d9e0d254370e90f636a01c9a5bbb2ca9b9d5d89eb50fce3edf2" diff --git a/pyproject.toml b/pyproject.toml index 37792763f..5bd6480b1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -18,7 +18,6 @@ classifiers = [ "Operating System :: Microsoft :: Windows", "Operating System :: POSIX", "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", @@ -32,9 +31,9 @@ exclude = ["nidaqmx/tests"] packages = [{ include = "nidaqmx", from = "generated" }] [tool.poetry.dependencies] -python = "^3.8" +python = "^3.9" numpy = [ - {version = ">=1.22", python = ">=3.8,<3.12"}, + {version = ">=1.22", python = ">=3.9,<3.12"}, {version = ">=1.26", python = ">=3.12,<3.13"}, {version = ">=2.1", python = "^3.13"}, ] @@ -63,7 +62,7 @@ grpc = ["grpcio", "protobuf"] click = "^8.1" Mako = "^1.2" grpcio-tools = [ - {version = "1.49.1", python = ">=3.8,<3.12"}, + {version = "1.49.1", python = ">=3.9,<3.12"}, {version = "1.59.0", python = ">=3.12,<3.13"}, {version = "1.67.0", python = "^3.13"}, ] diff --git a/tox.ini b/tox.ini index b65a4083c..49425f32e 100644 --- a/tox.ini +++ b/tox.ini @@ -5,7 +5,7 @@ [tox] isolated_build = true -envlist = clean, py{38,39,310,311,312,313}-base, py{38,39,310,311,312,313}-grpc, py39-base-nicaiu, py39-base-nicai_utf8, report, docs +envlist = clean, py{39,310,311,312,313}-base, py{39,310,311,312,313}-grpc, py39-base-nicaiu, py39-base-nicai_utf8, report, docs [testenv] skip_install = true From abb11450ee0d0f0159bde560bb5f897a380b17a5 Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Wed, 5 Mar 2025 19:17:14 -0600 Subject: [PATCH 2/6] Remove Python 3.8 workarounds --- src/handwritten/_time.py | 7 +------ tests/acceptance/test_multi_threading.py | 7 +------ tests/unit/test_grpc_time.py | 7 +------ tests/unit/test_lib_time.py | 7 +------ 4 files changed, 4 insertions(+), 24 deletions(-) diff --git a/src/handwritten/_time.py b/src/handwritten/_time.py index b6e6d47c9..fd0601968 100644 --- a/src/handwritten/_time.py +++ b/src/handwritten/_time.py @@ -1,17 +1,12 @@ from __future__ import annotations -import sys from tzlocal import get_localzone from datetime import timezone from datetime import tzinfo as dt_tzinfo from datetime import datetime as std_datetime from hightime import datetime as ht_datetime from typing import Optional, Union - -if sys.version_info >= (3, 9): - from zoneinfo import ZoneInfo -else: - from backports.zoneinfo import ZoneInfo +from zoneinfo import ZoneInfo # theoretically the same as astimezone(), but with support for dates before 1970 def _convert_to_desired_timezone(expected_time_utc: Union[std_datetime, ht_datetime], tzinfo: Optional[dt_tzinfo] = None) -> Union[std_datetime, ht_datetime]: diff --git a/tests/acceptance/test_multi_threading.py b/tests/acceptance/test_multi_threading.py index 5b3085ebc..8b0a1bdb9 100644 --- a/tests/acceptance/test_multi_threading.py +++ b/tests/acceptance/test_multi_threading.py @@ -1,7 +1,6 @@ import concurrent.futures import functools import random -import sys import threading import time from concurrent.futures import Future, ThreadPoolExecutor @@ -165,11 +164,7 @@ def _check_for_exceptions(futures: Sequence[Future]) -> None: def _release_n(semaphore: Semaphore, n: int) -> None: - if sys.version_info < (3, 9): - for i in range(n): - semaphore.release() - else: - semaphore.release(n) + semaphore.release(n) def test___shared_interpreter___run_multiple_acquisitions_with_events___callbacks_invoked( diff --git a/tests/unit/test_grpc_time.py b/tests/unit/test_grpc_time.py index d87865df5..2f01cade2 100644 --- a/tests/unit/test_grpc_time.py +++ b/tests/unit/test_grpc_time.py @@ -1,4 +1,3 @@ -import sys from datetime import datetime as std_datetime, timedelta, timezone import pytest @@ -18,11 +17,7 @@ import nidaqmx._stubs.nidaqmx_pb2 as nidaqmx_pb2 except ImportError: pass - -if sys.version_info >= (3, 9): - from zoneinfo import ZoneInfo -else: - from backports.zoneinfo import ZoneInfo +from zoneinfo import ZoneInfo @pytest.mark.parametrize("from_dt", [(JAN_01_2002_DATETIME), (JAN_01_2002_HIGHTIME)]) diff --git a/tests/unit/test_lib_time.py b/tests/unit/test_lib_time.py index e1db1aa7a..fd97211c0 100644 --- a/tests/unit/test_lib_time.py +++ b/tests/unit/test_lib_time.py @@ -1,5 +1,4 @@ import random -import sys from copy import copy from datetime import datetime as std_datetime, timedelta, timezone @@ -18,11 +17,7 @@ JAN_01_2002_HIGHTIME, JAN_01_2002_TIMESTAMP_1904_EPOCH, ) - -if sys.version_info >= (3, 9): - from zoneinfo import ZoneInfo -else: - from backports.zoneinfo import ZoneInfo +from zoneinfo import ZoneInfo JAN_01_2002_LIB = LibTimestamp(lsb=0, msb=JAN_01_2002_TIMESTAMP_1904_EPOCH) JAN_01_1904_LIB = LibTimestamp(lsb=0, msb=JAN_01_1904_TIMESTAMP_1904_EPOCH) From ab46354f8f849eaef784778b1cf38a3799869896 Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Wed, 5 Mar 2025 19:17:26 -0600 Subject: [PATCH 3/6] Regenerate codegen --- generated/nidaqmx/_time.py | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/generated/nidaqmx/_time.py b/generated/nidaqmx/_time.py index b6e6d47c9..fd0601968 100644 --- a/generated/nidaqmx/_time.py +++ b/generated/nidaqmx/_time.py @@ -1,17 +1,12 @@ from __future__ import annotations -import sys from tzlocal import get_localzone from datetime import timezone from datetime import tzinfo as dt_tzinfo from datetime import datetime as std_datetime from hightime import datetime as ht_datetime from typing import Optional, Union - -if sys.version_info >= (3, 9): - from zoneinfo import ZoneInfo -else: - from backports.zoneinfo import ZoneInfo +from zoneinfo import ZoneInfo # theoretically the same as astimezone(), but with support for dates before 1970 def _convert_to_desired_timezone(expected_time_utc: Union[std_datetime, ht_datetime], tzinfo: Optional[dt_tzinfo] = None) -> Union[std_datetime, ht_datetime]: From 2e1d8e6c68d827b366af8e4a30eca05c45fd7105 Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Wed, 5 Mar 2025 19:22:11 -0600 Subject: [PATCH 4/6] Fix lint errors --- tests/unit/test_lib_time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_lib_time.py b/tests/unit/test_lib_time.py index fd97211c0..73e06de08 100644 --- a/tests/unit/test_lib_time.py +++ b/tests/unit/test_lib_time.py @@ -1,6 +1,7 @@ import random from copy import copy from datetime import datetime as std_datetime, timedelta, timezone +from zoneinfo import ZoneInfo import pytest from hightime import datetime as ht_datetime @@ -17,7 +18,6 @@ JAN_01_2002_HIGHTIME, JAN_01_2002_TIMESTAMP_1904_EPOCH, ) -from zoneinfo import ZoneInfo JAN_01_2002_LIB = LibTimestamp(lsb=0, msb=JAN_01_2002_TIMESTAMP_1904_EPOCH) JAN_01_1904_LIB = LibTimestamp(lsb=0, msb=JAN_01_1904_TIMESTAMP_1904_EPOCH) From 01bde2858b7588a17459e2a8b7d94d606875540c Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Wed, 5 Mar 2025 19:23:28 -0600 Subject: [PATCH 5/6] Fix lint errors --- tests/unit/test_grpc_time.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/unit/test_grpc_time.py b/tests/unit/test_grpc_time.py index 2f01cade2..90cead580 100644 --- a/tests/unit/test_grpc_time.py +++ b/tests/unit/test_grpc_time.py @@ -1,4 +1,5 @@ from datetime import datetime as std_datetime, timedelta, timezone +from zoneinfo import ZoneInfo import pytest from hightime import datetime as ht_datetime @@ -17,7 +18,6 @@ import nidaqmx._stubs.nidaqmx_pb2 as nidaqmx_pb2 except ImportError: pass -from zoneinfo import ZoneInfo @pytest.mark.parametrize("from_dt", [(JAN_01_2002_DATETIME), (JAN_01_2002_HIGHTIME)]) From 2eb25057fa6414e62260600dbd0759daf3d2bfcb Mon Sep 17 00:00:00 2001 From: Brad Keryan Date: Wed, 5 Mar 2025 19:28:10 -0600 Subject: [PATCH 6/6] tests: Remove a vestigial helper function --- tests/acceptance/test_multi_threading.py | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/tests/acceptance/test_multi_threading.py b/tests/acceptance/test_multi_threading.py index 8b0a1bdb9..76d419f3f 100644 --- a/tests/acceptance/test_multi_threading.py +++ b/tests/acceptance/test_multi_threading.py @@ -49,7 +49,7 @@ def test___single_task___get_set_float_properties___no_errors( start_barrier.wait(timeout=TIMEOUT) time.sleep(RUN_TIME) - _release_n(stop_semaphore, num_channels) + stop_semaphore.release(num_channels) concurrent.futures.wait(futures) _check_for_exceptions(futures) @@ -91,7 +91,7 @@ def test___single_task___get_set_float_and_string_properties___no_errors( start_barrier.wait(timeout=TIMEOUT) time.sleep(RUN_TIME) - _release_n(stop_semaphore, num_channels) + stop_semaphore.release(num_channels) concurrent.futures.wait(futures) _check_for_exceptions(futures) @@ -138,7 +138,7 @@ def test___multiple_tasks___get_set_float_and_string_properties___no_errors( start_barrier.wait(timeout=TIMEOUT) time.sleep(RUN_TIME) - _release_n(stop_semaphore, num_tasks) + stop_semaphore.release(num_tasks) concurrent.futures.wait(futures) _check_for_exceptions(futures) @@ -163,10 +163,6 @@ def _check_for_exceptions(futures: Sequence[Future]) -> None: _ = future.result() -def _release_n(semaphore: Semaphore, n: int) -> None: - semaphore.release(n) - - def test___shared_interpreter___run_multiple_acquisitions_with_events___callbacks_invoked( init_kwargs, multi_threading_test_devices: Sequence[Device],