Skip to content

Qualifiers typing #169

@jhoward-lm

Description

@jhoward-lm

Examining PackageURL's __new__ and from_string methods, it looks like it isn't possible to provide encode=True when the qualifiers get normalized. In other words, an instantiated PackageURL object's qualifiers will always be a dict, unless I'm missing something. It appears that using encode only comes into play when calling to_dict.

The behavior is the same whether calling from_string:

Example
>>> import rich
>>> from packageurl import PackageURL
>>> purl = PackageURL.from_string("pkg:deb/ubuntu/ca-certificates@20230311?arch=all&distro=lunar")
>>> rich.print(purl)
PackageURL(
    type='deb',
    namespace='ubuntu',
    name='ca-certificates',
    version='20230311',
    qualifiers={'arch': 'all', 'distro': 'lunar'},
    subpath=None
)
>>> rich.print(f"{purl.qualifiers=} ({type(purl.qualifiers)})")
purl.qualifiers={'arch': 'all', 'distro': 'lunar'} (<class 'dict'>)

or calling the constructor directly, passing in qualifiers explicitly as a string:

Example
>>> purl = PackageURL(
...     type="deb",
...     namespace="ubuntu",
...     name="ca-certificates",
...     version="20230311",
...     qualifiers="arch=all&distro=lunar",
...     subpath=None,
... )
>>> rich.print(purl)
PackageURL(
    type='deb',
    namespace='ubuntu',
    name='ca-certificates',
    version='20230311',
    qualifiers={'arch': 'all', 'distro': 'lunar'},
    subpath=None
)
>>> rich.print(f"{purl.qualifiers=} ({type(purl.qualifiers)})")
purl.qualifiers={'arch': 'all', 'distro': 'lunar'} (<class 'dict'>)

However, the type of that field is declared as Union[str, Dict[str, str], None], causing downstream code to have to write quite a few if isinstance(purl.qualifiers, dict) checks, or write custom type stubs to work around it. The workaround is less than ideal when having to maintain multiple copies of the same stubs across multiple projects.

Would it be possible to change the field declaration type to just Dict[str, str]? The signature of __new__ would not be affected. I'm happy to contribute the change if the maintainers are in agreement.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions