79788230

Date: 2025-10-11 20:57:45
Score: 2
Natty:
Report link

Thanks @sakshi-sharma for your informative tips! Here's my fully working solution.

Eventually, I've decided that it's better to create a new file containing build timestamp (and add it to .gitignore) rather than update an existing one. Also, I prefer having it as a data file rather than .py (in case I want to ignore it being missing - like, when running my project from the IDE).

So, in the end, I am creating a .dotenv-like file src/myproject/.build_info containing key like TIMESTAMP=2025-10-11 21:37:57 each time I execute build --wheel.

Changes to pyproject.toml:

dependencies = [
    ...more stuff...
    "python-dotenv>=1.1.0",
]

[build-system]
requires = ["setuptools"]  # no "wheel" needed
build-backend = "setuptools_build_hook"
backend-path = ["."]  # important!

[tool.setuptools.package-data]
"*" = [
    ...more stuff...,
    ".build_info",
]

New file setuptools_build_hook.py in project's root:

"""
Setuptools build hook wrapper that writes file `src/myproject/.build_info`
containing build timestamp when building WHL files with `build --wheel`.
"""

from datetime import datetime
from os import PathLike
from pathlib import Path

from setuptools import build_meta


def build_wheel(
        wheel_directory: str | PathLike[str],
        config_settings: dict[str, str | list[str] | None] | None = None,
        metadata_directory: str | PathLike[str] | None = None,
) -> str:
    """Creates file `src/myproject/.build_info` with key TIMESTAMP, then proceeds normally."""
    Path("src/myproject/.build_info").write_text(f"TIMESTAMP={datetime.now():%Y-%m-%d %H:%M:%S}\n", encoding="utf-8")
    print("* Written .build_info.")
    return build_meta.build_wheel(wheel_directory, config_settings, metadata_directory)


# Proxy (wrappers) for setuptools.build_meta
get_requires_for_build_wheel = build_meta.get_requires_for_build_wheel
get_requires_for_build_sdist = build_meta.get_requires_for_build_sdist
prepare_metadata_for_build_wheel = build_meta.prepare_metadata_for_build_wheel
build_sdist = build_meta.build_sdist
get_requires_for_build_editable = build_meta.get_requires_for_build_editable
prepare_metadata_for_build_editable = build_meta.prepare_metadata_for_build_editable
build_editable = build_meta.build_editable

And now, how to read this value in runtime:

import myproject as this_package


from io import StringIO
build_timestamp: str | None = None
# noinspection PyBroadException
try:
    build_timestamp = dotenv_values(stream=StringIO(resources.files(this_package).joinpath(".build_info")
                                                    .read_text(encoding="utf-8")))["TIMESTAMP"]
except Exception:
    pass
Reasons:
  • Blacklisted phrase (0.5): Thanks
  • RegEx Blacklisted phrase (1): I want
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @sakshi-sharma
  • Self-answer (0.5):
  • Low reputation (0.5):
Posted by: Leszek Pachura