Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[#9791] Fix datetime.datetime.utcnow() is deprecated as of Python 3.12 #9839

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/Fixes-20240329-223653.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: Fixes
body: datetime.datetime.utcnow() is deprecated as of Python 3.12
time: 2024-03-29T22:36:53.504295426+01:00
custom:
Author: slothkong
Issue: "9791"
2 changes: 1 addition & 1 deletion core/dbt/artifacts/schemas/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ def read(cls, path: str):
class BaseArtifactMetadata(dbtClassMixin):
dbt_schema_version: str
dbt_version: str = __version__
generated_at: datetime = dataclasses.field(default_factory=datetime.utcnow)
generated_at: datetime = dataclasses.field(default_factory=datetime.now)
invocation_id: Optional[str] = dataclasses.field(default_factory=get_invocation_id)
env: Dict[str, str] = dataclasses.field(default_factory=get_metadata_vars)

Expand Down
6 changes: 3 additions & 3 deletions core/dbt/artifacts/schemas/results.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
from dbt_common.dataclass_schema import dbtClassMixin, StrEnum

from dataclasses import dataclass
from datetime import datetime
from datetime import timezone, datetime
from typing import Any, Callable, Dict, List, Optional, Sequence, Union


Expand All @@ -19,10 +19,10 @@ class TimingInfo(dbtClassMixin):
completed_at: Optional[datetime] = None

def begin(self):
self.started_at = datetime.utcnow()
self.started_at = datetime.now(timezone.utc).replace(tzinfo=None)

def end(self):
self.completed_at = datetime.utcnow()
self.completed_at = datetime.now(timezone.utc).replace(tzinfo=None)

def to_msg_dict(self):
msg_dict = {"name": self.name}
Expand Down
2 changes: 1 addition & 1 deletion core/dbt/artifacts/schemas/run/v5/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ class RunExecutionResult(
):
results: Sequence[RunResult]
args: Dict[str, Any] = field(default_factory=dict)
generated_at: datetime = field(default_factory=datetime.utcnow)
generated_at: datetime = field(default_factory=datetime.now)

def write(self, path: str):
writable = RunResultsArtifact.from_execution_results(
Expand Down
2 changes: 1 addition & 1 deletion core/dbt/contracts/graph/node_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class ModelNodeArgs:
latest_version: Optional[NodeVersion] = None
deprecation_date: Optional[datetime] = None
access: Optional[str] = AccessType.Protected.value
generated_at: datetime = field(default_factory=datetime.utcnow)
generated_at: datetime = field(default_factory=datetime.now)
depends_on_nodes: List[str] = field(default_factory=list)
enabled: bool = True

Expand Down
6 changes: 3 additions & 3 deletions core/dbt/contracts/sql.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
@dataclass
@schema_version("remote-compile-result", 1)
class RemoteCompileResult(RemoteCompileResultMixin):
generated_at: datetime = field(default_factory=datetime.utcnow)
generated_at: datetime = field(default_factory=datetime.now)

Check warning on line 37 in core/dbt/contracts/sql.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/contracts/sql.py#L37

Added line #L37 was not covered by tests

@property
def error(self):
Expand All @@ -46,7 +46,7 @@
class RemoteExecutionResult(ExecutionResult, RemoteResult):
results: Sequence[RunResult]
args: Dict[str, Any] = field(default_factory=dict)
generated_at: datetime = field(default_factory=datetime.utcnow)
generated_at: datetime = field(default_factory=datetime.now)

Check warning on line 49 in core/dbt/contracts/sql.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/contracts/sql.py#L49

Added line #L49 was not covered by tests

def write(self, path: str):
writable = RunResultsArtifact.from_execution_results(
Expand Down Expand Up @@ -82,4 +82,4 @@
@schema_version("remote-run-result", 1)
class RemoteRunResult(RemoteCompileResultMixin):
table: ResultTable
generated_at: datetime = field(default_factory=datetime.utcnow)
generated_at: datetime = field(default_factory=datetime.now)

Check warning on line 85 in core/dbt/contracts/sql.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/contracts/sql.py#L85

Added line #L85 was not covered by tests
4 changes: 2 additions & 2 deletions core/dbt/logger.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import time
import warnings
from dataclasses import dataclass
from datetime import datetime
from datetime import timezone, datetime
from typing import Optional, List, ContextManager, Callable, Dict, Any, Set

import logbook
Expand Down Expand Up @@ -295,7 +295,7 @@

def process(self, record):
super().process(record)
record.extra[self.name] = datetime.utcnow().isoformat()
record.extra[self.name] = datetime.now(timezone.utc).replace(tzinfo=None).isoformat()

Check warning on line 298 in core/dbt/logger.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/logger.py#L298

Added line #L298 was not covered by tests


class ScrubSecrets(logbook.Processor):
Expand Down
18 changes: 10 additions & 8 deletions core/dbt/parser/manifest.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from copy import deepcopy
from dataclasses import dataclass
from dataclasses import field
import datetime
from datetime import timezone, datetime, date
import os
import traceback
from typing import (
Expand Down Expand Up @@ -146,10 +146,10 @@


def extended_msgpack_encoder(obj):
if type(obj) is datetime.date:
if type(obj) is date:
date_bytes = msgpack.ExtType(1, obj.isoformat().encode())
return date_bytes
elif type(obj) is datetime.datetime:
elif type(obj) is datetime:

Check warning on line 152 in core/dbt/parser/manifest.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/manifest.py#L152

Added line #L152 was not covered by tests
datetime_bytes = msgpack.ExtType(2, obj.isoformat().encode())
return datetime_bytes

Expand All @@ -162,10 +162,10 @@

def extended_msgpack_decoder(code, data):
if code == 1:
d = datetime.date.fromisoformat(data.decode())
d = date.fromisoformat(data.decode())
return d
elif code == 2:
dt = datetime.datetime.fromisoformat(data.decode())
dt = datetime.fromisoformat(data.decode())

Check warning on line 168 in core/dbt/parser/manifest.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/parser/manifest.py#L168

Added line #L168 was not covered by tests
return dt
else:
return msgpack.ExtType(code, data)
Expand Down Expand Up @@ -590,7 +590,7 @@
if isinstance(node, ModelNode):
if (
node.deprecation_date
and node.deprecation_date < datetime.datetime.now().astimezone()
and node.deprecation_date < datetime.now(timezone.utc).astimezone()
):
warn_or_error(
DeprecatedModel(
Expand All @@ -605,7 +605,7 @@
node.depends_on
for resolved_ref in resolved_model_refs:
if resolved_ref.deprecation_date:
if resolved_ref.deprecation_date < datetime.datetime.now().astimezone():
if resolved_ref.deprecation_date < datetime.now(timezone.utc).astimezone():
event_cls = DeprecatedReference
else:
event_cls = UpcomingReferenceDeprecation
Expand Down Expand Up @@ -901,7 +901,9 @@
is_partial_parsable, reparse_reason = self.is_partial_parsable(manifest)
if is_partial_parsable:
# We don't want to have stale generated_at dates
manifest.metadata.generated_at = datetime.datetime.utcnow()
manifest.metadata.generated_at = datetime.now(timezone.utc).replace(
tzinfo=None
)
# or invocation_ids
manifest.metadata.invocation_id = get_invocation_id()
return manifest
Expand Down
5 changes: 3 additions & 2 deletions core/dbt/task/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import traceback
from abc import ABCMeta, abstractmethod
from contextlib import nullcontext
from datetime import datetime
from datetime import timezone, datetime
from pathlib import Path
from typing import Any, Dict, List, Optional, Type, Union, Set

Expand Down Expand Up @@ -232,7 +232,8 @@ def run_with_hooks(self, manifest):

result = self.safe_run(manifest)
self.node.update_event_status(
node_status=result.status, finished_at=datetime.utcnow().isoformat()
node_status=result.status,
finished_at=datetime.now(timezone.utc).replace(tzinfo=None).isoformat(),
)

if not self.node.is_ephemeral_model:
Expand Down
6 changes: 3 additions & 3 deletions core/dbt/task/docs/generate.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import shutil
from dataclasses import replace
from datetime import datetime
from datetime import timezone, datetime
from typing import Dict, List, Any, Optional, Tuple, Set, Iterable
import agate
from itertools import chain
Expand Down Expand Up @@ -226,7 +226,7 @@ def run(self) -> CatalogArtifact:
return CatalogArtifact.from_results(
nodes={},
sources={},
generated_at=datetime.utcnow(),
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
errors=None,
compile_results=compile_results,
)
Expand Down Expand Up @@ -306,7 +306,7 @@ def run(self) -> CatalogArtifact:
results = self.get_catalog_results(
nodes=nodes,
sources=sources,
generated_at=datetime.utcnow(),
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
compile_results=compile_results,
errors=errors,
)
Expand Down
9 changes: 6 additions & 3 deletions core/dbt/task/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
print_run_end_messages,
get_counts,
)
from datetime import datetime
from datetime import timezone, datetime
from dbt import tracking
from dbt import utils
from dbt.adapters.base import BaseRelation
Expand Down Expand Up @@ -366,7 +366,8 @@ def run_hooks(self, adapter, hook_type: RunHookType, extra_context) -> None:
# log_contextvars
with log_contextvars(node_info=hook.node_info):
hook.update_event_status(
started_at=datetime.utcnow().isoformat(), node_status=RunningStatus.Started
started_at=datetime.now(timezone.utc).replace(tzinfo=None).isoformat(),
node_status=RunningStatus.Started,
)
sql = self.get_hook_sql(adapter, hook, idx, num_hooks, extra_context)

Expand All @@ -391,7 +392,9 @@ def run_hooks(self, adapter, hook_type: RunHookType, extra_context) -> None:
status = "OK"

self.ran_hooks.append(hook)
hook.update_event_status(finished_at=datetime.utcnow().isoformat())
hook.update_event_status(
finished_at=datetime.now(timezone.utc).replace(tzinfo=None).isoformat()
)
with finishctx, DbtModelState({"node_status": "passed"}):
hook.update_event_status(node_status=RunStatus.Success)
fire_event(
Expand Down
6 changes: 3 additions & 3 deletions core/dbt/task/run_operation.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import os
import threading
import traceback
from datetime import datetime
from datetime import timezone, datetime
from typing import TYPE_CHECKING

import dbt_common.exceptions
Expand Down Expand Up @@ -51,7 +51,7 @@ def _run_unsafe(self, package_name, macro_name) -> "agate.Table":
return res

def run(self) -> RunResultsArtifact:
start = datetime.utcnow()
start = datetime.now(timezone.utc).replace(tzinfo=None)
self.compile_manifest()

success = True
Expand All @@ -69,7 +69,7 @@ def run(self) -> RunResultsArtifact:
fire_event(LogDebugStackTrace(exc_info=traceback.format_exc()))
success = False

end = datetime.utcnow()
end = datetime.now(timezone.utc).replace(tzinfo=None)

macro = (
self.manifest.find_macro_by_name(macro_name, self.config.project_name, package_name)
Expand Down
13 changes: 8 additions & 5 deletions core/dbt/task/runnable.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import time
from abc import abstractmethod
from concurrent.futures import as_completed
from datetime import datetime
from datetime import timezone, datetime
from multiprocessing.dummy import Pool as ThreadPool
from pathlib import Path
from typing import AbstractSet, Optional, Dict, List, Set, Tuple, Iterable
Expand Down Expand Up @@ -210,7 +210,8 @@ def call_runner(self, runner: BaseRunner) -> RunResult:
startctx = TimestampNamed("node_started_at")
index = self.index_offset(runner.node_index)
runner.node.update_event_status(
started_at=datetime.utcnow().isoformat(), node_status=RunningStatus.Started
started_at=datetime.now(timezone.utc).replace(tzinfo=None).isoformat(),
node_status=RunningStatus.Started,
)
extended_metadata = ModelMetadata(runner.node, index)

Expand Down Expand Up @@ -424,7 +425,7 @@ def execute_nodes(self):
run_result = self.get_result(
results=self.node_results,
elapsed_time=time.time() - self.started_at,
generated_at=datetime.utcnow(),
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
)

if self.args.write_json and hasattr(run_result, "write"):
Expand Down Expand Up @@ -502,7 +503,9 @@ def execute_with_hooks(self, selected_uids: AbstractSet[str]):
elapsed = time.time() - self.started_at
self.print_results_line(self.node_results, elapsed)
result = self.get_result(
results=self.node_results, elapsed_time=elapsed, generated_at=datetime.utcnow()
results=self.node_results,
elapsed_time=elapsed,
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
)

return result
Expand All @@ -527,7 +530,7 @@ def run(self):
warn_or_error(NothingToDo())
result = self.get_result(
results=[],
generated_at=datetime.utcnow(),
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
elapsed_time=0.0,
)
else:
Expand Down
10 changes: 5 additions & 5 deletions core/dbt/task/sql.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from abc import abstractmethod
from datetime import datetime
from datetime import timezone, datetime

Check warning on line 2 in core/dbt/task/sql.py

View check run for this annotation

Codecov / codecov/patch

core/dbt/task/sql.py#L2

Added line #L2 was not covered by tests
from typing import Generic, TypeVar
import traceback

Expand Down Expand Up @@ -68,7 +68,7 @@
node=compiled_node,
timing=[], # this will get added later
logs=[],
generated_at=datetime.utcnow(),
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
)

def from_run_result(self, result, start_time, timing_info) -> RemoteCompileResult:
Expand All @@ -78,7 +78,7 @@
node=result.node,
timing=timing_info,
logs=[],
generated_at=datetime.utcnow(),
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
)


Expand All @@ -98,7 +98,7 @@
table=table,
timing=[],
logs=[],
generated_at=datetime.utcnow(),
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
)

def from_run_result(self, result, start_time, timing_info) -> RemoteRunResult:
Expand All @@ -109,5 +109,5 @@
table=result.table,
timing=timing_info,
logs=[],
generated_at=datetime.utcnow(),
generated_at=datetime.now(timezone.utc).replace(tzinfo=None),
)
6 changes: 4 additions & 2 deletions core/dbt/tests/fixtures/project.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import pytest # type: ignore
import random
from argparse import Namespace
from datetime import datetime
from datetime import timezone, datetime
import warnings
import yaml

Expand Down Expand Up @@ -70,7 +70,9 @@
def prefix():
# create a directory name that will be unique per test session
_randint = random.randint(0, 9999)
_runtime_timedelta = datetime.utcnow() - datetime(1970, 1, 1, 0, 0, 0)
_runtime_timedelta = datetime.now(timezone.utc).replace(tzinfo=None) - datetime(
1970, 1, 1, 0, 0, 0
)
_runtime = (int(_runtime_timedelta.total_seconds() * 1e6)) + _runtime_timedelta.microseconds
prefix = f"test{_runtime}{_randint:04}"
return prefix
Expand Down
4 changes: 2 additions & 2 deletions core/dbt/tests/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import yaml
import json
import warnings
from datetime import datetime
from datetime import timezone, datetime
from typing import Any, Dict, List, Optional
from contextlib import contextmanager
from dbt.adapters.factory import Adapter
Expand Down Expand Up @@ -287,7 +287,7 @@ def check_result_nodes_by_unique_id(results, unique_ids):
def check_datetime_between(timestr, start, end=None):
datefmt = "%Y-%m-%dT%H:%M:%S.%fZ"
if end is None:
end = datetime.utcnow()
end = datetime.now(timezone.utc).replace(tzinfo=None)
parsed = datetime.strptime(timestr, datefmt)
assert start <= parsed
assert end >= parsed
Expand Down