SEP 3 — Including packages into the SDyPy namespace#
- Authors:
Domen Gorjup <domen.gorjup@fs.uni-lj.si>, Janko Slavič <janko.slavic@fs.uni-lj.si>
- Status:
Draft
- Type:
Process
- Created:
2021-03-25
Abstract#
SDyPy uses Python’s namespace package mechanism to include packages with a high level of integration into its namespace while allowing for an independently development processes. The use of namespace packages in SDyPy is described in this document.
Motivation#
As SDyPy aims to integrate multiple open-source Python packages in the structural dynamics field to provide a coherent workflow, it may be beneficial to include some packages into the SDyPy namespace. However, it is reasonable that some of these packages keep a high level of independence in their development and distribution (e.g. their repositories with a wealth of existing resources, issues and commit histories…). To achieve this, Python’s namespace package mechanism is used.
Detailed description#
The four levels of integration, described in SEP1, define two types of packages that are included in the SDyPy namespace, but are developed in independent repositories:
2nd level packages are namespace packages with a high level of integration with SDyPy, that are developed by a separate organization.
1st level packages are hosted by the SDyPy organization, but can be developed in a repository, separate from the `core SDyPy package`_.
To integrate these two types of packages into the SDyPy namespace, Python’s namespace package mechanism is used. A native support for namespace packages has been introduced with Python 3.3 and is defined by PEP 420. When a package has reached a high level of integration with SDyPy, it can be included into the SDyPy namespace by adhering to Python’s namespace package file structure
example_project/
setup.py
SDyPy/
example_project/
__init__.py
As stated in Python’s namespace package documentation, it is important that the namespace directory (SDyPy/) omits an __init__.py file. It is also necessary to alter an existing package’s setup script to adhere to the changed file structure.
When a package, developed by a separate organization is defined to be part of the SDyPy namespace, as shown in the above example, it becomes a Level 2 SDyPy package. If it’s ownership is also transferred to the SDyPy organization it becomes a Level 1 SDyPy package.
SDyPy packages should follow the The Zen of Python, presented in PEP 20.
The umbrella package and the lazy facade#
The core sdypy distribution provides the only sdypy/__init__.py in the
namespace and acts as a lightweight lazy facade. It exposes each first-level
sub-package (EMA, io, FRF, excitation, model, view) as an
attribute via PEP 562 module __getattr__ - importing the sub-package only on
first access - and provides __version__ from the installed distribution
metadata. It keeps the package a namespace-compatible portion (via
pkgutil.extend_path) so the sibling portions still contribute.
All other packages contributing to the sdypy namespace MUST be native
PEP 420 portions and MUST NOT ship a top-level sdypy/__init__.py. This
keeps the umbrella’s __init__.py the single owner of the namespace root, so
sub-package discovery and lazy attribute resolution are deterministic regardless
of sys.path order, and it reconciles the README’s documented sd.EMA usage
with the native-namespace requirement described above.
Discussion#
This section may just be a bullet list including links to any discussions regarding the SEP:
This includes links to mailing list threads or relevant GitHub issues.
References and Footnotes#
Copyright#
This document has been placed in the public domain. [1]