Skip to content

Commit

Permalink
datetime gui tests
Browse files Browse the repository at this point in the history
  • Loading branch information
e3rd committed Dec 16, 2024
1 parent fad9931 commit 7f72c3a
Show file tree
Hide file tree
Showing 8 changed files with 23 additions and 16 deletions.
2 changes: 1 addition & 1 deletion docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ The config variables needed by your program are kept in cozy dataclasses. Write
Install with a single command from [PyPi](https://pypi.org/project/mininterface/).

```bash
pip install mininterface
pip install mininterface[all] # GPLv3 and compatible
```

## Minimal installation
Expand Down
4 changes: 2 additions & 2 deletions mininterface/tag.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from ast import literal_eval
from dataclasses import dataclass, fields
from datetime import datetime
from datetime import date, time
from enum import Enum
from types import FunctionType, MethodType, NoneType, UnionType
from typing import TYPE_CHECKING, Any, Callable, Iterable, Optional, Type, TypeVar, Union, get_args, get_origin
Expand Down Expand Up @@ -683,7 +683,7 @@ def update(self, ui_value: TagValue) -> bool:
except (SyntaxError, ValueError):
self.set_error_text(f"Not a valid {self._repr_annotation()}")
return False
elif self.annotation is datetime:
elif self._is_subclass((time, date)):
try:
out_value = self.annotation.fromisoformat(ui_value)
except ValueError:
Expand Down
6 changes: 5 additions & 1 deletion mininterface/tag_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,11 @@ def tag_factory(val=None, description=None, annotation=None, *args, _src_obj=Non
new = copy(metadata)
new.val = val if val is not None else new.val
new.description = description or new.description
return new._fetch_from(Tag(*args, **kwargs))
if new.annotation is None:
# pAnnot: Annotated[date, Tag(name="hello")] = datetime.fromisoformat(...)
# -> DatetimeTag(date=True)
new.annotation = annotation
return tag_assure_type(new._fetch_from(Tag(*args, **kwargs)))
# NOTE The mechanism is not perfect. When done, we may test configs.PathTagClass.
# * fetch_from will not transfer PathTag.multiple
# * copy will not transfer list[Path] from `Annotated[list[Path], Tag(...)]`
Expand Down
7 changes: 2 additions & 5 deletions mininterface/tk_interface/date_entry.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@


class DateEntryFrame(tk.Frame):
last_date_entry_frame = None

def __init__(self, master, tk_app: "TkWindow", tag: DatetimeTag, variable: tk.Variable, **kwargs):
super().__init__(master, **kwargs)
Expand All @@ -34,7 +33,6 @@ def __init__(self, master, tk_app: "TkWindow", tag: DatetimeTag, variable: tk.Va
else:
self.datetimeformat = '%Y-%m-%d'


# Date entry
self.spinbox = self.create_spinbox(variable)

Expand All @@ -53,7 +51,6 @@ def __init__(self, master, tk_app: "TkWindow", tag: DatetimeTag, variable: tk.Va
self.calendar.grid()
# Initialize calendar with the current date
self.update_calendar(self.spinbox.get(), self.datetimeformat)
DateEntryFrame.last_date_entry_frame = self
else:
self.calendar = None

Expand Down Expand Up @@ -172,10 +169,10 @@ def increment_part(self, split_input, caret_pos, delta, separator):

if self.tag.full_precision and separator == ' ':
return f"{split_input[0]}-{split_input[1]}-{split_input[2]} "\
f"{split_input[3]}:{split_input[4]}:{split_input[5]}.{split_input[6]}"
f"{split_input[3]}:{split_input[4]}:{split_input[5]}.{split_input[6]}"
elif separator == ' ':
return f"{split_input[0]}-{split_input[1]}-{split_input[2]} "\
f"{split_input[3]}:{split_input[4]}:{split_input[5]}"
f"{split_input[3]}:{split_input[4]}:{split_input[5]}"
elif separator == ':':
if self.tag.full_precision:
return f"{split_input[0]}:{split_input[1]}:{split_input[2]}.{split_input[3]}"
Expand Down
2 changes: 1 addition & 1 deletion mininterface/tk_interface/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ def _fetch(variable):
# Calendar
elif isinstance(tag, DatetimeTag):
grid_info = widget.grid_info()
widget.grid_forget() # HERE
widget.grid_forget()
nested_frame = DateEntryFrame(master, tk_app, tag, variable)
nested_frame.grid(row=grid_info['row'], column=grid_info['column'])
widget = nested_frame.spinbox
Expand Down
8 changes: 4 additions & 4 deletions mininterface/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -222,17 +222,17 @@ class Env:
time: bool = False
""" The time part is active """

full_precision: Optional[bool] = None
full_precision: bool = False
""" Include full time precison, seconds, microseconds. """

def __post_init__(self):
super().__post_init__()
if self.annotation:
self.date = issubclass(self.annotation, date)
self.time = issubclass(self.annotation, time) or issubclass(self.annotation, datetime)
if not self.time and self.full_precision:
self.full_precision = False
# NOTE: self.full_precision ...
# NOTE: remove
# if not self.time and self.full_precision:
# self.full_precision = False

def _make_default_value(self):
return datetime.now()
1 change: 1 addition & 0 deletions tests/configs.py
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,7 @@ class DatetimeTagClass:
p1: datetime = datetime.fromisoformat("2024-09-10 17:35:39.922044")
p2: time = time.fromisoformat("17:35:39.922044")
p3: date = date.fromisoformat("2024-09-10")
pAnnot: Annotated[date, Tag(name="hello")] = datetime.fromisoformat("2024-09-10 17:35:39.922044")


@dataclass
Expand Down
9 changes: 7 additions & 2 deletions tests/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import os
import sys
from contextlib import contextmanager, redirect_stderr, redirect_stdout
from datetime import datetime
from datetime import datetime, date
from io import StringIO
from pathlib import Path, PosixPath
from types import NoneType, SimpleNamespace
Expand Down Expand Up @@ -551,13 +551,18 @@ class TestTypes(TestAbstract):
def test_datetime_tag(self):
m = runm(DatetimeTagClass)
d = dataclass_to_tagdict(m.env)[""]
for key, expected_date, expected_time in [("p1", True, True), ("p2", False, True), ("p3", True, False)]:
d["extern"] = dict_to_tagdict({"extern": date.fromisoformat("2024-09-10")})["extern"]

for key, expected_date, expected_time in [("p1", True, True), ("p2", False, True), ("p3", True, False),
("pAnnot", True, False),
("extern", True, False)]:
tag = d[key]
self.assertIsInstance(tag, DatetimeTag)
self.assertEqual(expected_date, tag.date)
self.assertEqual(expected_time, tag.time)



class TestRun(TestAbstract):
def test_run_ask_empty(self):
with self.assertOutputs("Asking the form SimpleEnv(test=False, important_number=4)"):
Expand Down

0 comments on commit 7f72c3a

Please sign in to comment.