├── vsc-ci.ini ├── test ├── data │ └── mailconfig.ini ├── runtests │ ├── run_nested.sh │ ├── simple.py │ ├── simple_option.py │ └── qa.py ├── __init__.py ├── sandbox │ └── testpkg │ │ ├── __init__.py │ │ ├── testmodule.py │ │ └── testmodulebis.py ├── 00-import.py ├── wrapper.py ├── docs.py ├── groups.py ├── asyncprocess.py ├── dateandtime.py ├── mail.py ├── optcomplete.py ├── rest.py ├── exceptions.py └── run.py ├── .gitignore ├── tox.ini ├── ruff.toml ├── lib └── vsc │ ├── __init__.py │ └── utils │ ├── __init__.py │ ├── wrapper.py │ ├── patterns.py │ ├── frozendict.py │ ├── docs.py │ ├── groups.py │ ├── daemon.py │ ├── exceptions.py │ ├── asyncprocess.py │ ├── affinity.py │ ├── dateandtime.py │ ├── mail.py │ ├── rest.py │ ├── missing.py │ └── optcomplete.py ├── Jenkinsfile ├── .github └── workflows │ └── unittest.yml ├── setup.py ├── examples ├── simple_option.py └── qa.py ├── bin └── optcomplete.bash └── README.md /vsc-ci.ini: -------------------------------------------------------------------------------- 1 | [vsc-ci] 2 | enable_github_actions=1 3 | py39_tests_must_pass=1 4 | run_ruff_format_check=1 5 | run_ruff_check=1 6 | -------------------------------------------------------------------------------- /test/data/mailconfig.ini: -------------------------------------------------------------------------------- 1 | [MAIN] 2 | smtp = config_host:789 3 | smtp_auth_user = config_user 4 | smtp_auth_password = config_passwd 5 | smtp_use_starttls = 1 6 | -------------------------------------------------------------------------------- /test/runtests/run_nested.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | depth=${1:-1} 4 | path=${2:-/dev/null} 5 | 6 | mysleep=15 7 | 8 | echo "$depth $$ $PPID" >> $path 9 | 10 | if [ $depth -ne 0 ]; then 11 | "$0" $(($depth -1)) "$path" & 12 | fi 13 | 14 | sleep $mysleep 15 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[co] 2 | *.swp 3 | *~ 4 | 5 | # ok to ignore generated file in vsc-base 6 | setup.cfg 7 | 8 | # Packages 9 | .eggs* 10 | *.egg 11 | *.egg-info 12 | dist 13 | build 14 | eggs 15 | parts 16 | var 17 | sdist 18 | develop-eggs 19 | .installed.cfg 20 | 21 | # Installer logs 22 | pip-log.txt 23 | 24 | # Unit test / coverage reports 25 | .coverage 26 | .tox 27 | 28 | #Translations 29 | *.mo 30 | 31 | #Mr Developer 32 | .mr.developer.cfg 33 | 34 | # Ninja 35 | *.nja 36 | 37 | html 38 | test-reports 39 | htmlcov/ 40 | -------------------------------------------------------------------------------- /tox.ini: -------------------------------------------------------------------------------- 1 | # tox.ini: configuration file for tox 2 | # This file was automatically generated using 'python -m vsc.install.ci' 3 | # DO NOT EDIT MANUALLY 4 | 5 | [tox] 6 | envlist = py36,py39 7 | skipsdist = true 8 | 9 | [testenv:py36] 10 | commands_pre = 11 | pip install 'setuptools<42.0' 12 | python -m easy_install -U vsc-install 13 | 14 | [testenv:py39] 15 | setenv = SETUPTOOLS_USE_DISTUTILS=local 16 | commands_pre = 17 | pip install 'setuptools<54.0' wheel 18 | python -c "from setuptools import setup;setup(script_args=['-q', 'easy_install', '-v', '-U', 'vsc-install'])" 19 | 20 | [testenv] 21 | commands = python setup.py test 22 | passenv = USER 23 | -------------------------------------------------------------------------------- /ruff.toml: -------------------------------------------------------------------------------- 1 | line-length = 120 2 | indent-width = 4 3 | preview = true 4 | target-version = "py37" 5 | exclude = ['.bzr', '.direnv', '.eggs', '.git', '.git-rewrite', '.hg', '.ipynb_checkpoints', '.mypy_cache', '.nox', '.pants.d', '.pyenv', '.pytest_cache', '.pytype', '.ruff_cache', '.svn', '.tox', '.venv', '.vscode', '__pypackages__', '_build', 'buck-out', 'build', 'dist', 'node_modules', 'site-packages', 'venv', 'test/*'] 6 | [lint] 7 | extend-select = ['E101', 'E501', 'E713', 'E4', 'E7', 'E9', 'F', 'F811', 'W291', 'PLR0911', 'PLW0602', 'PLW0604', 'PLW0108', 'PLW0127', 'PLW0129', 'PLW1501', 'PLR0124', 'PLR0202', 'PLR0203', 'PLR0402', 'PLR0913', 'B028', 'B905', 'C402', 'C403', 'UP032', 'UP037', 'UP025', 'UP026', 'UP036', 'UP034', 'UP033', 'UP031', 'UP004'] 8 | ignore = ['E731'] 9 | pylint.max-args = 11 10 | [format] 11 | quote-style = "double" 12 | indent-style = "space" 13 | docstring-code-format = true 14 | docstring-code-line-length = 120 15 | line-ending = "lf" 16 | -------------------------------------------------------------------------------- /test/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Init 28 | """ 29 | -------------------------------------------------------------------------------- /test/sandbox/testpkg/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2021-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | """ 28 | -------------------------------------------------------------------------------- /lib/vsc/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Allow other packages to extend this namespace, zip safe setuptools style 28 | """ 29 | 30 | import pkg_resources 31 | 32 | pkg_resources.declare_namespace(__name__) 33 | -------------------------------------------------------------------------------- /lib/vsc/utils/__init__.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Allow other packages to extend this namespace, zip safe setuptools style 28 | """ 29 | 30 | import pkg_resources 31 | 32 | pkg_resources.declare_namespace(__name__) 33 | -------------------------------------------------------------------------------- /test/00-import.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Common test import 28 | """ 29 | import vsc.install.commontest 30 | 31 | 32 | class ImportTest(vsc.install.commontest.CommonTest): 33 | 34 | # skip import for vsc.utils.py2vs3 modules 35 | EXCLUDE_MODS = [r'^vsc\.utils\.py2vs3'] 36 | -------------------------------------------------------------------------------- /test/sandbox/testpkg/testmodule.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2014-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Test module used by the unit tests 28 | 29 | @author: Kenneth Hoste (Ghent University) 30 | """ 31 | class TestModA(object): 32 | pass 33 | 34 | class TestModA1(TestModA): 35 | pass 36 | 37 | class TestModA2(TestModA): 38 | pass 39 | -------------------------------------------------------------------------------- /test/sandbox/testpkg/testmodulebis.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2014-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Test module used by the unit tests 28 | 29 | @author: Kenneth Hoste (Ghent University) 30 | """ 31 | from testmodule import TestModA, TestModA1 32 | class TestModA3(TestModA): 33 | pass 34 | 35 | class TestModA1B(TestModA1): 36 | pass 37 | 38 | class TestModA1B1(TestModA1B): 39 | pass 40 | -------------------------------------------------------------------------------- /Jenkinsfile: -------------------------------------------------------------------------------- 1 | // Jenkinsfile: scripted Jenkins pipefile 2 | // This file was automatically generated using 'python -m vsc.install.ci' 3 | // DO NOT EDIT MANUALLY 4 | 5 | pipeline { 6 | agent any 7 | stages { 8 | stage('checkout git') { 9 | steps { 10 | checkout scm 11 | // remove untracked files (*.pyc for example) 12 | sh 'git clean -fxd' 13 | } 14 | } 15 | stage('install ruff') { 16 | steps { 17 | sh 'curl -L --silent https://github.com/astral-sh/ruff/releases/download/0.13.1/ruff-x86_64-unknown-linux-gnu.tar.gz --output - | tar -xzv' 18 | sh 'cp ruff-x86_64-unknown-linux-gnu/ruff .' 19 | sh './ruff --version' 20 | } 21 | } 22 | stage('test pipeline') { 23 | parallel { 24 | stage ('ruff format') { 25 | steps { 26 | sh './ruff format --check .' 27 | } 28 | } 29 | stage ('ruff check') { 30 | steps { 31 | sh './ruff check .' 32 | } 33 | } 34 | stage('test') { 35 | steps { 36 | sh 'pip3 install --ignore-installed --prefix $PWD/.vsc-tox tox' 37 | sh 'export PATH=$PWD/.vsc-tox/bin:$PATH && export PYTHONPATH=$PWD/.vsc-tox/lib/python$(python3 -c "import sys; print(\\"%s.%s\\" % sys.version_info[:2])")/site-packages:$PYTHONPATH && tox -v -c tox.ini' 38 | sh 'rm -r $PWD/.vsc-tox' 39 | } 40 | } 41 | } 42 | } 43 | }} 44 | -------------------------------------------------------------------------------- /test/runtests/simple.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2016-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Simple, ugly test script 28 | """ 29 | import time 30 | import sys 31 | 32 | EC_SUCCES = 0 33 | EC_NOARGS = 1 34 | 35 | txt = [] 36 | ec = EC_SUCCES 37 | 38 | if 'shortsleep' in sys.argv: 39 | time.sleep(0.1) 40 | txt.append("Shortsleep completed") 41 | 42 | if 'longsleep' in sys.argv: 43 | time.sleep(10) 44 | txt.append("Longsleep completed") 45 | 46 | if __name__ == '__main__': 47 | if len(txt) == 0: 48 | txt.append('Nothing passed') 49 | ec = EC_NOARGS 50 | print("\n".join(txt)) 51 | sys.exit(ec) 52 | -------------------------------------------------------------------------------- /lib/vsc/utils/wrapper.py: -------------------------------------------------------------------------------- 1 | ### External compatible license 2 | """ 3 | This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License 4 | with attribution required 5 | 6 | Original code by http://stackoverflow.com/users/416467/kindall from answer 4 of 7 | http://stackoverflow.com/questions/9057669/how-can-i-intercept-calls-to-pythons-magic-methods-in-new-style-classes 8 | """ 9 | 10 | 11 | class WrapperMetaclass(type): 12 | def __init__(cls, name, bases, dct): 13 | def make_proxy(name): 14 | def proxy(self, *args): # pylint:disable=unused-argument 15 | return getattr(self._obj, name) 16 | 17 | return proxy 18 | 19 | type.__init__(cls, name, bases, dct) 20 | if cls.__wraps__: 21 | ignore = {f"__{n}__" for n in cls.__ignore__.split()} 22 | for name in dir(cls.__wraps__): 23 | if name.startswith("__"): 24 | if name not in ignore and name not in dct: 25 | setattr(cls, name, property(make_proxy(name))) 26 | 27 | 28 | class Wrapper(metaclass=WrapperMetaclass): 29 | """Wrapper class that provides proxy access to an instance of some 30 | internal instance.""" 31 | 32 | __wraps__ = None 33 | __ignore__ = "class mro new init setattr getattr getattribute" 34 | 35 | def __init__(self, obj): 36 | if self.__wraps__ is None: 37 | raise TypeError("base class Wrapper may not be instantiated") 38 | elif isinstance(obj, self.__wraps__): 39 | self._obj = obj 40 | else: 41 | raise ValueError(f"wrapped object must be of {self.__wraps__}") 42 | 43 | # provide proxy access to regular attributes of wrapped object 44 | def __getattr__(self, name): 45 | return getattr(self._obj, name) 46 | -------------------------------------------------------------------------------- /.github/workflows/unittest.yml: -------------------------------------------------------------------------------- 1 | # .github/workflows/unittest.yml: configuration file for github actions worflow 2 | # This file was automatically generated using 'python -m vsc.install.ci' 3 | # DO NOT EDIT MANUALLY 4 | jobs: 5 | python_ruff_check: 6 | runs-on: ubuntu-24.04 7 | steps: 8 | - name: Checkout code 9 | uses: actions/checkout@v4 10 | - name: Setup Python 11 | uses: actions/setup-python@v5 12 | with: 13 | python-version: ${{matrix.python}} 14 | - name: install ruff 15 | run: pip install 'ruff' 16 | - name: Run ruff 17 | run: ruff check . 18 | strategy: 19 | matrix: 20 | python: 21 | - 3.9 22 | python_ruff_format: 23 | runs-on: ubuntu-24.04 24 | steps: 25 | - name: Checkout code 26 | uses: actions/checkout@v4 27 | - name: Setup Python 28 | uses: actions/setup-python@v5 29 | with: 30 | python-version: ${{matrix.python}} 31 | - name: install ruff 32 | run: pip install 'ruff' 33 | - name: Run ruff format 34 | run: ruff format --check . 35 | strategy: 36 | matrix: 37 | python: 38 | - 3.9 39 | python_unittests: 40 | runs-on: ubuntu-24.04 41 | steps: 42 | - name: Checkout code 43 | uses: actions/checkout@v4 44 | - name: Setup Python 45 | uses: actions/setup-python@v5 46 | with: 47 | python-version: ${{ matrix.python }} 48 | - name: install tox 49 | run: pip install 'virtualenv' 'tox' 50 | - name: add mandatory git remote 51 | run: git remote add hpcugent https://github.com/hpcugent/vsc-base.git 52 | - name: Run tox 53 | run: tox -e py$(echo ${{ matrix.python }} | sed 's/\.//g') 54 | strategy: 55 | matrix: 56 | python: 57 | - 3.9 58 | name: run python tests 59 | 'on': 60 | - push 61 | - pull_request 62 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2009-2025 Ghent University 4 | # 5 | # This file is part of vsc-base, 6 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 7 | # with support of Ghent University (http://ugent.be/hpc), 8 | # the Flemish Supercomputer Centre (VSC) (https://vscentrum.be/nl/en), 9 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 10 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 11 | # 12 | # http://github.com/hpcugent/vsc-base 13 | # 14 | # vsc-base is free software: you can redistribute it and/or modify 15 | # it under the terms of the GNU Library General Public License as 16 | # published by the Free Software Foundation, either version 2 of 17 | # the License, or (at your option) any later version. 18 | # 19 | # vsc-base is distributed in the hope that it will be useful, 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | # GNU Library General Public License for more details. 23 | # 24 | # You should have received a copy of the GNU Library General Public License 25 | # along with vsc-base. If not, see . 26 | # 27 | """ 28 | vsc-base base distribution setup.py 29 | 30 | @author: Stijn De Weirdt (Ghent University) 31 | @author: Andy Georges (Ghent University) 32 | @author: Kenneth Hoste (Ghent University) 33 | """ 34 | 35 | from vsc.install import shared_setup 36 | from vsc.install.shared_setup import ag, kh, jt, sdw, wdp 37 | 38 | PACKAGE = { 39 | "version": "3.6.8", 40 | "author": [sdw, jt, ag, kh], 41 | "maintainer": [sdw, jt, ag, kh, wdp], 42 | "install_requires": [ 43 | "vsc-install >= 0.17.19", 44 | ], 45 | } 46 | 47 | if __name__ == "__main__": 48 | shared_setup.action_target(PACKAGE) 49 | -------------------------------------------------------------------------------- /test/runtests/simple_option.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2011-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | An example how simple_option can do its magic. 28 | 29 | Run it with -h and/or -H to see the help functions. 30 | 31 | To see it do something, try 32 | python examples/simple_option.py --info -L itjustworks 33 | 34 | @author: Stijn De Weirdt (Ghent University) 35 | """ 36 | from vsc.utils.generaloption import simple_option 37 | 38 | # dict = {longopt:(help_description,type,action,default_value,shortopt),} 39 | options = {'long1':('1st long option', None, 'store', 'excellent', 'L')} 40 | 41 | go = simple_option(options) 42 | 43 | go.log.info("1st option %s" % go.options.long1) 44 | go.log.debug("DEBUG 1st option %s" % go.options.long1) 45 | 46 | -------------------------------------------------------------------------------- /examples/simple_option.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2011-2013 Ghent University 4 | # 5 | # This file is part of vsc-base, 6 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 7 | # with support of Ghent University (http://ugent.be/hpc), 8 | # the Flemish Supercomputer Centre (VSC) (https://vscentrum.be/nl/en), 9 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 10 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 11 | # 12 | # http://github.com/hpcugent/vsc-base 13 | # 14 | # vsc-base is free software: you can redistribute it and/or modify 15 | # it under the terms of the GNU Library General Public License as 16 | # published by the Free Software Foundation, either version 2 of 17 | # the License, or (at your option) any later version. 18 | # 19 | # vsc-base is distributed in the hope that it will be useful, 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | # GNU Library General Public License for more details. 23 | # 24 | # You should have received a copy of the GNU Library General Public License 25 | # along with vsc-base. If not, see . 26 | # 27 | """ 28 | An example how simple_option can do its magic. 29 | 30 | Run it with -h and/or -H to see the help functions. 31 | 32 | To see it do something, try 33 | python examples/simple_option.py --info -L itjustworks 34 | 35 | @author: Stijn De Weirdt (Ghent University) 36 | """ 37 | 38 | import logging 39 | from vsc.utils.generaloption import simple_option 40 | 41 | # dict = {longopt:(help_description,type,action,default_value,shortopt),} 42 | options = {"long1": ("1st long option", None, "store", "excellent", "L")} 43 | 44 | go = simple_option(options) 45 | 46 | go.log.info("1st option %s", go.options.long1) 47 | go.log.debug("DEBUG 1st option %s", go.options.long1) 48 | 49 | logging.info("logging from logging.info (eg from 3rd party module)") 50 | logging.debug("logging with logging.root root %s", logging.root) 51 | -------------------------------------------------------------------------------- /lib/vsc/utils/patterns.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Module offering the Singleton class. 28 | 29 | 30 | This class can be used as the C{__metaclass__} class field to ensure only a 31 | single instance of the class gets used in the run of an application or 32 | script. 33 | 34 | >>> class A(object): 35 | ... __metaclass__ = Singleton 36 | 37 | @author: Andy Georges (Ghent University) 38 | """ 39 | 40 | from abc import ABCMeta 41 | 42 | 43 | class Singleton(ABCMeta): 44 | """Serves as metaclass for classes that should implement the Singleton pattern. 45 | 46 | See http://stackoverflow.com/questions/6760685/creating-a-singleton-in-python 47 | """ 48 | 49 | _instances = {} 50 | 51 | def __call__(cls, *args, **kwargs): 52 | if cls not in cls._instances: 53 | cls._instances[cls] = super().__call__(*args, **kwargs) 54 | return cls._instances[cls] 55 | -------------------------------------------------------------------------------- /test/wrapper.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2014-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Tests for the vsc.utils.wrapper module. 28 | 29 | @author: Stijn De Weirdt (Ghent University) 30 | """ 31 | from vsc.install.testing import TestCase 32 | 33 | from vsc.utils.wrapper import Wrapper 34 | 35 | 36 | class TestWrapper(TestCase): 37 | """Test for the Wrapper class.""" 38 | def test_wrapper(self): 39 | """Use the tests provided by the stackoverflow page""" 40 | class DictWrapper(Wrapper): 41 | __wraps__ = dict 42 | 43 | wrapped_dict = DictWrapper(dict(a=1, b=2, c=3)) 44 | 45 | self.assertTrue("b" in wrapped_dict) # __contains__ 46 | self.assertEqual(wrapped_dict, dict(a=1, b=2, c=3)) # __eq__ 47 | self.assertTrue("'a': 1" in str(wrapped_dict)) # __str__ 48 | self.assertTrue(wrapped_dict.__doc__.startswith("dict()")) # __doc__ 49 | 50 | 51 | def suite(): 52 | """ return all the tests""" 53 | return TestLoader().loadTestsFromTestCase(TestWrapper) 54 | -------------------------------------------------------------------------------- /test/docs.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Unit tests for the docs module. 28 | 29 | @author: Kenneth Hoste (Ghent University) 30 | @author: Caroline De Brouwer (Ghent University) 31 | """ 32 | import os 33 | from vsc.install.testing import TestCase 34 | 35 | from vsc.utils.docs import mk_rst_table 36 | 37 | 38 | class DocsTest(TestCase): 39 | """Tests for docs functions.""" 40 | 41 | def test_mk_rst_table(self): 42 | """Test mk_rst_table function.""" 43 | entries = [['one', 'two', 'three']] 44 | t = 'This title is longer than the entries in the column' 45 | titles = [t] 46 | 47 | # small table 48 | table = mk_rst_table(titles, entries) 49 | check = [ 50 | '=' * len(t), 51 | t, 52 | '=' * len(t), 53 | 'one' + ' ' * (len(t) - 3), 54 | 'two' + ' ' * (len(t) -3), 55 | 'three' + ' ' * (len(t) - 5), 56 | '=' * len(t), 57 | '', 58 | ] 59 | self.assertEqual(table, check) 60 | 61 | def suite(): 62 | """ returns all the testcases in this module """ 63 | return TestLoader().loadTestsFromTestCase(DocsTest) 64 | 65 | if __name__ == '__main__': 66 | main() 67 | -------------------------------------------------------------------------------- /lib/vsc/utils/frozendict.py: -------------------------------------------------------------------------------- 1 | ### External compatible license 2 | # taken from https://github.com/slezica/python-frozendict on March 14th 2014 (commit ID b27053e4d1) 3 | # 4 | # Copyright (c) 2012 Santiago Lezica 5 | # 6 | # Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated 7 | # documentation files (the "Software"), to deal in the Software without restriction, including without limitation 8 | # the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, 9 | # and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 10 | # 11 | # The above copyright notice and this permission notice shall be included in all copies or substantial portions 12 | # of the Software. 13 | # 14 | # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED 15 | # TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 16 | # THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF 17 | # CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 18 | # IN THE SOFTWARE 19 | """ 20 | frozendict is an immutable wrapper around dictionaries that implements the complete mapping interface. 21 | It can be used as a drop-in replacement for dictionaries where immutability is desired. 22 | """ 23 | 24 | import operator 25 | from functools import reduce 26 | from collections.abc import Mapping 27 | 28 | 29 | class FrozenDict(Mapping): 30 | def __init__(self, *args, **kwargs): 31 | self.__dict = dict(*args, **kwargs) 32 | self.__hash = None 33 | 34 | def __getitem__(self, key): 35 | return self.__dict[key] 36 | 37 | def copy(self, **add_or_replace): 38 | return FrozenDict(self, **add_or_replace) 39 | 40 | def __iter__(self): 41 | return iter(self.__dict) 42 | 43 | def __len__(self): 44 | return len(self.__dict) 45 | 46 | def __repr__(self): 47 | return f"" 48 | 49 | def __hash__(self): 50 | if self.__hash is None: 51 | self.__hash = reduce(operator.xor, map(hash, self.items()), 0) 52 | 53 | return self.__hash 54 | 55 | # minor adjustment: define missing keys() method 56 | def keys(self): 57 | return self.__dict.keys() 58 | -------------------------------------------------------------------------------- /test/groups.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | tests for groups module 28 | """ 29 | import pwd 30 | import logging 31 | 32 | # Uncomment when debugging, cannot enable permanetnly, messes up tests that toggle debugging 33 | #logging.basicConfig(level=logging.DEBUG) 34 | 35 | from vsc.install.testing import TestCase 36 | 37 | from vsc.utils.groups import getgrouplist 38 | from vsc.utils.run import run 39 | 40 | class GroupsTest(TestCase): 41 | """TestCase for groups""" 42 | 43 | def test_getgrouplist(self): 44 | """Test getgrouplist""" 45 | for user in pwd.getpwall(): 46 | gidgroups = sorted(getgrouplist(user.pw_uid)) 47 | namegroups = sorted(getgrouplist(user.pw_name)) 48 | 49 | # get named groups from id 50 | # grp.getgrall is wrong, e.g. for root user on F30, 51 | # gr_mem for root group is empty (as is entry in /etc/group), 52 | # while id returns 1 group 53 | #groups = [g.gr_name for g in grp.getgrall() if user.pw_name in g.gr_mem] 54 | ec, groups_txt = run(['id', '-Gn', user.pw_name]) 55 | groups = sorted(groups_txt.strip().split()) 56 | 57 | logging.debug("User %s gidgroups %s namegroups %s groups %s", 58 | user, gidgroups, namegroups, groups) 59 | self.assertEqual(gidgroups, namegroups) 60 | self.assertEqual(gidgroups, groups) 61 | -------------------------------------------------------------------------------- /test/asyncprocess.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2012-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Unit tests for asyncprocess.py. 28 | 29 | @author: Toon Willems (Ghent University) 30 | @author: Stijn De Weirdt (Ghent University) 31 | """ 32 | 33 | import os 34 | import time 35 | from vsc.install.testing import TestCase 36 | 37 | import vsc.utils.asyncprocess as p 38 | from vsc.utils.asyncprocess import Popen 39 | 40 | 41 | def p_recv_some_exception(*args, **kwargs): 42 | """Call recv_some with raise exception enabled""" 43 | kwargs['e'] = True 44 | return p.recv_some(*args, **kwargs) 45 | 46 | 47 | class AsyncProcessTest(TestCase): 48 | """ Testcase for asyncprocess """ 49 | 50 | def setUp(self): 51 | """ setup a basic shell """ 52 | self.shell = Popen('sh', stdin=p.PIPE, stdout=p.PIPE, shell=True, executable='/bin/bash') 53 | self.cwd = os.getcwd() 54 | super().setUp() 55 | 56 | def runTest(self): 57 | """ try echoing some text and see if it comes back out """ 58 | p.send_all(self.shell, "echo hello\n") 59 | time.sleep(0.1) 60 | self.assertEqual(p.recv_some(self.shell), b"hello\n") 61 | 62 | p.send_all(self.shell, "echo hello world\n") 63 | time.sleep(0.1) 64 | self.assertEqual(p.recv_some(self.shell), b"hello world\n") 65 | 66 | p.send_all(self.shell, "exit\n") 67 | time.sleep(0.2) 68 | self.assertEqual(b"", p.recv_some(self.shell, e=False)) 69 | self.assertRaises(Exception, p_recv_some_exception, self.shell) 70 | 71 | def tearDown(self): 72 | """cleanup""" 73 | os.chdir(self.cwd) 74 | -------------------------------------------------------------------------------- /bin/optcomplete.bash: -------------------------------------------------------------------------------- 1 | #******************************************************************************\ 2 | # * Copyright (c) 2003-2004, Martin Blais 3 | # * All rights reserved. 4 | # * 5 | # * Redistribution and use in source and binary forms, with or without 6 | # * modification, are permitted provided that the following conditions are 7 | # * met: 8 | # * 9 | # * * Redistributions of source code must retain the above copyright 10 | # * notice, this list of conditions and the following disclaimer. 11 | # * 12 | # * * Redistributions in binary form must reproduce the above copyright 13 | # * notice, this list of conditions and the following disclaimer in the 14 | # * documentation and/or other materials provided with the distribution. 15 | # * 16 | # * * Neither the name of the Martin Blais, Furius, nor the names of its 17 | # * contributors may be used to endorse or promote products derived from 18 | # * this software without specific prior written permission. 19 | # * 20 | # * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | # * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | # * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | # * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | # * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | # * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | # * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | # * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | # * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | # * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | # * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | #******************************************************************************\ 32 | # 33 | # stdweird: This is a copy of etc/optcomplete.bash (changeset 17:e0a9131a94cc) 34 | # stdweird: source: https://hg.furius.ca/public/optcomplete 35 | # 36 | # optcomplete harness for bash shell. You then need to tell 37 | # bash to invoke this shell function with a command like 38 | # this: 39 | # 40 | # complete -F _optcomplete 41 | # 42 | 43 | _optcomplete() 44 | { 45 | # needed to let it return _filedir based commands 46 | local cur prev quoted 47 | _get_comp_words_by_ref cur prev 48 | _quote_readline_by_ref "$cur" quoted 49 | _expand || return 0 50 | 51 | # call the command with the completion information, then eval it's results so it can call _filedir or similar 52 | # this does have the potential to be a security problem, especially if running as root, but we should trust 53 | # the completions as we're planning to run this script anyway 54 | eval $( \ 55 | COMP_LINE=$COMP_LINE COMP_POINT=$COMP_POINT \ 56 | COMP_WORDS="${COMP_WORDS[*]}" COMP_CWORD=$COMP_CWORD \ 57 | OPTPARSE_AUTO_COMPLETE=1 $1 58 | ) 59 | } 60 | -------------------------------------------------------------------------------- /lib/vsc/utils/docs.py: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright 2015-2025 Ghent University 3 | # 4 | # This file is part of vsc-base, 5 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 6 | # with support of Ghent University (http://ugent.be/hpc), 7 | # the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be), 8 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 9 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 10 | # 11 | # https://github.com/hpcugent/vsc-base 12 | # 13 | # vsc-base is free software: you can redistribute it and/or modify 14 | # it under the terms of the GNU Library General Public License as 15 | # published by the Free Software Foundation, either version 2 of 16 | # the License, or (at your option) any later version. 17 | # 18 | # vsc-base is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21 | # GNU Library General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Library General Public License 24 | # along with vsc-base. If not, see . 25 | # 26 | """ 27 | Functions for generating rst documentation 28 | 29 | @author: Caroline De Brouwer (Ghent University) 30 | """ 31 | 32 | 33 | class LengthNotEqualException(ValueError): 34 | pass 35 | 36 | 37 | def mk_rst_table(titles, columns): 38 | """ 39 | Returns an rst table with given titles and columns (a nested list of string columns for each column) 40 | """ 41 | # make sure that both titles and columns are actual lists (not generator objects), 42 | # since we use them multiple times (and a generator can only be consumed once 43 | titles, columns = list(titles), list(columns) 44 | 45 | title_cnt, col_cnt = len(titles), len(columns) 46 | if title_cnt != col_cnt: 47 | msg = f"Number of titles/columns should be equal, found {int(title_cnt)} titles and {int(col_cnt)} columns" 48 | raise LengthNotEqualException(msg) 49 | 50 | table = [] 51 | separator_blocks = [] 52 | title_items = [] 53 | column_widths = [] 54 | 55 | for i, title in enumerate(titles): 56 | # figure out column widths 57 | width = max(map(len, columns[i] + [title])) 58 | 59 | column_widths.append(width) 60 | separator_blocks.append(f"{'=' * width}") 61 | title_items.append(f"{title}".ljust(width)) 62 | 63 | separator_line = " ".join(separator_blocks) 64 | 65 | # header 66 | table.extend([separator_line, " ".join(title_items), separator_line]) 67 | 68 | # rows 69 | for row in map(list, zip(*columns)): 70 | row_items = [] 71 | for i, item in enumerate(row): 72 | row_items.append(item.ljust(column_widths[i])) 73 | table.append(" ".join(row_items)) 74 | 75 | # footer 76 | table.extend([separator_line, ""]) 77 | 78 | return table 79 | -------------------------------------------------------------------------------- /examples/qa.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # 3 | # Copyright 2013-2013 Ghent University 4 | # 5 | # This file is part of vsc-base, 6 | # originally created by the HPC team of Ghent University (http://ugent.be/hpc/en), 7 | # with support of Ghent University (http://ugent.be/hpc), 8 | # the Flemish Supercomputer Centre (VSC) (https://vscentrum.be/nl/en), 9 | # the Flemish Research Foundation (FWO) (http://www.fwo.be/en) 10 | # and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en). 11 | # 12 | # http://github.com/hpcugent/vsc-base 13 | # 14 | # vsc-base is free software: you can redistribute it and/or modify 15 | # it under the terms of the GNU Library General Public License as 16 | # published by the Free Software Foundation, either version 2 of 17 | # the License, or (at your option) any later version. 18 | # 19 | # vsc-base is distributed in the hope that it will be useful, 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 | # GNU Library General Public License for more details. 23 | # 24 | # You should have received a copy of the GNU Library General Public License 25 | # along with vsc-base. If not, see . 26 | # 27 | """ 28 | Simple QA script 29 | 30 | @author: Stijn De Weirdt (Ghent University) 31 | """ 32 | 33 | import os 34 | 35 | from vsc.utils.run import run_qa, run_qalog, run_qastdout, run_async_to_stdout 36 | from vsc.utils.generaloption import simple_option 37 | 38 | go = simple_option(None) 39 | 40 | SCRIPT_DIR = os.path.join(os.path.dirname(__file__), "..", "test", "runtests") 41 | SCRIPT_QA = os.path.join(SCRIPT_DIR, "qa.py") 42 | 43 | 44 | def test_qa(): 45 | qa_dict = { 46 | "Simple question:": "simple answer", 47 | } 48 | ec, output = run_qa([SCRIPT_QA, "simple"], qa=qa_dict) 49 | return ec, output 50 | 51 | 52 | def test_qalog(): 53 | qa_dict = { 54 | "Simple question:": "simple answer", 55 | } 56 | ec, output = run_qalog([SCRIPT_QA, "simple"], qa=qa_dict) 57 | return ec, output 58 | 59 | 60 | def test_qastdout(): 61 | run_async_to_stdout([SCRIPT_QA, "simple"]) 62 | qa_dict = { 63 | "Simple question:": "simple answer", 64 | } 65 | ec, output = run_qastdout([SCRIPT_QA, "simple"], qa=qa_dict) 66 | return ec, output 67 | 68 | 69 | def test_std_regex(): 70 | qa_dict = { 71 | r"\s(?P