Restructure: consolidate everything inside testium/ package

Move src/lib/ → src/testium/runtime/ (internal plumbing)
Move src/testium/libs/ → src/testium/api/ (public SDK for test scripts)
Move src/py_func/ → src/testium/py_func/ (Python subprocess)
Move src/lua_func/ → src/testium/lua_func/ (Lua subprocess data)

The package now ships as a single coherent unit instead of four sibling
top-level packages (testium, lib, py_func, lua_func) — pip install
gives a clean site-packages/testium/ with no namespace pollution; .lua
files travel with the wheel via package_data; the wheel installs
cleanly and `testium -b` runs end-to-end including py_func subprocesses
and entry-point exporter plugins.

Naming:
- runtime/ (internal, no API guarantees) clearer than lib/
- api/ (public SDK consumed as `import api.testium as tm`) clearer than libs/

Imports updated en masse: from lib. → from runtime. and from libs. →
from api., plus the importlib.import_module("libs.*") strings in
test_item_console.py and test_item_runtime_plot.py. Test/example
scripts (helper_lib.py, parallel.py, post_execution.py) and the
fake_exporter test suite migrated too.

paths.py: subproc_path() now returns testium_path() — both point at
the testium package directory since the subprocesses live inside.

pyproject.toml: removed exclude=["lua_func", "py_func"] (no longer
needed), added package-data for testium.lua_func/*.lua, removed the
license classifier (PEP 639 conflict with license expression).

Subprocess isolation contract: py_func/ and lua_func/ may only import
runtime/ and their own modules — never interpreter/, main_win/, api/,
or testium/. Enforced by test/validation/items/isolation/ which runs a
py_func that statically scans subprocess source files for forbidden
imports. The contract holds today; the test prevents future drift.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-02 09:28:40 +02:00
parent 8bd9b3e9d6
commit 4529da7aee
88 changed files with 230 additions and 139 deletions

View File

@@ -109,9 +109,28 @@ All dialog items (`dialog_image`, `dialog_question`, `dialog_references`, `dialo
| `src/testium/interpreter/test_items/test_item_parallel.py` | `parallel` and `parallel_branch` items | | `src/testium/interpreter/test_items/test_item_parallel.py` | `parallel` and `parallel_branch` items |
| `src/testium/interpreter/utils/globdict.py` | Global variable dict | | `src/testium/interpreter/utils/globdict.py` | Global variable dict |
| `src/testium/interpreter/utils/termlog.py` | Terminal color output | | `src/testium/interpreter/utils/termlog.py` | Terminal color output |
| `src/lib/stdout_redirect.py` | `StdioRedirect` singleton (`stdio_redir`) | | `src/testium/runtime/stdout_redirect.py` | `StdioRedirect` singleton (`stdio_redir`) |
| `src/lib/string_queue.py` | Thread-safe string buffer used for stdout redirection | | `src/testium/runtime/string_queue.py` | Thread-safe string buffer used for stdout redirection |
| `src/testium/libs/testium.py` | Public API for test scripts (`tm.*`) | | `src/testium/api/testium.py` | Public API for test scripts (`tm.*`) |
| `src/testium/py_func/` | Python subprocess for `py_func` items (sandboxed: imports only `runtime/` and `py_func/`) |
| `src/testium/lua_func/` | Lua subprocess scripts for `lua_func` items |
## Package layout
The whole project is a single Python package under `src/testium/`:
```
src/testium/
├── __init__.py / __main__.py
├── runtime/ internal plumbing (jrpc, stdout_redirect, string_queue, tum_except, api)
├── api/ public SDK exposed to test scripts (`import api.testium as tm`)
├── interpreter/ test execution engine (NOT visible to py_func/lua_func)
├── main_win/ GUI (NOT visible to py_func/lua_func)
├── py_func/ subprocess code for python_func items
└── lua_func/ subprocess scripts for lua_func items (data files)
```
`subproc_path()` and `testium_path()` both return the package directory. The py_func subprocess is launched with cwd=that directory and `python3 py_func`. The contract that `py_func/` and `lua_func/` only depend on `runtime/` (no `interpreter`, `main_win`, `api`, `testium`) is enforced by `test/validation/items/isolation/`.
## GUI icons (main_win) ## GUI icons (main_win)

View File

@@ -1,5 +1,5 @@
import libs.testium as tm import api.testium as tm
def post_exec(): def post_exec():
print('Success !!!!') print('Success !!!!')

View File

@@ -13,7 +13,6 @@ license-files = ["../LICENSE"]
classifiers = [ classifiers = [
"Development Status :: 5 - Production/Stable", "Development Status :: 5 - Production/Stable",
"Programming Language :: Python", "Programming Language :: Python",
"License :: OSI Approved :: European Union Public Licence 1.2 (EUPL 1.2)",
] ]
dependencies = [ dependencies = [
"setuptools", "setuptools",
@@ -36,7 +35,9 @@ testium = "testium:main"
[tool.setuptools.packages.find] [tool.setuptools.packages.find]
where=["."] where=["."]
exclude=["lua_func", "py_func"]
[tool.setuptools.package-data]
"testium.lua_func" = ["*.lua"]
[tool.setuptools.dynamic] [tool.setuptools.dynamic]
version = {file = ["VERSION"]} version = {file = ["VERSION"]}

View File

@@ -245,7 +245,7 @@ A {classname}.close() is missing somewhere in your code !'.format(classname=type
if not sys.platform.startswith('win'): if not sys.platform.startswith('win'):
# import SshConsole if pexpect is installed # import SshConsole if pexpect is installed
try: try:
from libs.console_ssh import SshConsole from api.console_ssh import SshConsole
except ImportError: except ImportError:
pass pass

View File

@@ -8,7 +8,7 @@ import os
import pexpect import pexpect
from pexpect import ExceptionPexpect, TIMEOUT, EOF, spawn from pexpect import ExceptionPexpect, TIMEOUT, EOF, spawn
from libs.console import Console from api.console import Console
# Exception classes used by this module. # Exception classes used by this module.

View File

@@ -3,7 +3,7 @@ import sys
import socket import socket
import traceback import traceback
from libs.console import * from api.console import *
class RawTCPConsole(Console): class RawTCPConsole(Console):
TYPE = 'rawtcp' TYPE = 'rawtcp'

View File

@@ -16,9 +16,9 @@ import numpy as np
import matplotlib.dates as mdates import matplotlib.dates as mdates
from datetime import datetime, timedelta, timezone from datetime import datetime, timedelta, timezone
import libs.testium as tm import api.testium as tm
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
from interpreter.utils.py_func_exec import PyFuncExecEngine from interpreter.utils.py_func_exec import PyFuncExecEngine
from interpreter.utils.api_srv import api_request from interpreter.utils.api_srv import api_request
from interpreter.utils.eval import post_evaluate from interpreter.utils.eval import post_evaluate

View File

@@ -10,7 +10,7 @@ import os
ourPath = os.path.dirname(__file__) ourPath = os.path.dirname(__file__)
sys.path.append(ourPath) sys.path.append(ourPath)
from libs.console import (Console, BytesStore, TIMEOUT_NULL) from api.console import (Console, BytesStore, TIMEOUT_NULL)
class TermConsole(Console): class TermConsole(Console):
TYPE = 'term' TYPE = 'term'

View File

@@ -4,7 +4,7 @@ import sys
import textwrap import textwrap
from time import monotonic from time import monotonic
import interpreter.utils.globdict as globdict import interpreter.utils.globdict as globdict
from lib.tum_except import (ETUMSyntaxError) from runtime.tum_except import (ETUMSyntaxError)
############################################################################### ###############################################################################
# Console helper functions # Console helper functions
@@ -14,7 +14,7 @@ def add_console(console):
''' Function which adds a ``Console`` class instance to *testium* ''' Function which adds a ``Console`` class instance to *testium*
:param console: The ``Console`` instance. :param console: The ``Console`` instance.
:type console: ``libs.console.Console`` or child class instance :type console: ``api.console.Console`` or child class instance
:return: No returned value :return: No returned value
''' '''
@@ -48,7 +48,7 @@ def console(name):
:param name: The name of the ``Console`` instance. :param name: The name of the ``Console`` instance.
:type name: str :type name: str
:return: The ``Console`` or child class object :return: The ``Console`` or child class object
:rtype: ``libs.console.Console`` or child class instance :rtype: ``api.console.Console`` or child class instance
""" """
cons = None cons = None
for c in globdict.gd('console_instances', []): for c in globdict.gd('console_instances', []):
@@ -65,7 +65,7 @@ def add_plot(plot: object) -> None:
''' Function which adds a ``RuntimePlot`` class instance to *testium* ''' Function which adds a ``RuntimePlot`` class instance to *testium*
:param plot: The ``RuntimePlot`` instance. :param plot: The ``RuntimePlot`` instance.
:type plot: ``libs.runtime_plot.RuntimePlot`` or child class instance :type plot: ``api.runtime_plot.RuntimePlot`` or child class instance
:return: No returned value :return: No returned value
''' '''
@@ -99,7 +99,7 @@ def plot(name: str) -> object:
:param name: The name of the ``RuntimePlot`` instance. :param name: The name of the ``RuntimePlot`` instance.
:type name: str :type name: str
:return: The ``RuntimePlot`` or child class object :return: The ``RuntimePlot`` or child class object
:rtype: ``libs.runtime_plot.RuntimePlot`` or child class instance :rtype: ``api.runtime_plot.RuntimePlot`` or child class instance
""" """
plot = None plot = None
for g in globdict.gd('plot_instances', []): for g in globdict.gd('plot_instances', []):

View File

@@ -9,8 +9,8 @@ from multiprocessing import Queue
from interpreter.process import TestProcess from interpreter.process import TestProcess
from interpreter.utils.test_ctrl import TestSetController from interpreter.utils.test_ctrl import TestSetController
from lib.tum_except import ETUMFileError, ETUMRuntimeError from runtime.tum_except import ETUMFileError, ETUMRuntimeError
from lib.stdout_redirect import stdio_redir from runtime.stdout_redirect import stdio_redir
class Batch: class Batch:

View File

@@ -6,9 +6,9 @@ from threading import Thread
from time import sleep from time import sleep
import copy import copy
from lib.string_queue import StringQueue from runtime.string_queue import StringQueue
from lib.tum_except import print_exception, ETUMRuntimeError, ETUMSyntaxError from runtime.tum_except import print_exception, ETUMRuntimeError, ETUMSyntaxError
import libs.testium as tm import api.testium as tm
import interpreter.utils.globdict as globdict import interpreter.utils.globdict as globdict
from interpreter.utils.params import expanse from interpreter.utils.params import expanse
from interpreter.utils.test_ctrl import TestSetController from interpreter.utils.test_ctrl import TestSetController
@@ -26,7 +26,7 @@ from interpreter.utils.test_init import (
from interpreter.utils.constants import TestItemType as cst_type from interpreter.utils.constants import TestItemType as cst_type
from interpreter.test_set import TestSet from interpreter.test_set import TestSet
from interpreter.utils.include import TUMLoader, TUMLoaderNoIncludes, TUMLoaderRawIncludes from interpreter.utils.include import TUMLoader, TUMLoaderNoIncludes, TUMLoaderRawIncludes
from lib.stdout_redirect import stdio_redir from runtime.stdout_redirect import stdio_redir
from interpreter.utils.template import template_to_test from interpreter.utils.template import template_to_test
from interpreter.utils.yaml_load import yaml_load from interpreter.utils.yaml_load import yaml_load
from interpreter.utils.py_eval import eval_process_init from interpreter.utils.py_eval import eval_process_init

View File

@@ -1,4 +1,4 @@
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
from interpreter.test_items.test_item import TestItem, test_run, test_data from interpreter.test_items.test_item import TestItem, test_run, test_data
from interpreter.test_items.test_result import TestResult, TestValue from interpreter.test_items.test_result import TestResult, TestValue
from interpreter.test_items.item_actions.action import TestItemAction from interpreter.test_items.item_actions.action import TestItemAction

View File

@@ -3,11 +3,11 @@ from time import sleep
import yaml import yaml
from copy import deepcopy from copy import deepcopy
from interpreter.test_items.test_result import TestResult, TestValue from interpreter.test_items.test_result import TestResult, TestValue
import libs.testium as tm import api.testium as tm
from interpreter.utils.params import TestItemParams from interpreter.utils.params import TestItemParams
from interpreter.utils.constants import TestItemType as cst_type from interpreter.utils.constants import TestItemType as cst_type
from interpreter.utils.eval import eval_to_boolean, evaluate, post_evaluate from interpreter.utils.eval import eval_to_boolean, evaluate, post_evaluate
from lib.tum_except import ETUMSyntaxError, item_load_context from runtime.tum_except import ETUMSyntaxError, item_load_context
LOG_TEST_STOP = '<----- step "{}" finished' LOG_TEST_STOP = '<----- step "{}" finished'
LOG_TEST_START = '-----> step "{}" started' LOG_TEST_START = '-----> step "{}" started'

View File

@@ -1,8 +1,8 @@
from interpreter.test_items.test_item import (TestItem, test_run) from interpreter.test_items.test_item import (TestItem, test_run)
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from lib.tum_except import ETUMSyntaxError, item_load_context from runtime.tum_except import ETUMSyntaxError, item_load_context
import libs.testium as tm import api.testium as tm
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from interpreter.utils.eval import evaluate from interpreter.utils.eval import evaluate

View File

@@ -2,8 +2,8 @@ from interpreter.test_items.test_item import test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import item_load_context from runtime.tum_except import item_load_context
import libs.testium as tm import api.testium as tm
class TestItemChoicesDialog(TestItemDialogBase): class TestItemChoicesDialog(TestItemDialogBase):

View File

@@ -3,9 +3,9 @@ import os
import importlib import importlib
import traceback import traceback
import libs.testium as tm import api.testium as tm
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
from lib.stdout_redirect import stdio_redir from runtime.stdout_redirect import stdio_redir
from interpreter.test_items.test_item import test_run from interpreter.test_items.test_item import test_run
from interpreter.test_items.item_actions import TestItemActions from interpreter.test_items.item_actions import TestItemActions
from interpreter.test_items.item_actions.action import TestItemAction from interpreter.test_items.item_actions.action import TestItemAction
@@ -345,17 +345,17 @@ class TestItemConsole(TestItemActions):
self.actions_token = {} self.actions_token = {}
global console global console
console = importlib.import_module("libs.console") console = importlib.import_module("api.console")
if not sys.platform.startswith("win"): if not sys.platform.startswith("win"):
global console_ssh global console_ssh
console_ssh = importlib.import_module("libs.console_ssh") console_ssh = importlib.import_module("api.console_ssh")
global termconsole global termconsole
termconsole = importlib.import_module("libs.termconsole") termconsole = importlib.import_module("api.termconsole")
global raw_tcp_console global raw_tcp_console
raw_tcp_console = importlib.import_module("libs.raw_tcp_console") raw_tcp_console = importlib.import_module("api.raw_tcp_console")
self.actions_token["console_name"] = self._prms.getParam( self.actions_token["console_name"] = self._prms.getParam(
"console_name", required=True "console_name", required=True

View File

@@ -1,11 +1,11 @@
import traceback import traceback
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError from runtime.tum_except import ETUMSyntaxError, ETUMRuntimeError
from interpreter.utils.py_func_exec import PyFuncExecEngine from interpreter.utils.py_func_exec import PyFuncExecEngine
from interpreter.utils.api_srv import api_request from interpreter.utils.api_srv import api_request
from interpreter.test_items.test_item import TestItem, test_run from interpreter.test_items.test_item import TestItem, test_run
from interpreter.test_items.test_result import TestResult, TestValue from interpreter.test_items.test_result import TestResult, TestValue
import libs.testium as tm import api.testium as tm
from interpreter.utils.params import TestItemParams from interpreter.utils.params import TestItemParams
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst

View File

@@ -1,6 +1,6 @@
import multiprocessing import multiprocessing
import libs.testium as tm import api.testium as tm
from interpreter.test_items.test_item import TestItem from interpreter.test_items.test_item import TestItem

View File

@@ -1,7 +1,7 @@
from interpreter.test_items.test_item import (TestItem, test_run) from interpreter.test_items.test_item import (TestItem, test_run)
from interpreter.test_items.test_result import (TestValue) from interpreter.test_items.test_result import (TestValue)
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import ETUMParamError, ETUMSyntaxError from runtime.tum_except import ETUMParamError, ETUMSyntaxError
import interpreter.utils.version as git import interpreter.utils.version as git
class TestItemGit(TestItem): class TestItemGit(TestItem):

View File

@@ -1,8 +1,8 @@
from interpreter.test_items.test_item import (TestItem, test_run) from interpreter.test_items.test_item import (TestItem, test_run)
from interpreter.test_items.test_result import (TestResult, TestValue) from interpreter.test_items.test_result import (TestResult, TestValue)
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
import libs.testium as tm import api.testium as tm
class TestItemGroup(TestItem): class TestItemGroup(TestItem):
def __init__(self, dict_cycle, parent = None, status_queue=None, filename=""): def __init__(self, dict_cycle, parent = None, status_queue=None, filename=""):

View File

@@ -4,8 +4,8 @@ from interpreter.test_items.test_item import test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import item_load_context from runtime.tum_except import item_load_context
import libs.testium as tm import api.testium as tm
class TestItemImageDialog(TestItemDialogBase): class TestItemImageDialog(TestItemDialogBase):

View File

@@ -2,7 +2,7 @@ import sys
import traceback import traceback
from random import randint from random import randint
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
from interpreter.test_items.test_item import TestItem, test_run from interpreter.test_items.test_item import TestItem, test_run
from interpreter.test_items.test_result import TestResult, TestValue from interpreter.test_items.test_result import TestResult, TestValue

View File

@@ -3,9 +3,9 @@ import socket
import re import re
import struct import struct
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
import libs.testium as tm import api.testium as tm
from libs.console import Console from api.console import Console
def is_ip_address(address): def is_ip_address(address):

View File

@@ -5,8 +5,8 @@ import time
from interpreter.test_items.test_item import (TestItem, test_run) from interpreter.test_items.test_item import (TestItem, test_run)
from interpreter.test_items.test_result import (TestResult, TestValue) from interpreter.test_items.test_result import (TestResult, TestValue)
from lib.tum_except import ETUMSyntaxError, item_load_context from runtime.tum_except import ETUMSyntaxError, item_load_context
import libs.testium as tm import api.testium as tm
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
class TestItemLet(TestItem): class TestItemLet(TestItem):

View File

@@ -4,10 +4,10 @@ import traceback
import pprint import pprint
import textwrap import textwrap
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context from runtime.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context
from interpreter.test_items.test_item import TestItem, test_run from interpreter.test_items.test_item import TestItem, test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
import libs.testium as tm import api.testium as tm
from interpreter.utils.lua_func_exec import LuaFuncExecEngine from interpreter.utils.lua_func_exec import LuaFuncExecEngine
from interpreter.utils.api_srv import api_request from interpreter.utils.api_srv import api_request
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst

View File

@@ -5,7 +5,7 @@ from interpreter.test_items.test_item import test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import item_load_context from runtime.tum_except import item_load_context
class TestItemMsgDialog(TestItemDialogBase): class TestItemMsgDialog(TestItemDialogBase):

View File

@@ -2,8 +2,8 @@ from interpreter.test_items.test_item import test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import item_load_context from runtime.tum_except import item_load_context
import libs.testium as tm import api.testium as tm
class TestItemNoteDialog(TestItemDialogBase): class TestItemNoteDialog(TestItemDialogBase):

View File

@@ -6,9 +6,9 @@ from interpreter.test_items.test_item import test_run
from interpreter.test_items.test_result import TestResult, TestValue from interpreter.test_items.test_result import TestResult, TestValue
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from interpreter.utils.eval import eval_to_boolean from interpreter.utils.eval import eval_to_boolean
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
from lib.string_queue import StringQueue from runtime.string_queue import StringQueue
from lib.stdout_redirect import stdio_redir from runtime.stdout_redirect import stdio_redir
class TestItemParallelBranch(TestItemContainer): class TestItemParallelBranch(TestItemContainer):

View File

@@ -4,10 +4,10 @@ import time
import pprint import pprint
import textwrap import textwrap
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context from runtime.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context
from interpreter.test_items.test_item import TestItem, test_run from interpreter.test_items.test_item import TestItem, test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
import libs.testium as tm import api.testium as tm
from interpreter.utils.py_func_exec import PyFuncExecEngine from interpreter.utils.py_func_exec import PyFuncExecEngine
from interpreter.utils.api_srv import api_request from interpreter.utils.api_srv import api_request
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst

View File

@@ -2,7 +2,7 @@ from interpreter.test_items.test_item import test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import item_load_context from runtime.tum_except import item_load_context
class TestItemQuestionDialog(TestItemDialogBase): class TestItemQuestionDialog(TestItemDialogBase):

View File

@@ -1,7 +1,7 @@
from interpreter.test_items.test_item import (TestItem, test_run) from interpreter.test_items.test_item import (TestItem, test_run)
from interpreter.test_items.test_result import (TestValue) from interpreter.test_items.test_result import (TestValue)
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from interpreter.test_report.test_report import Export from interpreter.test_report.test_report import Export

View File

@@ -8,9 +8,9 @@ import traceback
from interpreter.test_items.test_item import (TestItem, test_run) from interpreter.test_items.test_item import (TestItem, test_run)
from interpreter.test_items.test_result import (TestValue) from interpreter.test_items.test_result import (TestValue)
import libs.testium as tm import api.testium as tm
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context from runtime.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context
def nowInBetween(start, end): def nowInBetween(start, end):

View File

@@ -3,8 +3,8 @@ import importlib
import traceback import traceback
from functools import wraps from functools import wraps
import libs.testium as tm import api.testium as tm
from lib.tum_except import ETUMSyntaxError, item_load_context from runtime.tum_except import ETUMSyntaxError, item_load_context
from interpreter.test_items.test_item import TestItem, test_run from interpreter.test_items.test_item import TestItem, test_run
from interpreter.test_items.test_result import TestResult, TestValue from interpreter.test_items.test_result import TestResult, TestValue
from interpreter.test_items.item_actions import TestItemActions from interpreter.test_items.item_actions import TestItemActions
@@ -235,4 +235,4 @@ class TestItemPlot(TestItemActions):
self.actions_token = self._prms.getParam("plot_name", required=True) self.actions_token = self._prms.getParam("plot_name", required=True)
global runtime_plot global runtime_plot
runtime_plot = importlib.import_module("libs.runtime_plot") runtime_plot = importlib.import_module("api.runtime_plot")

View File

@@ -3,11 +3,11 @@ from time import sleep
from datetime import timedelta from datetime import timedelta
from multiprocessing import Process, Pipe from multiprocessing import Process, Pipe
import libs.testium as tm import api.testium as tm
from interpreter.test_items.test_item import (TestItem, test_run) from interpreter.test_items.test_item import (TestItem, test_run)
from interpreter.test_items.test_result import (TestValue) from interpreter.test_items.test_result import (TestValue)
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context from runtime.tum_except import ETUMSyntaxError, ETUMRuntimeError, item_load_context
class TestItemSleep(TestItem): class TestItemSleep(TestItem):
"""sleep item usage. """sleep item usage.

View File

@@ -2,8 +2,8 @@ from interpreter.test_items.test_item import test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import item_load_context from runtime.tum_except import item_load_context
import libs.testium as tm import api.testium as tm
class TestItemTestedRefsDialog(TestItemDialogBase): class TestItemTestedRefsDialog(TestItemDialogBase):

View File

@@ -4,14 +4,14 @@ from unittest import (TestCase, TestSuite, TextTestRunner,
TextTestResult) TextTestResult)
from unittest.loader import defaultTestLoader from unittest.loader import defaultTestLoader
import libs.testium as tm import api.testium as tm
from lib.tum_except import (ETUMFileError) from runtime.tum_except import (ETUMFileError)
from interpreter.utils.modules import load_source from interpreter.utils.modules import load_source
from interpreter.test_items.test_item import (TestItem, test_run, LOG_TEST_STOP, LOG_TEST_START) from interpreter.test_items.test_item import (TestItem, test_run, LOG_TEST_STOP, LOG_TEST_START)
from interpreter.test_items.test_result import (TestResult, TestValue) from interpreter.test_items.test_result import (TestResult, TestValue)
from interpreter.test_items.test_item import test_data from interpreter.test_items.test_item import test_data
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.stdout_redirect import stdio_redir from runtime.stdout_redirect import stdio_redir
class UnittestResult(TextTestResult): class UnittestResult(TextTestResult):
"""Test result adapted for unittest test""" """Test result adapted for unittest test"""

View File

@@ -2,8 +2,8 @@ from interpreter.test_items.test_item import test_run
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue
from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive from interpreter.test_items.test_item_dialog_base import TestItemDialogBase, _is_text_mode, _is_interactive
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from lib.tum_except import item_load_context from runtime.tum_except import item_load_context
import libs.testium as tm import api.testium as tm
class TestItemValueDialog(TestItemDialogBase): class TestItemValueDialog(TestItemDialogBase):

View File

@@ -1,4 +1,4 @@
from lib.tum_except import (ETUMRuntimeError) from runtime.tum_except import (ETUMRuntimeError)
from datetime import datetime from datetime import datetime
from enum import Enum from enum import Enum

View File

@@ -3,7 +3,7 @@ import os
import interpreter.test_report.test_report as tr import interpreter.test_report.test_report as tr
from interpreter.utils.paths import prepare_file_to_save from interpreter.utils.paths import prepare_file_to_save
import interpreter.utils.constants as cst import interpreter.utils.constants as cst
import libs.testium as tm import api.testium as tm
class ReportExport: class ReportExport:

View File

@@ -1,5 +1,5 @@
from junit_xml import (TestSuite, TestCase) from junit_xml import (TestSuite, TestCase)
import libs.testium as tm import api.testium as tm
from interpreter.test_items.test_result import (TestValue) from interpreter.test_items.test_result import (TestValue)
import interpreter.test_report.report_export as rpe import interpreter.test_report.report_export as rpe
import interpreter.test_report.test_report as tr import interpreter.test_report.test_report as tr

View File

@@ -4,8 +4,8 @@ from functools import wraps
import sqlite3 import sqlite3
from time import (time, sleep) from time import (time, sleep)
import traceback import traceback
from lib.tum_except import (ETUMRuntimeError, ETUMSyntaxError) from runtime.tum_except import (ETUMRuntimeError, ETUMSyntaxError)
from lib.stdout_redirect import stdio_redir from runtime.stdout_redirect import stdio_redir
from interpreter.utils.params import (expanse) from interpreter.utils.params import (expanse)
from interpreter.utils.paths import prepare_file_to_save from interpreter.utils.paths import prepare_file_to_save
import interpreter.utils.constants as cst import interpreter.utils.constants as cst

View File

@@ -2,13 +2,13 @@ import os
import datetime import datetime
from queue import Queue from queue import Queue
from interpreter.utils.params import expanse from interpreter.utils.params import expanse
import libs.testium as tm import api.testium as tm
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
import interpreter.utils.settings as prefs import interpreter.utils.settings as prefs
from interpreter.test_report.test_report import TestReport from interpreter.test_report.test_report import TestReport
from interpreter.utils.py_func_exec import PyFuncExecEngine from interpreter.utils.py_func_exec import PyFuncExecEngine
from interpreter.utils.api_srv import api_request from interpreter.utils.api_srv import api_request
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
from interpreter.utils.constants import TestItemType as cst_type from interpreter.utils.constants import TestItemType as cst_type
import interpreter.utils.constants as cst import interpreter.utils.constants as cst
from interpreter.utils.constants import TEST_TYPE_LIST from interpreter.utils.constants import TEST_TYPE_LIST

View File

@@ -1,6 +1,6 @@
from lib.api import SUPPORTED_API from runtime.api import SUPPORTED_API
import libs.testium as tm import api.testium as tm
# Fill the api_dict with the function of tm # Fill the api_dict with the function of tm
api_dict = {k: getattr(tm, k) for k in SUPPORTED_API if hasattr(tm, k)} api_dict = {k: getattr(tm, k) for k in SUPPORTED_API if hasattr(tm, k)}

View File

@@ -1,6 +1,6 @@
import libs.testium as tm import api.testium as tm
from interpreter.utils.py_eval import eval_exec from interpreter.utils.py_eval import eval_exec
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError from runtime.tum_except import ETUMSyntaxError, ETUMRuntimeError
def evaluate(val, **replacement_dict): def evaluate(val, **replacement_dict):

View File

@@ -1,8 +1,8 @@
import yaml import yaml
import os.path import os.path
import libs.testium as tm import api.testium as tm
from interpreter.utils.params import expanse from interpreter.utils.params import expanse
from lib.tum_except import ETUMFileError from runtime.tum_except import ETUMFileError
from interpreter.utils.template import template_to_test from interpreter.utils.template import template_to_test
from copy import copy from copy import copy
from interpreter.utils.globdict import global_dict from interpreter.utils.globdict import global_dict

View File

@@ -1,6 +1,6 @@
from interpreter.utils.lua_process import LuaProcessBase from interpreter.utils.lua_process import LuaProcessBase
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue

View File

@@ -4,10 +4,10 @@ import shutil
import subprocess import subprocess
import socket import socket
import libs.testium as tm import api.testium as tm
from lib.jrpc import JsonRpcClient from runtime.jrpc import JsonRpcClient
from interpreter.utils.paths import subproc_path from interpreter.utils.paths import subproc_path
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
from interpreter.utils.paths import sys_app_path_lin, sys_app_path_win from interpreter.utils.paths import sys_app_path_lin, sys_app_path_win
def _lua_version(path: str): def _lua_version(path: str):

View File

@@ -1,5 +1,5 @@
import interpreter.utils.globdict as globdict import interpreter.utils.globdict as globdict
from lib.tum_except import ETUMSyntaxError, ETUMRuntimeError from runtime.tum_except import ETUMSyntaxError, ETUMRuntimeError
glob_eval_func = None glob_eval_func = None

View File

@@ -5,7 +5,7 @@ from pathlib import Path
import testium import testium
from interpreter.utils.params import expanse from interpreter.utils.params import expanse
import subprocess import subprocess
import libs.testium as tm import api.testium as tm
def testium_path(): def testium_path():
@@ -18,12 +18,9 @@ def testium_path():
return str(Path(tp).parent.resolve()) return str(Path(tp).parent.resolve())
def subproc_path(): def subproc_path():
if getattr(sys, 'frozen', False): # py_func and lua_func now live inside the testium package; their cwd
# Exécuté depuis le .exe # is the testium package root, same as testium_path().
return sys._MEIPASS return testium_path()
tp = inspect.getfile(inspect.getmodule(testium))
return str(Path(tp).parent.parent.resolve())
def prepare_file_to_save(file_name, file_ext=""): def prepare_file_to_save(file_name, file_ext=""):
iname = file_name iname = file_name

View File

@@ -1,6 +1,6 @@
from interpreter.utils.py_process import PyProcessBase from interpreter.utils.py_process import PyProcessBase
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
import libs.testium as tm import api.testium as tm
eval_process = None eval_process = None

View File

@@ -1,6 +1,6 @@
from interpreter.utils.py_process import PyProcessBase from interpreter.utils.py_process import PyProcessBase
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
from interpreter.test_items.test_result import TestValue from interpreter.test_items.test_result import TestValue

View File

@@ -3,10 +3,10 @@ import shutil
import sys import sys
import subprocess import subprocess
import socket import socket
from lib.jrpc import JsonRpcClient from runtime.jrpc import JsonRpcClient
import libs.testium as tm import api.testium as tm
from interpreter.utils.paths import sys_app_path_lin, sys_app_path_win from interpreter.utils.paths import sys_app_path_lin, sys_app_path_win
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
from interpreter.utils.paths import testium_path, subproc_path from interpreter.utils.paths import testium_path, subproc_path

View File

@@ -2,7 +2,7 @@ import os
import configparser import configparser
import json import json
import platform import platform
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
SettingsCompany = 'Testium' SettingsCompany = 'Testium'
SettingsApplication = 'testium' SettingsApplication = 'testium'

View File

@@ -4,7 +4,7 @@ from jinja2 import Template
from jinja2.exceptions import TemplateSyntaxError, TemplateError, UndefinedError from jinja2.exceptions import TemplateSyntaxError, TemplateError, UndefinedError
from tempfile import TemporaryFile from tempfile import TemporaryFile
from interpreter.utils.yaml_load import print_yaml from interpreter.utils.yaml_load import print_yaml
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
def template_to_test(filename: str, params: list): def template_to_test(filename: str, params: list):

View File

@@ -1,6 +1,6 @@
from multiprocessing import Queue from multiprocessing import Queue
from queue import Empty from queue import Empty
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
class TestSetController: class TestSetController:

View File

@@ -7,13 +7,13 @@ import yaml
import copy import copy
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
import libs.testium as tm import api.testium as tm
import interpreter.utils.globdict as globdict import interpreter.utils.globdict as globdict
import interpreter.utils.settings as prefs import interpreter.utils.settings as prefs
from interpreter.utils.paths import testium_path from interpreter.utils.paths import testium_path
from interpreter.utils.yaml_load import yaml_load from interpreter.utils.yaml_load import yaml_load
from interpreter.utils import clear_recursively from interpreter.utils import clear_recursively
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
from interpreter.utils.params import expanse, eval_func_init from interpreter.utils.params import expanse, eval_func_init
from interpreter.utils.eval import evaluate from interpreter.utils.eval import evaluate
from interpreter.utils.version import ( from interpreter.utils.version import (

View File

@@ -3,7 +3,7 @@ import sys
from importlib import import_module from importlib import import_module
import interpreter.utils.settings as prefs import interpreter.utils.settings as prefs
import libs.testium as tm import api.testium as tm
_cached_versions = {} _cached_versions = {}

View File

@@ -1,8 +1,8 @@
from yaml.parser import ParserError from yaml.parser import ParserError
from yaml import load, Loader from yaml import load, Loader
from yaml.scanner import ScannerError from yaml.scanner import ScannerError
from libs.testium import print_debug from api.testium import print_debug
from lib.tum_except import ETUMSyntaxError from runtime.tum_except import ETUMSyntaxError
import io import io

View File

@@ -10,7 +10,7 @@ from interpreter.process import TestProcess
from interpreter.utils.test_ctrl import TestSetController from interpreter.utils.test_ctrl import TestSetController
from main_win.test_controller_service import TestControllerService from main_win.test_controller_service import TestControllerService
import interpreter.utils.settings as prefs import interpreter.utils.settings as prefs
from lib.tum_except import ETUMFileError, ETUMRuntimeError from runtime.tum_except import ETUMFileError, ETUMRuntimeError
class TestFileManager: class TestFileManager:

View File

@@ -10,12 +10,12 @@ from PySide6.QtGui import (QFont, QFontInfo)
from time import (time) from time import (time)
from main_win.test_tree_items.common import (TEST_COLS, TEST_COLS_WITH_TIME) from main_win.test_tree_items.common import (TEST_COLS, TEST_COLS_WITH_TIME)
from lib.tum_except import (ETUMFileError, ETUMSyntaxError) from runtime.tum_except import (ETUMFileError, ETUMSyntaxError)
from main_win.test_controller_service import TestControllerService from main_win.test_controller_service import TestControllerService
from main_win.test_tree_items.test_tree_item import make_tree_item from main_win.test_tree_items.test_tree_item import make_tree_item
from interpreter.test_items.test_result import (TestValue) from interpreter.test_items.test_result import (TestValue)
import libs.testium as tm import api.testium as tm
import interpreter.utils.settings as prefs import interpreter.utils.settings as prefs
from interpreter.utils.constants import TestItemType as cst from interpreter.utils.constants import TestItemType as cst
from interpreter.utils.icons import icon_prefix from interpreter.utils.icons import icon_prefix

View File

@@ -5,7 +5,7 @@ from PySide6.QtGui import (QIcon, QPixmap, QBrush, QColor)
from PySide6.QtCore import Qt from PySide6.QtCore import Qt
from PySide6.QtWidgets import (QTreeWidgetItem) from PySide6.QtWidgets import (QTreeWidgetItem)
from interpreter.utils.icons import icon_prefix from interpreter.utils.icons import icon_prefix
from libs.testium import print_warn from api.testium import print_warn
# Maps item_name (from TestItemType.item_name) to visual config. # Maps item_name (from TestItemType.item_name) to visual config.
# Keys: icon (required), icon_on (optional 2nd state), expanded, unfoldable, no_breakpoint # Keys: icon (required), icon_on (optional 2nd state), expanded, unfoldable, no_breakpoint

View File

@@ -30,7 +30,7 @@ from main_win.f1_win.d_f1_win import DialogF1
from main_win.test_tree import QTestTree from main_win.test_tree import QTestTree
from main_win.test_run.thread_output import ThreadTestOutput from main_win.test_run.thread_output import ThreadTestOutput
from lib.string_queue import StringQueue from runtime.string_queue import StringQueue
from interpreter.process import TestProcess from interpreter.process import TestProcess
from interpreter.utils.test_ctrl import TestSetController from interpreter.utils.test_ctrl import TestSetController
from interpreter.utils.icons import icon_prefix from interpreter.utils.icons import icon_prefix
@@ -38,14 +38,14 @@ from interpreter.utils.icons import icon_prefix
from main_win.test_run.outlog import OutLog from main_win.test_run.outlog import OutLog
from main_win.test_run.test_run import ThreadTestStatus from main_win.test_run.test_run import ThreadTestStatus
import interpreter.utils.settings as prefs import interpreter.utils.settings as prefs
from lib.stdout_redirect import stdio_redir from runtime.stdout_redirect import stdio_redir
import libs.testium as tm import api.testium as tm
from interpreter.utils.test_init import ( from interpreter.utils.test_init import (
env_init, env_init,
locate_report_file, locate_report_file,
) )
from interpreter.utils.version import get_testium_version from interpreter.utils.version import get_testium_version
from lib.tum_except import ETUMFileError, ETUMRuntimeError from runtime.tum_except import ETUMFileError, ETUMRuntimeError
from main_win.test_controller_service import TestControllerService from main_win.test_controller_service import TestControllerService
from main_win.test_runner import TestRunner, TestState from main_win.test_runner import TestRunner, TestState
from main_win.test_file_manager import TestFileManager from main_win.test_file_manager import TestFileManager

View File

@@ -6,7 +6,7 @@ from PySide6.QtGui import QCursor, QDesktopServices, QFont
from main_win.text_log_highlighter import TextLogHighlighter from main_win.text_log_highlighter import TextLogHighlighter
import libs.testium as tm import api.testium as tm
class QTextLog(QPlainTextEdit): class QTextLog(QPlainTextEdit):
def __init__(self, parent): def __init__(self, parent):

View File

@@ -1,7 +1,7 @@
#!/usr/bin/env python #!/usr/bin/env python
import multiprocessing import multiprocessing
from py_func.tm import _init_api, _remote_print from py_func.tm import _init_api, _remote_print
from lib.stdout_redirect import stdio_redir from runtime.stdout_redirect import stdio_redir
class TcpStdOut: class TcpStdOut:

View File

@@ -5,7 +5,7 @@ from pathlib import Path
import importlib import importlib
import traceback import traceback
from lib.tum_except import ETUMRuntimeError, ETUMSyntaxError from runtime.tum_except import ETUMRuntimeError, ETUMSyntaxError
from py_func import tm from py_func import tm

View File

@@ -7,8 +7,8 @@ import math
import json import json
import traceback import traceback
from lib.jrpc import JsonRpcSrv from runtime.jrpc import JsonRpcSrv
from lib.tum_except import ETUMRuntimeError, print_exception from runtime.tum_except import ETUMRuntimeError, print_exception
import py_func.tm as tm import py_func.tm as tm
from py_func.func_call import func_exec from py_func.func_call import func_exec

View File

@@ -2,8 +2,8 @@
import json import json
import sys import sys
from py_func.handle import FuncHandler from py_func.handle import FuncHandler
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
from lib.api import SUPPORTED_API from runtime.api import SUPPORTED_API
thismodule = sys.modules[__name__] thismodule = sys.modules[__name__]
_func_call_thread = None _func_call_thread = None

View File

View File

@@ -6,11 +6,11 @@ import itertools
from time import sleep from time import sleep
from typing import Callable, Any from typing import Callable, Any
try: try:
import libs.testium as tm import api.testium as tm
except: except:
import py_func.tm as tm import py_func.tm as tm
from lib.tum_except import ETUMRuntimeError from runtime.tum_except import ETUMRuntimeError
"""Lightweight JSON-RPC 2.0 helpers over TCP sockets. """Lightweight JSON-RPC 2.0 helpers over TCP sockets.

View File

@@ -1,7 +1,7 @@
import sys import sys
import threading import threading
from threading import (Thread, Event) from threading import (Thread, Event)
from lib.string_queue import StringQueue from runtime.string_queue import StringQueue
from time import (sleep) from time import (sleep)

View File

@@ -1,4 +1,4 @@
import libs.testium as tm import api.testium as tm
def RetreiveData(console_name): def RetreiveData(console_name):
print("--------------- retrieving data ---------------") print("--------------- retrieving data ---------------")

View File

@@ -1,4 +1,4 @@
import libs.testium as tm import api.testium as tm
def RetreiveData(console_name): def RetreiveData(console_name):
print("--------------- retrieving data ---------------") print("--------------- retrieving data ---------------")

View File

@@ -1,4 +1,4 @@
import libs.testium as libtm import api.testium as libtm
def check_os(expected_os): def check_os(expected_os):

View File

@@ -0,0 +1,65 @@
"""Static check that py_func/ and lua_func/ subprocess code does not depend
on testium internals. The contract is:
py_func/*.py may import: py_func.*, runtime.*, plus stdlib/3rd-party
lua_func/*.lua may require: lua_func/<own files>, plus lua stdlib
Forbidden top-level modules: interpreter, main_win, api, testium.
"""
import ast
import os
import re
FORBIDDEN_PY = {"interpreter", "main_win", "api", "testium"}
FORBIDDEN_LUA = {"interpreter", "main_win", "api", "testium"}
def _collect_py_imports(path):
with open(path, "r", encoding="utf-8") as f:
tree = ast.parse(f.read(), filename=path)
out = set()
for node in ast.walk(tree):
if isinstance(node, ast.Import):
for n in node.names:
out.add(n.name.split(".")[0])
elif isinstance(node, ast.ImportFrom):
if node.level == 0 and node.module:
out.add(node.module.split(".")[0])
return out
def _collect_lua_requires(path):
with open(path, "r", encoding="utf-8") as f:
text = f.read()
return {m.split(".")[0] for m in re.findall(r'require\s*\(?\s*["\']([^"\']+)["\']', text)}
def check_isolation(testium_dir):
failures = []
py_dir = os.path.join(testium_dir, "py_func")
for root, _, files in os.walk(py_dir):
for f in files:
if not f.endswith(".py"):
continue
p = os.path.join(root, f)
leaks = _collect_py_imports(p) & FORBIDDEN_PY
if leaks:
failures.append(f"py_func/{os.path.relpath(p, py_dir)} leaks: {sorted(leaks)}")
lua_dir = os.path.join(testium_dir, "lua_func")
for root, _, files in os.walk(lua_dir):
for f in files:
if not f.endswith(".lua"):
continue
p = os.path.join(root, f)
leaks = _collect_lua_requires(p) & FORBIDDEN_LUA
if leaks:
failures.append(f"lua_func/{os.path.relpath(p, lua_dir)} leaks: {sorted(leaks)}")
if failures:
for line in failures:
print(f" - {line}")
return False
return True

View File

@@ -0,0 +1 @@
no_param: Null

View File

@@ -0,0 +1,8 @@
- py_func:
name: py_func/lua_func do not depend on testium internals
file: $(test_path)$(psep)check_isolation.py
func_name: check_isolation
key: $(test)_PASS
param:
- $(testium_path)
expected_result: True

View File

@@ -1,5 +1,5 @@
import time import time
import libs.testium as tm import api.testium as tm
def sleep_func(duration): def sleep_func(duration):