aboutsummaryrefslogtreecommitdiffstats
path: root/sources/shiboken6/tests/shiboken_paths.py
blob: c829c0ab93ad9906f641f1b0b7d867574d1c1488 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#############################################################################
##
## Copyright (C) 2020 The Qt Company Ltd.
## Contact: https://www.qt.io/licensing/
##
## This file is part of the test suite of Qt for Python.
##
## $QT_BEGIN_LICENSE:GPL-EXCEPT$
## Commercial License Usage
## Licensees holding valid commercial Qt licenses may use this file in
## accordance with the commercial license agreement provided with the
## Software or, alternatively, in accordance with the terms contained in
## a written agreement between you and The Qt Company. For licensing terms
## and conditions see https://www.qt.io/terms-conditions. For further
## information use the contact form at https://www.qt.io/contact-us.
##
## GNU General Public License Usage
## Alternatively, this file may be used under the terms of the GNU
## General Public License version 3 as published by the Free Software
## Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
## included in the packaging of this file. Please review the following
## information to ensure the GNU General Public License requirements will
## be met: https://www.gnu.org/licenses/gpl-3.0.html.
##
## $QT_END_LICENSE$
##
#############################################################################


import os
import sys
from pathlib import Path


def get_dir_env_var(var_name):
    """Return a directory set by an environment variable"""
    result = os.environ.get(var_name)
    if not result:
        raise ValueError(f'{var_name} is not set!')
    if not Path(result).is_dir():
        raise ValueError(f'{result} is not a directory!')
    return result


def get_build_dir():
    """
    Return the env var `BUILD_DIR`.
    If not set (interactive mode), take the last build history entry.
    """
    try:
        return get_dir_env_var('BUILD_DIR')
    except ValueError:
        look_for = Path("testing")
        here = Path(__file__).resolve().parent
        while here / look_for not in here.iterdir():
            import pprint
            parent = here.parent
            if parent == here:
                raise SystemError(look_for + " not found!")
            here = parent
        try:
            sys.path.insert(0, os.fspath(here))
            from testing.buildlog import builds
            if not builds.history:
                raise
            return builds.history[-1].build_dir
        finally:
            del sys.path[0]


def _prepend_path_var(var_name, paths):
    """Prepend additional paths to a path environment variable
       like PATH, LD_LIBRARY_PATH"""
    old_paths = os.environ.get(var_name)
    new_paths = os.pathsep.join(paths)
    if old_paths:
        new_paths += f'{os.pathsep}{old_paths}'
    os.environ[var_name] = new_paths


def add_python_dirs(python_dirs):
    """Add directories to the Python path unless present.
       Care is taken that the added directories come before
       site-packages."""
    new_paths = []
    for python_dir in python_dirs:
        new_paths.append(python_dir)
        if python_dir in sys.path:
            sys.path.remove(python_dir)
    sys.path[:0] = new_paths


def add_lib_dirs(lib_dirs):
    """Add directories to the platform's library path."""
    if sys.platform == 'win32':
        if sys.version_info >= (3, 8, 0):
            for lib_dir in lib_dirs:
                os.add_dll_directory(lib_dir)
        else:
            _prepend_path_var('PATH', lib_dirs)
    else:
        _prepend_path_var('LD_LIBRARY_PATH', lib_dirs)


def shiboken_paths(include_shiboken_tests=False):
    """Return a tuple of python directories/lib directories to be set for
       using the shiboken6 module from the build directory or running the
       shiboken tests depending on a single environment variable BUILD_DIR
       pointing to the build directory."""
    src_dir = Path(__file__).resolve().parent
    python_dirs = []
    if include_shiboken_tests:
        python_dirs.append(os.fspath(src_dir))  # For shiboken_test_helper
    python_dirs.append(get_build_dir())  # for toplevel shiboken6 import
    shiboken_dir = Path(get_build_dir()) / 'shiboken6'
    lib_dirs = [os.fspath(shiboken_dir / 'libshiboken')]
    if include_shiboken_tests:
        shiboken_test_dir = shiboken_dir /'tests'
        for module in ['minimal', 'sample', 'smart', 'other']:
            module_dir = shiboken_test_dir / f"{module}binding"
            python_dirs.append(os.fspath(module_dir))
            lib_dir = shiboken_test_dir / f"lib{module}"
            lib_dirs.append(os.fspath(lib_dir))
    return (python_dirs, lib_dirs)


def init_paths():
    """Sets the correct import paths (Python modules and C++ library
       paths) for testing shiboken depending on a single
       environment variable BUILD_DIR pointing to the build
       directory."""
    paths = shiboken_paths(True)
    add_python_dirs(paths[0])
    add_lib_dirs(paths[1])