DocumentProperties.created and modified are set at import time of the openpyxl module, rather than actual created time
Thank you for openpyxl, it is very useful!
Description
We're creating documents and were surprised to find that the created
and modified
attributes of openpyxl.packaging.core.DocumentProperties
are set to the time that the module is imported, rather than when an individual DocumentProperties
instance is created.
Reproducer
from datetime import datetime
import time
before_import = datetime.utcnow()
import openpyxl
after_import_ = datetime.utcnow()
first_props__ = openpyxl.packaging.core.DocumentProperties().created
time.sleep(1.234)
second_props_ = openpyxl.packaging.core.DocumentProperties().created
print(
f"""\
{before_import = }
{after_import_ = }
{first_props__ = }
{second_props_ = }
{openpyxl.__version__ = }"""
)
Output:
before_import = datetime.datetime(2022, 8, 31, 22, 23, 12, 614431)
after_import_ = datetime.datetime(2022, 8, 31, 22, 23, 12, 798539)
first_props__ = datetime.datetime(2022, 8, 31, 22, 23, 12, 793817)
second_props_ = datetime.datetime(2022, 8, 31, 22, 23, 12, 793817)
openpyxl.__version__ = '3.0.10'
Note that both props
timestamps are exactly equal, and occur between the before/after import timestamps.
Proposed patch
One possibility to address would be a change to https://foss.heptapod.net/openpyxl/openpyxl/-/blob/c95449fa6295debe169f265c09182d6d7bd68a33/openpyxl/packaging/core.py#L89-94 like the following, to move the default arg logic (which is evaluated during parsing/on import) to be within the constructor:
revision=None,
version=None,
- created=datetime.datetime.utcnow(),
+ created=None,
creator="openpyxl",
description=None,
identifier=None,
language=None,
- modified=datetime.datetime.utcnow(),
+ modified=None,
subject=None,
title=None,
):
+ if created is None:
+ created = datetime.datetime.utcnow()
+ if modified is None:
+ modified = datetime.datetime.utcnow()
self.contentStatus = contentStatus
self.lastPrinted = lastPrinted
That said, it looks like the behaviour was changed from timestamps-at-creation to timestamps-at-import in 66c7f18a5ab2 and thus this may be intended behaviour?
Work-around
We've been able to work-around this by explicitly setting wb.properties.created = wb.properties.modified = datetime.utcnow()
in our code.
As I said above, thank you for openpyxl!