
My goal is to come up with a simple, straightforward set of rules — not a bunch of complex, loosely-defined, or hard-to-understand heuristics. I've been exploring the suggestions from Guido and Shantanu, and those ideas are looking pretty good. Here's an updated version of my proposed rule that incorporates this feedback: For py.typed packages, type checkers should always apply PEP 484 import rules for “.py” files. If a symbol x is imported with an `import x` or `from y import x`, it is treated as “not public”, and any attempt to import it from another package will result in an error. If a “.py” file defines a module-level `__all__` symbol, the names it includes are considered public exports, overriding all other rules to the contrary. This modified rule doesn't cover 100% of existing py.typed packages, but it covers the vast majority, and it should be straightforward to update the small percentage that are not handled. As Guido pointed out, the number of "py.typed" packages is still relatively small, so now is a good time to standardize this. It looks like the following idioms for manipulating `__all__` cover the vast majority of the cases: * `__all__ = (‘a', ‘b', ‘c')` * `__all__ = [‘a', ‘b', ‘c']` * `__all__ += [‘a’, ’b', ‘c']` * `__all__.extend([‘a', ‘b', ‘c'])` * `__all__.extend(lib.__all__)` * `__all__.remove(‘a')` Brett, if we adopt this set of rules, you would simply need to change your usage from `from . import builtins as debuiltins` to something like `from . import builtins as _builtins`. By adding the underscore, the symbol will no longer be interpreted as a public export.