Skip to content

Commit 94c9702

Browse files
Copilotastafan8
andauthored
Fix mypy CI crash on qcodes; test _split_timestamp independently
Co-authored-by: astafan8 <15662810+astafan8@users.noreply.github.com>
1 parent 079dfb0 commit 94c9702

2 files changed

Lines changed: 55 additions & 10 deletions

File tree

‎pyproject.toml‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,17 @@ module = [
117117
]
118118
ignore_missing_imports = true
119119

120+
# qcodes ships a py.typed marker, so mypy type-checks its source when following
121+
# imports from plottr. mypy 2.3.1 crashes with an INTERNAL ERROR while analysing
122+
# ``qcodes.dataset.data_set_protocol``. Skip following imports into qcodes so we
123+
# do not type-check a third-party library (and work around the mypy crash).
124+
[[tool.mypy.overrides]]
125+
module = [
126+
"qcodes.*",
127+
]
128+
follow_imports = "skip"
129+
follow_imports_for_stubs = true
130+
120131
[tool.versioningit]
121132
default-version = "0.0"
122133

‎test/pytest/test_qcodes_data.py‎

Lines changed: 44 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import datetime
2+
13
import numpy as np
24
import pytest
35
from packaging import version
@@ -181,6 +183,39 @@ def test_get_ds_structure(experiment):
181183
assert structure == expected_structure
182184

183185

186+
def test_split_timestamp_naive():
187+
# The legacy qcodes timestamp format has no timezone information and is
188+
# returned as-is (split into date and time). Expected values are hard-coded
189+
# so this does not depend on the helper's own logic.
190+
assert _split_timestamp("2026-07-31 10:27:25") == ("2026-07-31", "10:27:25")
191+
192+
193+
def test_split_timestamp_none_and_invalid():
194+
assert _split_timestamp(None) == ("", "")
195+
assert _split_timestamp("") == ("", "")
196+
assert _split_timestamp("not a timestamp") == ("", "")
197+
198+
199+
def test_split_timestamp_timezone_aware_rendered_in_local_time():
200+
# The new qcodes timestamp format includes the UTC offset. Such timestamps
201+
# must be converted to the local timezone of the machine before being split.
202+
# We compute the expected local date/time independently from the helper:
203+
# take a fixed absolute instant, convert it to local wall-clock time via
204+
# ``datetime.fromtimestamp`` (a different code path than the helper), and
205+
# verify the helper agrees for the same instant given in different offsets.
206+
utc_instant = datetime.datetime(2026, 7, 31, 8, 27, 25,
207+
tzinfo=datetime.timezone.utc)
208+
local = datetime.datetime.fromtimestamp(utc_instant.timestamp())
209+
expected = (local.strftime("%Y-%m-%d"), local.strftime("%H:%M:%S"))
210+
211+
# Same instant expressed as UTC (+00:00) and as +02:00.
212+
assert _split_timestamp("2026-07-31 08:27:25+00:00") == expected
213+
assert _split_timestamp("2026-07-31 10:27:25+02:00") == expected
214+
# qcodes renders the offset without a colon (e.g. "+0000"); ensure that
215+
# format is handled too.
216+
assert _split_timestamp("2026-07-31 08:27:25+0000") == expected
217+
218+
184219
def test_get_ds_info(experiment):
185220
N = 5
186221

@@ -203,20 +238,19 @@ def test_get_ds_info(experiment):
203238
# timestamps are difficult to test for, so we will cheat here and
204239
# instead of hard-coding timestamps we will just get them from the dataset
205240
# The same applies to the guid as it contains the timestamp.
206-
# We parse the qcodes timestamps the same way ``get_ds_info`` does, so that
207-
# this test is robust to the qcodes timestamp format (in particular the
208-
# newer format that appends the local UTC offset, e.g.
209-
# "2026-07-31 10:27:25+0200").
210-
started_date, started_time = _split_timestamp(dataset.run_timestamp())
211-
completed_date, completed_time = _split_timestamp(dataset.completed_timestamp())
241+
# To avoid testing ``get_ds_info`` against the very helper it uses
242+
# (``_split_timestamp``), we derive the expected local date/time
243+
# independently from the raw unix timestamps exposed by qcodes.
244+
started = datetime.datetime.fromtimestamp(dataset.run_timestamp_raw)
245+
completed = datetime.datetime.fromtimestamp(dataset.completed_timestamp_raw)
212246

213247
expected_ds_info = {
214248
'experiment': '2d_softsweep',
215249
'sample': 'no sample',
216-
'completed_date': completed_date,
217-
'completed_time': completed_time,
218-
'started_date': started_date,
219-
'started_time': started_time,
250+
'completed_date': completed.strftime('%Y-%m-%d'),
251+
'completed_time': completed.strftime('%H:%M:%S'),
252+
'started_date': started.strftime('%Y-%m-%d'),
253+
'started_time': started.strftime('%H:%M:%S'),
220254
'name': 'results',
221255
'structure': None,
222256
'records': 0,

0 commit comments

Comments
 (0)