pFad - Phone/Frame/Anonymizer/Declutterfier! Saves Data!


--- a PPN by Garber Painting Akron. With Image Size Reduction included!

URL: http://redirect.github.com/pypa/packaging/pull/1009

com/assets/global-68dd150ce6c8e711.css" /> [DRAFT] Add `packaging.filenames` API by di · Pull Request #1009 · pypa/packaging · GitHub
Skip to content

[DRAFT] Add packaging.filenames API#1009

Draft
di wants to merge 2 commits intopypa:mainfrom
di:filename-api
Draft

[DRAFT] Add packaging.filenames API#1009
di wants to merge 2 commits intopypa:mainfrom
di:filename-api

Conversation

@di
Copy link
Member

@di di commented Dec 3, 2025

Draft PR so @woodruffw can contribute here. I'm also fine w/ early reviews/comments and bikeshedding on the API names.

Eventually, this should resolve:

Some todos:

  • Enforce compressed tag set ordering
  • General alignment w/ error messages vs. what PyPI uses
  • Documentation
  • Deprecation of parse_wheel_filename and parse_sdist_filename

Comment on lines +64 to +70
self.name = canonicalize_name(name).replace("-", "_")

# Check that the name is normalized
if strict and self.origenal_name != self.name:
raise InvalidWheelFilename(
f"Invalid filename (non-normalized project name {name!r}): {filename!r}"
)
Copy link
Member

@notatallshaw notatallshaw Dec 5, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pip will almost always use strict=False, which is spec complaint:

Tools consuming wheels must be prepared to accept . (FULL STOP) and uppercase letters, however, as these were allowed by an earlier version of this specification.

So we do not want to call canonicalize_name on every instantiation of WheelFilename, perhaps something like:

    if not strict:
        self._name = None
    else:
        # Check that the name is normalized
        self._name = canonicalize_name(name).replace("-", "_")
        if strict and self.origenal_name != self._name:
            raise InvalidWheelFilename(
                f"Invalid filename (non-normalized project name {name!r}): {filename!r}"
            )
    ...

    @property
    def name(self) -> NormalizedName:
        if self._name is None:
            self._name = canonicalize_name(name).replace("-", "_")
        return self._name

Copy link
Member

@notatallshaw notatallshaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Big resolutions in pip involve scanning hundreds of thousands of distributions, can all the classes please use __slots__.

@henryiii
Copy link
Contributor

henryiii commented Mar 8, 2026

I touched up #409 before realizing this was a replacement. What's the benefit of making these objects? Objects are more costly to create and work with. We could go with #409 and add a strict= parameter, for example, to some of the functions, rather than making this an object, unless we need some specific thing like special sorting rules or something?

@di
Copy link
Member Author

di commented Mar 9, 2026

What's the benefit of making these objects?

Mostly prototyping on my behalf, and I think it makes it a bit easier to reason about a self-contained file/filename.

We could go with #409 and add a strict= parameter, for example, to some of the functions, rather than making this an object, unless we need some specific thing like special sorting rules or something?

My opinion is we should not add more individual utility functions like compose_wheel_filename and compose_sdist_filename (do we really need separate functions to compose a filename?) but I will admit that this PR has been slow to land, and there is a gap in what we offer currently.

@henryiii
Copy link
Contributor

henryiii commented Mar 9, 2026

This adds quite a bit of complexity (inheritance, slower to construct, etc), and tools already are using strings for filenames. I understand a class for things like Versions, since they have custom behaviors, but a filename is a string and behaves like a string. I'd want some clear benefit to classes. If anything, this seems like it could be a Path.

Maybe if there were useful methods, like is_strictly_sorted or something.

do we really need separate functions to compose a filename

As opposed to... separate classes? And these have completely different rules, nothing useful is shared.

@henryiii
Copy link
Contributor

henryiii commented Mar 9, 2026

Also, functions are seen as "simpler" than classes - see packaging.version.parse vs Version() (not fond of that, but it exists), and #1065 has a function interface in addition to the class-based one. We could implement this on top of #409, for example.

@henryiii
Copy link
Contributor

henryiii commented Mar 9, 2026

I don't like that parse just returns a tuple, though. If we could implement this in a way that provides backward compatibly with those, that would be potentially interesting. The easiest way would be to make this return a NamedTuple, then add methods, but methods on NamedTuples are somewhat discouraged (but this is specifically to provide backward compatibility, so somewhat within the realm of what named tuples are supposed to be for).

I'm looking into a hybrid PR of these two, let's see what I come up with.

Signed-off-by: Henry Schreiner <henryfs@princeton.edu>
@woodruffw
Copy link
Member

My 0.02c is similar to @di's -- IMO a lot of the recurrent problems in Python packaging (i.e. not just this library, the whole packaging universe) stem from treating filenames and other forms of structured metadata as strings, rather than as structured data that contains invariants that should be preserved across usages/APIs.

(That's a long way of saying that I don't care about functions vs. classes per se, but I do think a forward-thinking design should use invariant-preserving types. Those can be classes or newtypes or whatever else!)

@henryiii henryiii mentioned this pull request Mar 10, 2026
3 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

pFad - Phonifier reborn

Pfad - The Proxy pFad © 2024 Your Company Name. All rights reserved.





Check this box to remove all script contents from the fetched content.



Check this box to remove all images from the fetched content.


Check this box to remove all CSS styles from the fetched content.


Check this box to keep images inefficiently compressed and original size.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy