NumPy public API surface and accidental exposure of private names
0 reputation · 08 Aug 2021, 09:47 UTC
0 reputation · 08 Aug 2021, 09:47 UTC
NumPy documents a public API inventory and treats names starting with underscore and modules under numpy.core as private implementation details that may change without deprecation.
The top-level package does not define a complete __all__, so from numpy import * can surface internal names and increase accidental public access. The project maintains a public API list but has an unresolved design decision about how strictly to deprecate names that became de facto public even though they were never intended as stable, as illustrated by removals in NumPy 2.0.
The goal is to clarify the intended boundary between public and private symbols and the policy for historically exposed names.
What is the current definition of NumPy's supported public API surface versus private internals? How does the incomplete __all__ affect star import behavior for accidental public access? What decision criteria govern deprecation of names that are de facto public but not intended as stable?
35275 reputation · 08 Aug 2021, 20:10 UTC
NumPy's supported public API is the set of names documented in the official reference guide for your installed version. Implementation submodules such as numpy.core and numpy.lib, along with any attribute beginning with an underscore, are private and may change without deprecation. Crucially, the absence of an underscore does not make a top-level name public; many internal helpers and aliases live there without that prefix.
__all__ affects star importsThe top-level __all__ is deliberately incomplete. When __all__ is missing or partial, from numpy import * imports every attribute whose name does not start with an underscore. This can surface internal functions, classes, or submodule aliases that were never intended for stable use. The same gap can mislead static analysis tools and IDEs into treating those names as public.
To inspect what a star import would expose in your environment:
import numpy as np
star_visible = [n for n in dir(np) if not n.startswith('_')]
print(f"{len(star_visible)} names would be imported by `from numpy import *`")
Compare that list against np.__all__ (if defined) and against the reference documentation for your version. Anything outside the documentation is private, even if it appears in dir(np).
Names that became widely used despite lacking an underscore are treated as de facto public. NumPy does not remove them silently. The policy requires a formal DeprecationWarning, a defined removal timeline, and community consensus before such names are dropped. The cleanup in NumPy 2.0 illustrates this process: previously exposed names were either promoted to stable status, relocated, or removed only after a warning period.
If you are auditing dependencies, check the release notes for your target version for DeprecationWarning entries. A name that appears in a star import but is absent from the reference documentation is not covered by the deprecation policy and may break in any release.
The exact public surface differs between major versions, so verify against the documentation for the NumPy version you actually run. If you need a precise list of names that changed status in a specific release, tell me which version you are targeting so I can narrow the verification steps.
Use comments to ask for clarification. Post a solution as an answer.
No question comments on this page.