News for hackers. Stuff that matters.
Re:An analysis of module names inside top PyPI packages by woodruffw on Wednesday July 10, 2024 @09:39PM (#40933075)
> As in, `import pillow as PIL`?

As in, not changing your imports at all, and just changing your dependency from PIL to pillow. This has two substantial advantages:

1. You only have to change one line (the dependency), not an indefinite number of source files. This is less of an issue now that the Python community has high-quality refactoring tools, but it's still the past of least resistance.

2. More importantly: `import pillow as PIL` is not referentially transparent: the `PIL` binding that it introduces is a `module` object, but that object can't be used in subsequent imports. In other words, blindly performing an `import X as Y` refactor would break code like this:

    import PIL
    from PIL import whatever
You can observe this for yourself locally:

    >>> import ssl as lol
    >>> from lol import CERT_NONE
    ModuleNotFoundError: No module named 'lol'
    >>> from ssl import CERT_NONE
This is arguably a defect in Python's import and module machinery, but that's how it currently is. Renaming the dependency and keeping the module name is far less fraught.
Re:An analysis of module names inside top PyPI packages by dheera on Thursday July 11, 2024 @01:37AM (#40933950)
The related thing that bothers me deeply is that

    import PIL
does not make PIL.Image available. What the hell else do you expect me to do with PIL? Why isn't PIL.Image included in importing PIL? You have to explicitly do either of these

    import PIL.Image
    from PIL import Image
Re:An analysis of module names inside top PyPI packages by woodruffw on Thursday July 11, 2024 @01:56AM (#40934011)
That’s because it’s a module within the PIL module, not an attribute of PIL. But that doesn’t really have anything to do with the original comment; that’s a different quirk of Python’s import machinery.

(Understanding the difference between packages, module hierarchies, and module attributes is table stakes for architecting a large Python package correctly. PIL almost certainly does this to prevent hard-to-debug circular imports elsewhere in their codebase.)

Re:An analysis of module names inside top PyPI packages by Jasper_ on Thursday July 11, 2024 @02:08PM (#40939119)
It's a strange distinction, because the standard library sometimes eschews this. `os.path` is accessible through just `import os`, because they made os.py import it into the local namespace.

I wish it was clearer sometimes what was a module, and what was an attribute in the core import syntax. `import foo; foo.bar` only breaks if it's a module, and `import foo.bar` only breaks if it's an attribute. If you do `from foo import bar`, the syntax works with both.

Re:An analysis of module names inside top PyPI packages by ciupicri on Thursday July 11, 2024 @03:18PM (#40939683)
Just because `os.path` is accessible through just `import os`, doesn't mean that you shouldn't import it explicitly. As the Zen of Python says, explicit is better than implicit. After all it's documented separately at https://docs.python.org/3/library/os.path.html

If you see `os.path.basename` what could `os.path` be? It would be a module most of the time because it's written with lowercase. `itertools.chain.from_iterable` [1] would be a notable exception.

[1]: https://docs.python.org/3/library/itertools.html#itertools.c...