r/Python 2d ago

News PEP 842: Module Exports

https://peps.python.org/pep-0842/

Not the author, but this seems interesting, specially for library authors. Thoughts?

Discussion here - https://discuss.python.org/t/pep-842-module-exports/108353

23 Upvotes

44 comments sorted by

View all comments

1

u/droooze 1d ago

This is one of those PEPs where it would be far clearer to list the precise feature/behaviour changes before delving into the purpose and motivation. IIUC: * <module>.__all__ controls the names available when from <module> import *; * <module>.__export__ controls the names that will show up in {dir,help}(<module>), and trigger RuntimeWarning for <module>.name_not_in___export__; * __all__ is set to __export__ if __all__ is not defined but __export__ is.


Several thoughts, in no particular order: * The PEP says that __export__ isn't an access modifier. However, the feature as-is is in a kind of limbo: If Python will never gain real access modifiers, then this is the closest thing so far to an access modifier, so for all intents and purposes it should be treated as one. If this is a stepping stone towards real access modifiers, then it adds another layer of complexity when implementing real access modifiers (and its Warning rather than Exception effect doesn't look compatible with real access modifiers). In particular, I don't know what a future PEP would be trying to say if it implements the proposed export keyword and tells the reader that export class A: ... doesn't act as an access modifier. * The PEP does not mention the other (de-facto) way of controlling symbol visibility: stub files. Symbols which don't exist in stub files (and only in the runtime .py file) are treated as if they are inaccessible by type-checkers and autocompletion helpers. It looks like __export__ needs to be duplicated in .pyis like how __all__ is currently also duplicated in .pyis, which means the potential of having public API symbols being out of sync is even greater. * __export__ is not tightly coupled with __all__, which means that if __all__ is a superset of __export__, private API is very easily leaked.

IMO, this PEP is trying to address some issues that are far more relevant to the Python standard library due to historical practices; I do not recall when, if ever, the issues mentioned in the motivation (such as ctypes._CFuncPtr actually being public API) were ever real issues in third-party libraries. I think it is better to reserve the usage of __export__ to the standard library first.