Skip to content

Commit

Permalink
Merge pull request #173 from 0Hughman0/tz-aware
Browse files Browse the repository at this point in the history
Switching started to be timezone aware.
  • Loading branch information
0Hughman0 authored Sep 23, 2024
2 parents 0fc3f96 + 0dfb078 commit f849725
Show file tree
Hide file tree
Showing 8 changed files with 59 additions and 11 deletions.
6 changes: 3 additions & 3 deletions cassini/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
from typing_extensions import Self

import jinja2
from pydantic import JsonValue
from pydantic import JsonValue, AwareDatetime

from .meta import Meta, MetaManager
from .accessors import cached_prop, cached_class_prop, soft_prop
Expand Down Expand Up @@ -539,7 +539,7 @@ def setup_files(

print("Writing Meta Data")

self.started = datetime.datetime.now()
self.started = datetime.datetime.now(datetime.timezone.utc)

print("Success")

Expand All @@ -563,7 +563,7 @@ def exists(self) -> bool:

description = manager.meta_attr(str, str, cas_field="core")
conclusion = manager.meta_attr(str, str, cas_field="core")
started = manager.meta_attr(datetime.datetime, datetime.datetime, cas_field="core")
started = manager.meta_attr(AwareDatetime, datetime.datetime, cas_field="core")

@cached_prop
def meta_file(self) -> Path:
Expand Down
4 changes: 3 additions & 1 deletion cassini/migrate/V0_2toV0_3.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,9 @@ def migrate_meta(self, tier):
started = meta.get("started")

if started:
started_dt = datetime.datetime.strptime(started, "%d/%m/%Y")
started_dt = datetime.datetime.strptime(
started, "%d/%m/%Y"
).astimezone() # assume local timezone.
meta["started"] = str(started_dt)

with open(tier.meta_file, "w") as fs:
Expand Down
14 changes: 12 additions & 2 deletions cassini/testing_utils.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
from typing import Sequence
from typing import Sequence, Tuple, Callable

from cassini import (
Home,
Expand Down Expand Up @@ -43,7 +43,17 @@ class Tier(NotebookTierBase):


@pytest.fixture
def patched_default_project(get_Project, tmp_path):
def patched_default_project(
get_Project, tmp_path
) -> Tuple[Project, Callable[[Sequence[str]], Sequence[TierABC]]]:
"""
Returns
-------
project: Project
The fresh
create_tiers: Callable[[Sequence[str]], Sequence[TierABC]]
function for creating tiers by a list of names. Returns each pre-setup tier in order.
"""
Project = get_Project

project = Project(DEFAULT_TIERS, tmp_path)
Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "cassini"
version = "0.3.0a8"
version = "0.3.0a9"
description = "A tool to structure experimental work, data and analysis using Jupyter Lab."
authors = ["0Hughman0 <[email protected]>"]
license = "GPL-3.0-only"
Expand Down
1 change: 1 addition & 0 deletions tests/migrate/test_zero_two.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ def test_update_meta(get_migrator):
migrator.migrate_meta(WP1)
assert '/' not in json.loads(WP1.meta_file.read_text())['started']
assert isinstance(WP1.started, datetime.datetime)
assert WP1.started.tzinfo == datetime.datetime.now().astimezone().tzinfo


def test_full_migrate(get_migrator):
Expand Down
37 changes: 36 additions & 1 deletion tests/test_meta.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import json
import pathlib
import datetime

import pytest # type: ignore[import]
from cassini import HomeTierBase, NotebookTierBase
from cassini.meta import MetaAttr, MetaManager, Meta, MetaCache
from cassini.testing_utils import get_Project, patch_project
from cassini.testing_utils import get_Project, patch_project, patched_default_project

import pydantic

Expand Down Expand Up @@ -191,6 +192,40 @@ class Second(NotebookTierBase):
assert obj2.meta is obj2.__meta_manager__.metas[obj2]


def test_started_is_utc(patched_default_project):
project, create_tiers = patched_default_project

WP1, = create_tiers(['WP1'])

assert WP1.started.tzinfo == datetime.timezone.utc


def test_started_requires_timezone(patched_default_project):
project, create_tiers = patched_default_project

WP1, = create_tiers(['WP1'])

with pytest.raises(pydantic.ValidationError):
WP1.started = datetime.datetime.now()


def test_dumped_started_includes_timezone(patched_default_project):
project, create_tiers = patched_default_project
WP1, = create_tiers(['WP1'])

assert 'Z' in json.loads(WP1.meta._cache.model_dump_json())['started']


def test_non_utc_timezones(patched_default_project):
project, create_tiers = patched_default_project
WP1, = create_tiers(['WP1'])

WP1.started = datetime.datetime.fromisoformat('2011-11-04T00:05:23+04:00')
WP1.started.utcoffset() == datetime.timedelta(hours=4)

assert '+04:00' in json.loads(WP1.meta._cache.model_dump_json())['started']


def test_meta_attr_discovery(get_Project, tmp_path):
Project = get_Project
class First(HomeTierBase):
Expand Down
2 changes: 1 addition & 1 deletion tests/test_sharing.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ def test_meta_wrapping(get_Project, tmp_path):

assert stier.conclusion == 'c'

now = datetime.datetime.now()
now = datetime.datetime.now(datetime.timezone.utc)

stier.started = now

Expand Down
4 changes: 2 additions & 2 deletions tests/test_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ def test_make_child(mk_project):
assert not second.exists()
assert list(home) == []

before = datetime.datetime.now()
before = datetime.datetime.now(datetime.timezone.utc)
second.setup_files()
after = datetime.datetime.now()
after = datetime.datetime.now(datetime.timezone.utc)

assert before <= second.started <= after
assert second.exists()
Expand Down

0 comments on commit f849725

Please sign in to comment.