You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Is your feature request related to a problem? Please describe.
Currently FabSim3 uses a bespoke approach for having users install the application via the configure_fabsim.py script, and the fabsim directory is not structured as a regular Python package due to the lack of __init__.py files in the top-level and sub directories.
This creates a few related issues:
FabSim3 cannot be installed with existing package managment tools like pip, conda, poetry or pdm. This means it cannot be specified as a dependency for other packages and libraries using standard approaches (for example within a pyproject.toml file, setup.py script,requirements.txt or other tool specific format such as conda environment YAML or lock files). This also makes it difficult to use tools like tox, which are designed to help automating running Python tests in isolated environments, with FabSim3 itself or packages / modules (such as FabSim3 plugins) which themselves depend on FabSim. For example we have hit against precisely this issue when trying to run tests for the FabNESO plugin using tox (First draft of tests on the ensemble_tools UCL/FabNESO#23).
If a user follows the recommendation in the installation script to add the root of the FabSim3 repository to PYTHONPATH in .bashrc (or equivalent for other shells), all of the directories within this root directory that are valid Python package / module names (that is docs, fabsim, lists, plugins, tests) will be importable as namespace packages in all Python environments that the user runs that do not otherwise overwrite PYTHONPATH. Polluting the Python import namespace globally like this is not ideal, and given the very generic names of some of these directories could lead to confusion for example if a user imports lists and finds that nothing is defined there.
The configure_fabsim.py script reimplements standard functionality available in build backends such as setuptools by manually installing dependencies in a way which makes it difficult to flexibly used FabSim with an environment management system of the users choice (the script forces use of pip to install dependencies and uses the --user argument unless the VIRTUALENV variable is set - this means if installing in a conda environment for example, the packages will still be installed in the user directory rather than isolated to the conda environment).
Presumably partly because of the above non-standard approach for making fabsim importable, plugins are recommended to use a verbose approach of importing names from fabsim.base.fab, which shouldn't be necessary if fabsim was installed into the site-packages directory as a regular package.
For the fabsim directory to be made in a regular Python package by including __init__.py files in the top-level and all subdirectories.
For the current configure_fabsim.py script approach used for installing FabSim3 to be changed to instead use a modern pyproject.toml based approach for declaring package metadata combined with a build backend such as setuptools or poetry.
For the fabsim package to register a console script entrypoint for its command line interface rather than having the user add the fabsim/bin directory manually to search path.
For FabSim3 plugins to be able to register a fabsim.plugins entrypoint as a (potentially alternative to while maintaining current) approach for allowing FabSim3 to discover available plugins.
For FabSim3 user specific configurations files such as each plugins machines_{plugin_name}_user.yml file and the top-level machines_user.yml file to be located in an appropriate platform specific application data directory using something like platformdirs.
something the user separately explicitly opts in to post install by running a fabsim command, as some users may not want FabSim3 to make changes to these files.
Describe alternatives you've considered
An alternative to making fabsim a regular package, would be to keep it as a namespace package as currently and either use a src layout plus auomatic package discovery or explicitly specify the package directory in a pyproject.toml / setup.cfg / setup.py file. This would then allow FabSim3 plugins to 'register' themselves by making themselves part of the same namespace package and the pkguti.iter_modules() function used to discover all registered modules in a particular namespace (for example fabsim.plugins). The disadvantage of this approach is the aforementioned slight performance disadvantage at import time of namespace versus regular packages, and that this approach will force all plugins which wish to use this approach of registering themselves to be namespace packages as a plugin created as regular package with an __init__.py would make other subpackages in namespace non-importable.
Is your feature request related to a problem? Please describe.
Currently FabSim3 uses a bespoke approach for having users install the application via the
configure_fabsim.pyscript, and thefabsimdirectory is not structured as a regular Python package due to the lack of__init__.pyfiles in the top-level and sub directories.This creates a few related issues:
pip,conda,poetryorpdm. This means it cannot be specified as a dependency for other packages and libraries using standard approaches (for example within apyproject.tomlfile,setup.pyscript,requirements.txtor other tool specific format such ascondaenvironment YAML or lock files). This also makes it difficult to use tools liketox, which are designed to help automating running Python tests in isolated environments, with FabSim3 itself or packages / modules (such as FabSim3 plugins) which themselves depend on FabSim. For example we have hit against precisely this issue when trying to run tests for the FabNESO plugin usingtox(First draft of tests on the ensemble_tools UCL/FabNESO#23).PYTHONPATHin.bashrc(or equivalent for other shells), all of the directories within this root directory that are valid Python package / module names (that isdocs,fabsim,lists,plugins,tests) will be importable as namespace packages in all Python environments that the user runs that do not otherwise overwritePYTHONPATH. Polluting the Python import namespace globally like this is not ideal, and given the very generic names of some of these directories could lead to confusion for example if a user importslistsand finds that nothing is defined there.configure_fabsim.pyscript reimplements standard functionality available in build backends such assetuptoolsby manually installing dependencies in a way which makes it difficult to flexibly used FabSim with an environment management system of the users choice (the script forces use ofpipto install dependencies and uses the--userargument unless theVIRTUALENVvariable is set - this means if installing in acondaenvironment for example, the packages will still be installed in the user directory rather than isolated to thecondaenvironment).fabsimimportable, plugins are recommended to use a verbose approach of importing names fromfabsim.base.fab, which shouldn't be necessary iffabsimwas installed into thesite-packagesdirectory as a regular package.__init__.pyfiles infabsimand its subdirectories, any imports from that namespace will be resolved as an (implicit) namespace package which carries a performance penalty compared to imporing a regular package.Describe the solution you'd like
fabsimdirectory to be made in a regular Python package by including__init__.pyfiles in the top-level and all subdirectories.configure_fabsim.pyscript approach used for installing FabSim3 to be changed to instead use a modernpyproject.tomlbased approach for declaring package metadata combined with a build backend such assetuptoolsorpoetry.fabsimpackage to register a console script entrypoint for its command line interface rather than having the user add thefabsim/bindirectory manually to search path.fabsim.pluginsentrypoint as a (potentially alternative to while maintaining current) approach for allowing FabSim3 to discover available plugins.machines_{plugin_name}_user.ymlfile and the top-levelmachines_user.ymlfile to be located in an appropriate platform specific application data directory using something likeplatformdirs.FabSim3/configure_fabsim.py
Lines 209 to 221 in 7d80396
something the user separately explicitly opts in to post install by running a
fabsimcommand, as some users may not want FabSim3 to make changes to these files.Describe alternatives you've considered
An alternative to making
fabsima regular package, would be to keep it as a namespace package as currently and either use asrclayout plus auomatic package discovery or explicitly specify the package directory in apyproject.toml/setup.cfg/setup.pyfile. This would then allow FabSim3 plugins to 'register' themselves by making themselves part of the same namespace package and thepkguti.iter_modules()function used to discover all registered modules in a particular namespace (for examplefabsim.plugins). The disadvantage of this approach is the aforementioned slight performance disadvantage at import time of namespace versus regular packages, and that this approach will force all plugins which wish to use this approach of registering themselves to be namespace packages as a plugin created as regular package with an__init__.pywould make other subpackages in namespace non-importable.