Has there been any prior discussion of this feature?
I presented this idea as a lightning talk at the Language Summit and got generally positive responses and a suggestion to write the PEP by multiple participants. The general consensus seemed to be that this is a small ergonomic improvement with no obvious downside.
I find it pretty rare that a module only exposes a single callable as its interface
It might not be the majority of cases, but I’ve found it frequently enough over the years. Just in the stdlib, there are a couple of modules with only a single documented callable:
array.array
fractions.Fraction
But there are several more where I would personally consider it useful to expose the “main” API from each module as a potential “default” callable:
configparser.ConfigParser
dis.dis
enum.Enum
fnmatch.fnmatch
getopt.getopt
glob.glob
mmap.mmap
queue.Queue
I can also imagine cases where stdlib packages could have had more ergonomic usage with callable modules, and perhaps some better naming. Consider:
import dataclass
@dataclass
class Foo:
something: str
many_things: list[str] = dataclass.field(...)
import sqlite
with sqlite(":memory:"):
...
Beyond stdlib, looking at the top packages on PyPI, a few also stand out to me as potentially gaining a cleaner import for their primary UX:
decorator.decorator
filelock.FileLock
frozenlist.FrozenList
iniconfig.IniConfig
tqdm.tqdm
wrapt.decorator
As I mentioned earlier in the thread, there are multiple cases where I’ve personally written (or maintained) libraries with a single class or function that serves as the entrypoint to the library, including aiosqlite.connect
, diff_match_patch.diff_match_patch
, and trailrunner.Trailrunner
.
that’s going to be a hard sell, because as I say, I don’t see
from mod import mod
as being perceptibly worse
Maybe it’s not a huge QoL improvement in a single instance, but is there really a downside to reducing the amount of text, typing, and redundancy in imports? Small papercuts add up over time, and IMO from mod import mod
is a papercut that shouldn’t exist if we can solve it with a dozen lines of C code.
Other than “I’m fine with the status quo”, is there an actual concern with the feature? I’m happy to add more of these example use cases to the PEP if the only concern is that the PEP is light on real world examples.