diff --git a/.env.template b/.env.template index 60f01f7..b06759e 100644 --- a/.env.template +++ b/.env.template @@ -1 +1,10 @@ -PYTHONPATH=. \ No newline at end of file +# Python interpreter (explicit path, e.g. WinPython). Auto-detected if empty. +PYTHON= +# WinPython base directory (legacy, prefer PYTHON instead) +# WINPYDIRBASE= +# Virtual environment directory (e.g. .venv39). Auto-discovered if empty. +VENV_DIR= +# Python path for development (sibling packages) +PYTHONPATH=. +# Locale (e.g. fr) +LANG= \ No newline at end of file diff --git a/.github/workflows/test-PyQt5.yml b/.github/workflows/test-PyQt5.yml index 18b4cb6..029acbb 100644 --- a/.github/workflows/test-PyQt5.yml +++ b/.github/workflows/test-PyQt5.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.11", "3.13"] + python-version: ["3.9", "3.11", "3.13", "3.14"] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-PyQt6.yml b/.github/workflows/test-PyQt6.yml index 4bd9efa..465cc70 100644 --- a/.github/workflows/test-PyQt6.yml +++ b/.github/workflows/test-PyQt6.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.11", "3.13"] + python-version: ["3.9", "3.11", "3.13", "3.14"] steps: - uses: actions/checkout@v4 diff --git a/.github/workflows/test-PySide6.yml b/.github/workflows/test-PySide6.yml index 965509f..d466d9d 100644 --- a/.github/workflows/test-PySide6.yml +++ b/.github/workflows/test-PySide6.yml @@ -22,7 +22,7 @@ jobs: strategy: fail-fast: false matrix: - python-version: ["3.9", "3.11", "3.13"] + python-version: ["3.9", "3.11", "3.13", "3.14"] steps: - uses: actions/checkout@v4 diff --git a/.gitignore b/.gitignore index c19ea1c..7e8ec8c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,12 @@ doctmp/ # Visual Studio Code .env +.venv* +.*venv* + +#AI instructions +*.ai +*.ai* # Created by https://www.gitignore.io/api/python @@ -37,6 +43,16 @@ var/ .installed.cfg *.egg +# Environments +.env* +.envrc +.venv* +env*/ +venv*/ +ENV/ +env.bak/ +venv.bak/ + # PyInstaller # Usually these files are written by a python script from a template # before PyInstaller builds the exe, so as to inject date/other infos into it. diff --git a/.vscode/tasks.json b/.vscode/tasks.json index a67d8ef..72eff1a 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -49,12 +49,18 @@ "statusbar": { "hide": true, }, + "cwd": "${workspaceFolder}", + "statusbar": { + "hide": true, + }, }, "group": { "kind": "build", "isDefault": true, + "isDefault": true, }, "presentation": { + "clear": true, "clear": true, "echo": true, "focus": false, @@ -81,6 +87,7 @@ "focus": false, "panel": "dedicated", "reveal": "always", + "reveal": "always", "showReuseMessage": true, }, "type": "shell", @@ -94,6 +101,7 @@ "-m", "pylint", "qwt", + // "--disable=R0801,C0103,C0114,C0115,C0116,W0612,W0613", "--disable=fixme,C,R,W", ], "options": { @@ -132,12 +140,14 @@ "group": { "kind": "build", "isDefault": true, + "isDefault": true, }, "presentation": { + "clear": true, "echo": true, - "reveal": "always", "focus": false, "panel": "dedicated", + "reveal": "always", "showReuseMessage": true, "clear": true, }, @@ -160,7 +170,7 @@ "options": { "cwd": "${workspaceFolder}", "env": { - "COVERAGE_PROCESS_START": "${workspaceFolder}/.coveragerc", + "UNATTENDED": "1", }, "statusbar": { "hide": true, @@ -189,9 +199,6 @@ }, "options": { "cwd": "${workspaceFolder}", - "env": { - "COVERAGE_PROCESS_START": "${workspaceFolder}/.coveragerc", - }, }, "presentation": { "panel": "dedicated", @@ -203,56 +210,80 @@ ], }, { - "label": "📷 Take test screenshots", + "label": "Take screenshots", "type": "shell", "command": "${command:python.interpreterPath}", "args": [ "scripts/run_with_env.py", "${command:python.interpreterPath}", - "qwt/tests/__init__.py", - "--mode", - "screenshots", + "scripts/take_screenshots.py", ], "options": { "cwd": "${workspaceFolder}", + "env": { + "UNATTENDED": "1", + }, + }, + "group": { + "kind": "build", + "isDefault": true, }, "presentation": { "clear": true, + "echo": true, + "focus": false, "panel": "dedicated", + "reveal": "always", + "showReuseMessage": true, + "clear": true, }, - "problemMatcher": [], }, { - "label": "📷 Take doc screenshots", - "type": "shell", + "label": "🔦 Pylint", "command": "${command:python.interpreterPath}", "args": [ "scripts/run_with_env.py", "${command:python.interpreterPath}", - "doc/plot_example.py", + "-m", + "pylint", + "qwt", + "--disable=fixme,C,R,W", ], "options": { "cwd": "${workspaceFolder}", }, + "group": { + "kind": "build", + "isDefault": true, + }, "presentation": { + "clear": true, + "echo": true, + "focus": false, "panel": "dedicated", + "reveal": "always", + "showReuseMessage": true, }, - "problemMatcher": [], + "type": "shell", }, { - "label": "📷 Take symbol screenshots", + "label": "Build documentation", "type": "shell", - "command": "${command:python.interpreterPath}", - "args": [ - "scripts/run_with_env.py", - "${command:python.interpreterPath}", - "doc/symbol_path_example.py", - ], + "windows": { + "command": "${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m sphinx -b html doc build/doc; if ($?) { start build\\doc\\index.html }" + }, + "linux": { + "command": "${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m sphinx -b html doc build/doc && xdg-open build/doc/index.html" + }, + "osx": { + "command": "${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m sphinx -b html doc build/doc && open build/doc/index.html" + }, "options": { "cwd": "${workspaceFolder}", - }, - "presentation": { - "panel": "dedicated", + "cwd": "${workspaceFolder}", + "env": { + "UNATTENDED": "1" + } }, "problemMatcher": [], }, @@ -304,21 +335,22 @@ { "label": "📚 Build documentation", "type": "shell", - "command": "${command:python.interpreterPath}", - "args": [ - "scripts/run_with_env.py", - "${command:python.interpreterPath}", - "-m", - "sphinx", - "build", - "doc", - "${workspaceFolder}/build/doc", - "-b", - "html", - ], + "windows": { + "command": "if (Test-Path MANIFEST) { Remove-Item MANIFEST }; ${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m build; if (Test-Path PythonQwt.egg-info) { Remove-Item -Recurse -Force PythonQwt.egg-info }" + }, + "linux": { + "command": "rm -f MANIFEST && ${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m build && rm -rf PythonQwt.egg-info" + }, + "osx": { + "command": "rm -f MANIFEST && ${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m build && rm -rf PythonQwt.egg-info" + }, "options": { "cwd": "${workspaceFolder}", + "env": { + "UNATTENDED": "1" + } }, + "problemMatcher": [], "group": { "kind": "build", "isDefault": true, @@ -345,14 +377,12 @@ "command": "open build/doc/index.html", }, "options": { - "cwd": "${workspaceFolder}", + "cwd": "scripts", + "env": { + "PYTHON": "${command:python.interpreterPath}", + "UNATTENDED": "1" + } }, - "problemMatcher": [], - }, - { - "label": "📦 Build package", - "type": "shell", - "command": "${command:python.interpreterPath}", "args": [ "scripts/run_with_env.py", "${command:python.interpreterPath}", diff --git a/pyproject.toml b/pyproject.toml index c972b99..891f636 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,7 +59,7 @@ version = { attr = "qwt.__version__" } addopts = "qwt" [tool.ruff] -exclude = [".git", ".vscode", "build", "dist"] +exclude = [".git", ".vscode", "build", "dist","venv*",".venv*"] line-length = 88 # Same as Black. indent-width = 4 # Same as Black. target-version = "py39" # Assume Python 3.9. diff --git a/scripts/take_screenshots.py b/scripts/take_screenshots.py new file mode 100644 index 0000000..8f3d159 --- /dev/null +++ b/scripts/take_screenshots.py @@ -0,0 +1,24 @@ +# Copyright (c) 2026 PlotPyStack developers +# Licensed under the terms of the MIT License +# (see LICENSE file for more details) + +"""Screenshots update script.""" + +import subprocess +import sys + + +def main(): + """Run all screenshot-generating scripts.""" + scripts = [ + [sys.executable, "qwt/tests/__init__.py", "--mode", "screenshots"], + [sys.executable, "doc/plot_example.py"], + [sys.executable, "doc/symbol_path_example.py"], + ] + for cmd in scripts: + print(f"Running: {' '.join(cmd)}") + subprocess.check_call(cmd) + + +if __name__ == "__main__": + main()