Compare commits
No commits in common. "fc9844f1ca9235068296379d2785f50799a8fca7" and "1a3756f47ce05576cb06bff0f8b4a31da7928ed0" have entirely different histories.
fc9844f1ca
...
1a3756f47c
11 changed files with 22 additions and 316 deletions
|
|
@ -5,13 +5,6 @@ All notable changes to WuttJamaican will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
|
||||||
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
## v0.25.0 (2025-12-15)
|
|
||||||
|
|
||||||
### Feat
|
|
||||||
|
|
||||||
- drop timezone, assume UTC for all datetime values in DB
|
|
||||||
- add `make_utc()` function, app method
|
|
||||||
|
|
||||||
## v0.24.1 (2025-10-29)
|
## v0.24.1 (2025-10-29)
|
||||||
|
|
||||||
### Fix
|
### Fix
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ build-backend = "hatchling.build"
|
||||||
|
|
||||||
[project]
|
[project]
|
||||||
name = "WuttJamaican"
|
name = "WuttJamaican"
|
||||||
version = "0.25.0"
|
version = "0.24.1"
|
||||||
description = "Base package for Wutta Framework"
|
description = "Base package for Wutta Framework"
|
||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
|
authors = [{name = "Lance Edgar", email = "lance@wuttaproject.org"}]
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,6 @@ from wuttjamaican.util import (
|
||||||
load_object,
|
load_object,
|
||||||
make_title,
|
make_title,
|
||||||
make_full_name,
|
make_full_name,
|
||||||
make_utc,
|
|
||||||
make_uuid,
|
make_uuid,
|
||||||
make_true_uuid,
|
make_true_uuid,
|
||||||
progress_loop,
|
progress_loop,
|
||||||
|
|
@ -527,14 +526,6 @@ class AppHandler: # pylint: disable=too-many-public-methods
|
||||||
"""
|
"""
|
||||||
return make_full_name(*parts)
|
return make_full_name(*parts)
|
||||||
|
|
||||||
def make_utc(self, dt=None, tzinfo=False):
|
|
||||||
"""
|
|
||||||
This returns a datetime local to the UTC timezone. It is a
|
|
||||||
convenience wrapper around
|
|
||||||
:func:`~wuttjamaican.util.make_utc()`.
|
|
||||||
"""
|
|
||||||
return make_utc(dt=dt, tzinfo=tzinfo)
|
|
||||||
|
|
||||||
def make_true_uuid(self):
|
def make_true_uuid(self):
|
||||||
"""
|
"""
|
||||||
Generate a new UUID value.
|
Generate a new UUID value.
|
||||||
|
|
@ -862,8 +853,7 @@ class AppHandler: # pylint: disable=too-many-public-methods
|
||||||
|
|
||||||
:returns: Text to display.
|
:returns: Text to display.
|
||||||
"""
|
"""
|
||||||
# TODO: this now assumes naive UTC value incoming...
|
return humanize.naturaltime(value)
|
||||||
return humanize.naturaltime(value, when=self.make_utc(tzinfo=False))
|
|
||||||
|
|
||||||
##############################
|
##############################
|
||||||
# getters for other handlers
|
# getters for other handlers
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@
|
||||||
Batch Handlers
|
Batch Handlers
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
import os
|
import os
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
|
|
@ -480,7 +481,7 @@ class BatchHandler(GenericHandler): # pylint: disable=too-many-public-methods
|
||||||
result = self.execute( # pylint: disable=assignment-from-none
|
result = self.execute( # pylint: disable=assignment-from-none
|
||||||
batch, user=user, progress=progress, **kwargs
|
batch, user=user, progress=progress, **kwargs
|
||||||
)
|
)
|
||||||
batch.executed = self.app.make_utc()
|
batch.executed = datetime.datetime.now()
|
||||||
batch.executed_by = user
|
batch.executed_by = user
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,186 +0,0 @@
|
||||||
"""drop time zones
|
|
||||||
|
|
||||||
Revision ID: b59a34266288
|
|
||||||
Revises: efdcb2c75034
|
|
||||||
Create Date: 2025-12-14 19:10:11.627188
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
from typing import Sequence, Union
|
|
||||||
|
|
||||||
from alembic import op
|
|
||||||
import sqlalchemy as sa
|
|
||||||
import wuttjamaican.db.util
|
|
||||||
from sqlalchemy.dialects import postgresql
|
|
||||||
from wuttjamaican.util import make_utc
|
|
||||||
|
|
||||||
# revision identifiers, used by Alembic.
|
|
||||||
revision: str = "b59a34266288"
|
|
||||||
down_revision: Union[str, None] = "efdcb2c75034"
|
|
||||||
branch_labels: Union[str, Sequence[str], None] = None
|
|
||||||
depends_on: Union[str, Sequence[str], None] = None
|
|
||||||
|
|
||||||
|
|
||||||
def upgrade() -> None:
|
|
||||||
|
|
||||||
# upgrade.created
|
|
||||||
op.add_column("upgrade", sa.Column("created_new", sa.DateTime(), nullable=True))
|
|
||||||
upgrade = sa.sql.table(
|
|
||||||
"upgrade",
|
|
||||||
sa.sql.column("uuid"),
|
|
||||||
sa.sql.column("created"),
|
|
||||||
sa.sql.column("created_new"),
|
|
||||||
)
|
|
||||||
cursor = op.get_bind().execute(upgrade.select())
|
|
||||||
for row in cursor.fetchall():
|
|
||||||
op.get_bind().execute(
|
|
||||||
upgrade.update()
|
|
||||||
.where(upgrade.c.uuid == row.uuid)
|
|
||||||
.values({"created_new": make_utc(row.created)})
|
|
||||||
)
|
|
||||||
op.drop_column("upgrade", "created")
|
|
||||||
op.alter_column(
|
|
||||||
"upgrade",
|
|
||||||
"created_new",
|
|
||||||
new_column_name="created",
|
|
||||||
nullable=False,
|
|
||||||
existing_type=sa.DateTime(),
|
|
||||||
existing_nullable=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# upgrade.executed
|
|
||||||
op.add_column("upgrade", sa.Column("executed_new", sa.DateTime(), nullable=True))
|
|
||||||
upgrade = sa.sql.table(
|
|
||||||
"upgrade",
|
|
||||||
sa.sql.column("uuid"),
|
|
||||||
sa.sql.column("executed"),
|
|
||||||
sa.sql.column("executed_new"),
|
|
||||||
)
|
|
||||||
cursor = op.get_bind().execute(upgrade.select())
|
|
||||||
for row in cursor.fetchall():
|
|
||||||
if row.executed:
|
|
||||||
op.get_bind().execute(
|
|
||||||
upgrade.update()
|
|
||||||
.where(upgrade.c.uuid == row.uuid)
|
|
||||||
.values({"executed_new": make_utc(row.executed)})
|
|
||||||
)
|
|
||||||
op.drop_column("upgrade", "executed")
|
|
||||||
op.alter_column(
|
|
||||||
"upgrade",
|
|
||||||
"executed_new",
|
|
||||||
new_column_name="executed",
|
|
||||||
existing_type=sa.DateTime(),
|
|
||||||
existing_nullable=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# user_api_token.created
|
|
||||||
op.add_column(
|
|
||||||
"user_api_token", sa.Column("created_new", sa.DateTime(), nullable=True)
|
|
||||||
)
|
|
||||||
user_api_token = sa.sql.table(
|
|
||||||
"user_api_token",
|
|
||||||
sa.sql.column("uuid"),
|
|
||||||
sa.sql.column("created"),
|
|
||||||
sa.sql.column("created_new"),
|
|
||||||
)
|
|
||||||
cursor = op.get_bind().execute(user_api_token.select())
|
|
||||||
for row in cursor.fetchall():
|
|
||||||
op.get_bind().execute(
|
|
||||||
user_api_token.update()
|
|
||||||
.where(user_api_token.c.uuid == row.uuid)
|
|
||||||
.values({"created_new": make_utc(row.created)})
|
|
||||||
)
|
|
||||||
op.drop_column("user_api_token", "created")
|
|
||||||
op.alter_column(
|
|
||||||
"user_api_token",
|
|
||||||
"created_new",
|
|
||||||
new_column_name="created",
|
|
||||||
nullable=False,
|
|
||||||
existing_type=sa.DateTime(),
|
|
||||||
existing_nullable=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
def downgrade() -> None:
|
|
||||||
|
|
||||||
# user_api_token.created
|
|
||||||
op.add_column(
|
|
||||||
"user_api_token",
|
|
||||||
sa.Column("created_old", sa.DateTime(timezone=True), nullable=True),
|
|
||||||
)
|
|
||||||
user_api_token = sa.sql.table(
|
|
||||||
"user_api_token",
|
|
||||||
sa.sql.column("uuid"),
|
|
||||||
sa.sql.column("created"),
|
|
||||||
sa.sql.column("created_old"),
|
|
||||||
)
|
|
||||||
cursor = op.get_bind().execute(user_api_token.select())
|
|
||||||
for row in cursor.fetchall():
|
|
||||||
op.get_bind().execute(
|
|
||||||
user_api_token.update()
|
|
||||||
.where(user_api_token.c.uuid == row.uuid)
|
|
||||||
.values({"created_old": row.created})
|
|
||||||
)
|
|
||||||
op.drop_column("user_api_token", "created")
|
|
||||||
op.alter_column(
|
|
||||||
"user_api_token",
|
|
||||||
"created_old",
|
|
||||||
new_column_name="created",
|
|
||||||
nullable=False,
|
|
||||||
existing_type=sa.DateTime(timezone=True),
|
|
||||||
existing_nullable=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# upgrade.executed
|
|
||||||
op.add_column(
|
|
||||||
"upgrade", sa.Column("executed_old", sa.DateTime(timezone=True), nullable=True)
|
|
||||||
)
|
|
||||||
upgrade = sa.sql.table(
|
|
||||||
"upgrade",
|
|
||||||
sa.sql.column("uuid"),
|
|
||||||
sa.sql.column("executed"),
|
|
||||||
sa.sql.column("executed_old"),
|
|
||||||
)
|
|
||||||
cursor = op.get_bind().execute(upgrade.select())
|
|
||||||
for row in cursor.fetchall():
|
|
||||||
if row.executed:
|
|
||||||
op.get_bind().execute(
|
|
||||||
upgrade.update()
|
|
||||||
.where(upgrade.c.uuid == row.uuid)
|
|
||||||
.values({"executed_old": row.executed})
|
|
||||||
)
|
|
||||||
op.drop_column("upgrade", "executed")
|
|
||||||
op.alter_column(
|
|
||||||
"upgrade",
|
|
||||||
"executed_old",
|
|
||||||
new_column_name="executed",
|
|
||||||
existing_type=sa.DateTime(timezone=True),
|
|
||||||
existing_nullable=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
# upgrade.created
|
|
||||||
op.add_column(
|
|
||||||
"upgrade", sa.Column("created_old", sa.DateTime(timezone=True), nullable=True)
|
|
||||||
)
|
|
||||||
upgrade = sa.sql.table(
|
|
||||||
"upgrade",
|
|
||||||
sa.sql.column("uuid"),
|
|
||||||
sa.sql.column("created"),
|
|
||||||
sa.sql.column("created_old"),
|
|
||||||
)
|
|
||||||
cursor = op.get_bind().execute(upgrade.select())
|
|
||||||
for row in cursor.fetchall():
|
|
||||||
op.get_bind().execute(
|
|
||||||
upgrade.update()
|
|
||||||
.where(upgrade.c.uuid == row.uuid)
|
|
||||||
.values({"created_old": row.created})
|
|
||||||
)
|
|
||||||
op.drop_column("upgrade", "created")
|
|
||||||
op.alter_column(
|
|
||||||
"upgrade",
|
|
||||||
"created_old",
|
|
||||||
new_column_name="created",
|
|
||||||
nullable=False,
|
|
||||||
existing_type=sa.DateTime(timezone=True),
|
|
||||||
existing_nullable=True,
|
|
||||||
)
|
|
||||||
|
|
@ -39,13 +39,14 @@ So a user's permissions are "inherited" from the role(s) to which they
|
||||||
belong.
|
belong.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
from sqlalchemy.ext.associationproxy import association_proxy
|
from sqlalchemy.ext.associationproxy import association_proxy
|
||||||
|
|
||||||
from wuttjamaican.db.util import uuid_column, uuid_fk_column
|
from wuttjamaican.db.util import uuid_column, uuid_fk_column
|
||||||
from wuttjamaican.db.model.base import Base
|
from wuttjamaican.db.model.base import Base
|
||||||
from wuttjamaican.util import make_utc
|
|
||||||
|
|
||||||
|
|
||||||
class Role(Base): # pylint: disable=too-few-public-methods
|
class Role(Base): # pylint: disable=too-few-public-methods
|
||||||
|
|
@ -342,9 +343,9 @@ class UserAPIToken(Base): # pylint: disable=too-few-public-methods
|
||||||
)
|
)
|
||||||
|
|
||||||
created = sa.Column(
|
created = sa.Column(
|
||||||
sa.DateTime(),
|
sa.DateTime(timezone=True),
|
||||||
nullable=False,
|
nullable=False,
|
||||||
default=make_utc,
|
default=datetime.datetime.now,
|
||||||
doc="""
|
doc="""
|
||||||
Date/time when the token was created.
|
Date/time when the token was created.
|
||||||
""",
|
""",
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,6 @@ from sqlalchemy.ext.orderinglist import ordering_list
|
||||||
from wuttjamaican.db.model.base import uuid_column
|
from wuttjamaican.db.model.base import uuid_column
|
||||||
from wuttjamaican.db.model.auth import User
|
from wuttjamaican.db.model.auth import User
|
||||||
from wuttjamaican.db.util import UUID
|
from wuttjamaican.db.util import UUID
|
||||||
from wuttjamaican.util import make_utc
|
|
||||||
|
|
||||||
|
|
||||||
class BatchMixin:
|
class BatchMixin:
|
||||||
|
|
@ -224,7 +223,9 @@ class BatchMixin:
|
||||||
status_code = sa.Column(sa.Integer(), nullable=True)
|
status_code = sa.Column(sa.Integer(), nullable=True)
|
||||||
status_text = sa.Column(sa.String(length=255), nullable=True)
|
status_text = sa.Column(sa.String(length=255), nullable=True)
|
||||||
|
|
||||||
created = sa.Column(sa.DateTime(), nullable=False, default=make_utc)
|
created = sa.Column(
|
||||||
|
sa.DateTime(timezone=True), nullable=False, default=datetime.datetime.now
|
||||||
|
)
|
||||||
created_by_uuid = sa.Column(UUID(), nullable=False)
|
created_by_uuid = sa.Column(UUID(), nullable=False)
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
|
|
@ -237,7 +238,7 @@ class BatchMixin:
|
||||||
cascade_backrefs=False,
|
cascade_backrefs=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
executed = sa.Column(sa.DateTime(), nullable=True)
|
executed = sa.Column(sa.DateTime(timezone=True), nullable=True)
|
||||||
executed_by_uuid = sa.Column(UUID(), nullable=True)
|
executed_by_uuid = sa.Column(UUID(), nullable=True)
|
||||||
|
|
||||||
@declared_attr
|
@declared_attr
|
||||||
|
|
@ -427,5 +428,8 @@ class BatchRowMixin: # pylint: disable=too-few-public-methods
|
||||||
status_text = sa.Column(sa.String(length=255), nullable=True)
|
status_text = sa.Column(sa.String(length=255), nullable=True)
|
||||||
|
|
||||||
modified = sa.Column(
|
modified = sa.Column(
|
||||||
sa.DateTime(), nullable=True, default=make_utc, onupdate=make_utc
|
sa.DateTime(timezone=True),
|
||||||
|
nullable=True,
|
||||||
|
default=datetime.datetime.now,
|
||||||
|
onupdate=datetime.datetime.now,
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,14 @@
|
||||||
Upgrade Model
|
Upgrade Model
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from sqlalchemy import orm
|
from sqlalchemy import orm
|
||||||
|
|
||||||
from wuttjamaican.enum import UpgradeStatus
|
from wuttjamaican.enum import UpgradeStatus
|
||||||
from wuttjamaican.db.util import uuid_column, uuid_fk_column
|
from wuttjamaican.db.util import uuid_column, uuid_fk_column
|
||||||
from wuttjamaican.db.model.base import Base
|
from wuttjamaican.db.model.base import Base
|
||||||
from wuttjamaican.util import make_utc
|
|
||||||
|
|
||||||
|
|
||||||
class Upgrade(Base): # pylint: disable=too-few-public-methods
|
class Upgrade(Base): # pylint: disable=too-few-public-methods
|
||||||
|
|
@ -43,9 +44,9 @@ class Upgrade(Base): # pylint: disable=too-few-public-methods
|
||||||
uuid = uuid_column()
|
uuid = uuid_column()
|
||||||
|
|
||||||
created = sa.Column(
|
created = sa.Column(
|
||||||
sa.DateTime(),
|
sa.DateTime(timezone=True),
|
||||||
nullable=False,
|
nullable=False,
|
||||||
default=make_utc,
|
default=datetime.datetime.now,
|
||||||
doc="""
|
doc="""
|
||||||
When the upgrade record was created.
|
When the upgrade record was created.
|
||||||
""",
|
""",
|
||||||
|
|
@ -97,7 +98,7 @@ class Upgrade(Base): # pylint: disable=too-few-public-methods
|
||||||
)
|
)
|
||||||
|
|
||||||
executed = sa.Column(
|
executed = sa.Column(
|
||||||
sa.DateTime(),
|
sa.DateTime(timezone=True),
|
||||||
nullable=True,
|
nullable=True,
|
||||||
doc="""
|
doc="""
|
||||||
When the upgrade was executed.
|
When the upgrade was executed.
|
||||||
|
|
|
||||||
|
|
@ -24,7 +24,6 @@
|
||||||
WuttJamaican - utilities
|
WuttJamaican - utilities
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import datetime
|
|
||||||
import importlib
|
import importlib
|
||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
@ -190,50 +189,6 @@ def make_full_name(*parts):
|
||||||
return " ".join(parts)
|
return " ".join(parts)
|
||||||
|
|
||||||
|
|
||||||
def make_utc(dt=None, tzinfo=False):
|
|
||||||
"""
|
|
||||||
This returns a datetime local to the UTC timezone. By default it
|
|
||||||
will be a *naive* datetime; the common use case is to convert as
|
|
||||||
needed for sake of writing to the database.
|
|
||||||
|
|
||||||
See also the shortcut
|
|
||||||
:meth:`~wuttjamaican.app.AppHandler.make_utc()` method on the app
|
|
||||||
handler.
|
|
||||||
|
|
||||||
:param dt: Optional :class:`python:datetime.datetime` instance.
|
|
||||||
If not specified, the current time will be used.
|
|
||||||
|
|
||||||
:param tzinfo: Boolean indicating whether the return value should
|
|
||||||
have its :attr:`~python:datetime.datetime.tzinfo` attribute
|
|
||||||
set. This is false by default in which case the return value
|
|
||||||
will be naive.
|
|
||||||
|
|
||||||
:returns: :class:`python:datetime.datetime` instance local to UTC.
|
|
||||||
"""
|
|
||||||
# use current time if none provided
|
|
||||||
if dt is None:
|
|
||||||
now = datetime.datetime.now(datetime.timezone.utc)
|
|
||||||
if tzinfo:
|
|
||||||
return now
|
|
||||||
return now.replace(tzinfo=None)
|
|
||||||
|
|
||||||
# otherwise may need to convert timezone
|
|
||||||
if dt.tzinfo:
|
|
||||||
if dt.tzinfo is not datetime.timezone.utc:
|
|
||||||
dt = dt.astimezone(datetime.timezone.utc)
|
|
||||||
if tzinfo:
|
|
||||||
return dt
|
|
||||||
return dt.replace(tzinfo=None)
|
|
||||||
|
|
||||||
# naive value returned as-is..
|
|
||||||
if not tzinfo:
|
|
||||||
return dt
|
|
||||||
|
|
||||||
# ..unless tzinfo is wanted, in which case this assumes naive
|
|
||||||
# value is in the UTC timezone
|
|
||||||
return dt.replace(tzinfo=datetime.timezone.utc)
|
|
||||||
|
|
||||||
|
|
||||||
def make_true_uuid():
|
def make_true_uuid():
|
||||||
"""
|
"""
|
||||||
Generate a new v7 UUID value.
|
Generate a new v7 UUID value.
|
||||||
|
|
|
||||||
|
|
@ -426,11 +426,6 @@ app_title = WuttaTest
|
||||||
name = self.app.make_full_name("Fred", "", "Flintstone", "")
|
name = self.app.make_full_name("Fred", "", "Flintstone", "")
|
||||||
self.assertEqual(name, "Fred Flintstone")
|
self.assertEqual(name, "Fred Flintstone")
|
||||||
|
|
||||||
def test_make_utc(self):
|
|
||||||
dt = self.app.make_utc()
|
|
||||||
self.assertIsInstance(dt, datetime.datetime)
|
|
||||||
self.assertIsNone(dt.tzinfo)
|
|
||||||
|
|
||||||
def test_make_uuid(self):
|
def test_make_uuid(self):
|
||||||
uuid = self.app.make_uuid()
|
uuid = self.app.make_uuid()
|
||||||
self.assertEqual(len(uuid), 32)
|
self.assertEqual(len(uuid), 32)
|
||||||
|
|
@ -571,7 +566,7 @@ app_title = WuttaTest
|
||||||
now = datetime.datetime.now()
|
now = datetime.datetime.now()
|
||||||
result = self.app.render_time_ago(now)
|
result = self.app.render_time_ago(now)
|
||||||
self.assertEqual(result, "now")
|
self.assertEqual(result, "now")
|
||||||
humanize.naturaltime.assert_called_once()
|
humanize.naturaltime.assert_called_once_with(now)
|
||||||
|
|
||||||
def test_get_person(self):
|
def test_get_person(self):
|
||||||
people = self.app.get_people_handler()
|
people = self.app.get_people_handler()
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
# -*- coding: utf-8; -*-
|
# -*- coding: utf-8; -*-
|
||||||
|
|
||||||
import datetime
|
|
||||||
import sys
|
import sys
|
||||||
from unittest import TestCase
|
from unittest import TestCase
|
||||||
from unittest.mock import patch, MagicMock
|
from unittest.mock import patch, MagicMock
|
||||||
|
|
@ -165,53 +164,6 @@ class TestLoadObject(TestCase):
|
||||||
self.assertIs(result, TestCase)
|
self.assertIs(result, TestCase)
|
||||||
|
|
||||||
|
|
||||||
class TestMakeUTC(TestCase):
|
|
||||||
|
|
||||||
def test_current_time(self):
|
|
||||||
|
|
||||||
# no tzinfo by default
|
|
||||||
dt = mod.make_utc()
|
|
||||||
self.assertIsInstance(dt, datetime.datetime)
|
|
||||||
self.assertIsNone(dt.tzinfo)
|
|
||||||
now = datetime.datetime.now(datetime.timezone.utc).replace(tzinfo=None)
|
|
||||||
self.assertAlmostEqual(int(dt.timestamp()), int(now.timestamp()))
|
|
||||||
|
|
||||||
# with tzinfo
|
|
||||||
dt = mod.make_utc(tzinfo=True)
|
|
||||||
self.assertIsInstance(dt, datetime.datetime)
|
|
||||||
self.assertIs(dt.tzinfo, datetime.timezone.utc)
|
|
||||||
now = datetime.datetime.now(datetime.timezone.utc)
|
|
||||||
self.assertAlmostEqual(int(dt.timestamp()), int(now.timestamp()))
|
|
||||||
|
|
||||||
def test_convert_with_tzinfo(self):
|
|
||||||
sample = datetime.datetime(
|
|
||||||
2024, 9, 15, 8, 30, tzinfo=datetime.timezone(-datetime.timedelta(hours=5))
|
|
||||||
)
|
|
||||||
|
|
||||||
# no tzinfo by default
|
|
||||||
dt = mod.make_utc(sample)
|
|
||||||
self.assertEqual(dt, datetime.datetime(2024, 9, 15, 13, 30, tzinfo=None))
|
|
||||||
|
|
||||||
# with tzinfo
|
|
||||||
dt = mod.make_utc(sample, tzinfo=True)
|
|
||||||
self.assertEqual(
|
|
||||||
dt, datetime.datetime(2024, 9, 15, 13, 30, tzinfo=datetime.timezone.utc)
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_convert_without_tzinfo(self):
|
|
||||||
sample = datetime.datetime(2024, 9, 15, 8, 30)
|
|
||||||
|
|
||||||
# no tzinfo by default
|
|
||||||
dt = mod.make_utc(sample)
|
|
||||||
self.assertEqual(dt, datetime.datetime(2024, 9, 15, 8, 30, tzinfo=None))
|
|
||||||
|
|
||||||
# with tzinfo
|
|
||||||
dt = mod.make_utc(sample, tzinfo=True)
|
|
||||||
self.assertEqual(
|
|
||||||
dt, datetime.datetime(2024, 9, 15, 8, 30, tzinfo=datetime.timezone.utc)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TestMakeUUID(TestCase):
|
class TestMakeUUID(TestCase):
|
||||||
|
|
||||||
def test_basic(self):
|
def test_basic(self):
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue