Search code examples
pythonpipenvpython-poetry

How can I check poetry lockfile freshness without importing poetry


We've been using pipenv for dependency management for a while, and using micropipenv's protected functionality to check lock freshness - the idea here being that micropipenv is lightweight, so this is a cheap and cheerful way of ensuring that our dependencies haven't drifted during CI or during a docker build.

Alas, micropipenv has no such feature for poetry (it skips the hash check completely), and I am therefore left to "reverse-engineer" the feature on my own. Ostensibly this should be super easy - I've assembled the code posted later from what I traced through the poetry and poetry-core repos (Locker, Factory, core.Factory, and PyProjectTOML, primarily). This absolutely does not do the trick, and I'm at a loss as to why.

_relevant_keys = ["dependencies", "group", "source", "extras"]


def _get_content_hash(pyproject):
    content = pyproject["tool"]["poetry"]
    print(content)
    relevant_content = {}
    for key in _relevant_keys:
        relevant_content[key] = content.get(key)
    print(json.dumps(relevant_content, sort_keys=True).encode())
    content_hash = sha256(
        json.dumps(relevant_content, sort_keys=True).encode()
    ).hexdigest()
    print(f"Calculated: {content_hash}")
    return content_hash


def is_fresh(lockfile, pyproject):
    metadata = lockfile.get("metadata", {})
    print(f"From file: {lockfile['metadata']['content-hash']}")
    if "content-hash" in metadata:
        return _get_content_hash(pyproject) == lockfile["metadata"]["content-hash"]
    return False

Would love to figure out what exactly the heck I'm missing here - i'm guessing that the poetry locker _local_config gets changed at some point and I've failed to notice it.

References:

Locker: https://github.com/python-poetry/poetry/blob/a1a5bce96d85bdc0fdc60b8abf644615647f969e/poetry/packages/locker.py#L454

core.Factory: https://github.com/python-poetry/poetry-core/blob/afaa6903f654b695d9411fb548ad10630287c19f/poetry/core/factory.py#L24


Solution

  • Naturally, this ended up being a PEBKAC error. I was using the hash generation function from the master branch but using an earlier version of poetry on the command line. Once I used the function from the correct code version, everything was hunky dory.

    I think this functionality actually exists in micropipenv now anyways lol