Create a public API - #194
Open
FrederikSchnack wants to merge 3 commits into
Open
FrederikSchnack wants to merge 3 commits into
FrederikSchnack wants to merge 3 commits into
Conversation
Expose supported symbols through sympde.api, migrate tests and API-facing documentation, remove package-level wildcard exports and obsolete compatibility code, and lazily load optional plotting and serialization dependencies.
FrederikSchnack
added this pull request to stack #192
September 29, 2026 15:37
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This is the final PR of this stack.
Introduce a single, explicit public API for SymPDE and reduce the amount of code and third-party functionality loaded during package imports.
User-facing code should now import supported objects from:
Internal SymPDE modules continue to import objects directly from their defining modules.
Closes #180
Closes #181
Closes #182
Public API changes
1. Add an explicit
sympde.apinamespaceA new
sympde.apipackage provides a documented, flat namespace containing the supported user-facing objects.The API covers:
The namespace defines an explicit
__all__, making it possible to identify the supported API without relying on implementation details or wildcard imports.Tests verify that:
__all__exists;__all__does not contain duplicates;2. Remove wildcard exports from package initializers
The previous package initializers recursively imported and re-exported entire subpackages:
Importing a small part of SymPDE could therefore load most of the library, including modules unrelated to the requested functionality.
The initializers for the following packages are now empty:
This makes imports more predictable and prevents package initialization from eagerly traversing the full dependency graph.
3. Establish separate user-facing and internal import conventions
User code should use the convenient public namespace:
Internal library code imports directly from the module that defines each object:
This separation provides a stable user-facing API while keeping internal dependencies explicit and avoiding circular imports.
Import-performance improvements
4. Avoid loading the complete library for package imports
Previously, imports such as:
executed wildcard imports from multiple package initializers. This loaded many unrelated symbolic, plotting, mapping, and expression modules.
With empty package initializers, importing a module now loads only its actual dependencies. The complete user-facing namespace is loaded only when explicitly requested through:
5. Import plotting dependencies only when plotting is requested
matplotlib.pyplotwas previously imported whensympde.utilities.utilswas loaded, even when no plotting functionality was used.It is now imported locally by the plotting functions:
This avoids Matplotlib initialization, backend selection, and configuration-directory access during unrelated SymPDE imports.
6. Import serialization dependencies only when needed
The domain module previously imported
h5py,yaml, and additional NumPy functionality at module import time.These dependencies are now imported inside the operations that require them:
Creating or manipulating symbolic domains therefore no longer initializes the HDF5 and YAML stacks.
7. Remove unnecessary production imports
A large number of unused imports were removed from the core, topology, exterior-calculus, expression, and printing modules.
This includes unused:
Besides reducing import work, this makes each module’s dependency requirements easier to understand.
8. Break circular imports with local imports
The topology derivative module previously imported mapping classes at module scope, while the mapping module also depended on derivative definitions.
MappingandJacobianare now imported locally only in the logical-derivative path that needs them.This removes the module-level cycle without changing the public behavior of differential operators.
Compatibility and cleanup
9. Remove the obsolete SymPy compatibility module
The previous PR replaced usages of the local compatibility helpers with maintained SymPy utilities and native Python metaclass syntax.
Once the package-level wildcard exports are removed, the remaining compatibility module is no longer part of the import surface and can be deleted.
This removes:
10. Migrate tests to the supported API
User-facing tests now import objects from
sympde.apirather than relying on wildcard package exports.This ensures that the test suite exercises the same import path recommended to downstream users.
Dedicated API tests verify:
The API checks use direct imports and assertions rather than dynamically executing generated import statements.
11. Fix plotting of unmapped two-dimensional domains
While adding coverage for deferred plotting imports, the unmapped 2D plotting path was found to create a three-dimensional identity mapping.
It now creates the correct two-dimensional identity mapping:
A regression test plots an unmapped square with a non-interactive Matplotlib backend.
Documentation changes
12. Document the supported public API
The README and Sphinx documentation now direct users to
sympde.api.A dedicated API page documents the complete explicit namespace:
The API documentation avoids generating duplicate cross-reference targets for objects that are also documented in their defining modules.
13. Replace obsolete notebooks with executable examples
The old notebooks and their Binder integration had become outdated and were not validated by CI.
They are replaced by focused Python examples covering:
All examples use the new public API.
14. Execute documentation examples in CI
The documentation workflow now runs every Python example before building the Sphinx pages:
This ensures that documented imports and examples remain executable as the API evolves.
Obsolete documentation helper scripts, notebooks, notebook styles, and the Binder badge are removed.
Breaking changes
Wildcard convenience imports from package namespaces are no longer supported.
For example, user code should migrate from:
to:
Code that intentionally depends on internal implementation details may instead import directly from the defining module:
The
sympde.apinamespace is the recommended interface for downstream users.Validation
The complete test suite passes:
The documentation validation also passes: