Skip to content

Commit f5f6c44

Browse files
Merge branch 'master' into develop
# Conflicts: # .vscode/tasks.json # pyproject.toml
2 parents 4869ddd + d4c9737 commit f5f6c44

46 files changed

Lines changed: 1642 additions & 605 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/copilot-instructions.md

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
### Technology Stack
88

99
- **Python**: 3.9+
10-
- **Core**: NumPy (≥1.19), QtPy (≥1.9)
10+
- **Core**: NumPy (≥1.21), QtPy (≥1.9)
1111
- **GUI**: Qt via QtPy (PyQt5/PyQt6/PySide6)
1212
- **Testing**: pytest
1313
- **Linting**: Ruff, Pylint
@@ -33,28 +33,18 @@ qwt/
3333

3434
### Running Commands
3535

36-
Use batch scripts in `scripts/`:
36+
**Always use `scripts/run_with_env.py`** to load `.env` before running Python commands:
3737

3838
```powershell
39-
scripts\run_pytest.bat # Run tests
40-
scripts\run_ruff.bat # Format and lint
41-
scripts\run_pylint.bat # Pylint checks
42-
scripts\run_coverage.bat # Coverage report
43-
scripts\take_screenshots.bat # Generate doc images
44-
```
45-
46-
Or directly:
47-
48-
```powershell
49-
python -m pytest qwt --ff
50-
python -m ruff format
51-
python -m ruff check --fix
39+
python scripts/run_with_env.py python -m pytest --ff
40+
python scripts/run_with_env.py python -m ruff format
41+
python scripts/run_with_env.py python -m ruff check --fix
5242
```
5343

5444
### Running Test Launcher
5545

5646
```powershell
57-
PythonQwt # GUI test launcher
47+
PythonQwt-tests # GUI test launcher
5848
PythonQwt-tests --mode unattended # Headless tests
5949
```
6050

@@ -107,8 +97,12 @@ curve = qwt.QwtPlotCurve.make(
10797
linewidth=2, # Line width
10898
linestyle=Qt.DashLine, # Qt line style
10999
antialiased=True, # Anti-aliasing
110-
marker=qwt.QwtSymbol.Ellipse, # Marker symbol
111-
markersize=8, # Marker size
100+
symbol=qwt.QwtSymbol( # Marker symbol (QwtSymbol instance)
101+
qwt.QwtSymbol.Ellipse,
102+
QBrush(Qt.yellow),
103+
QPen(Qt.red, 2),
104+
QSize(8, 8),
105+
),
112106
)
113107
```
114108

@@ -122,9 +116,12 @@ curve = qwt.QwtPlotCurve.make(
122116
| `QwtPlotGrid` | Grid lines |
123117
| `QwtLegend` | Legend widget |
124118
| `QwtSymbol` | Marker symbols |
125-
| `QwtScaleEngine` | Scale calculations |
119+
| `QwtLinearScaleEngine` | Linear scale calculations |
120+
| `QwtLogScaleEngine` | Logarithmic scale calculations |
126121
| `QwtScaleMap` | Scale transformations |
127122
| `QwtText` | Rich text labels |
123+
| `QwtDateTimeScaleDraw` | Datetime axis tick labels |
124+
| `QwtDateTimeScaleEngine` | Datetime scale divisions |
128125

129126
### Scale Configuration
130127

@@ -186,7 +183,7 @@ def setData(self, x, y):
186183
|------|---------|
187184
| `qwt/plot.py` | QwtPlot implementation |
188185
| `qwt/plot_curve.py` | QwtPlotCurve with `make()` factory |
189-
| `qwt/scale_engine.py` | Linear/log scale engines |
186+
| `qwt/scale_engine.py` | Linear/log/datetime scale engines |
190187
| `qwt/scale_map.py` | Scale transformations |
191188
| `qwt/symbol.py` | QwtSymbol definitions |
192189
| `qwt/tests/__init__.py` | Test launcher |

.github/workflows/build_deploy.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,17 @@ permissions:
88
contents: read
99

1010
jobs:
11+
test-pyqt5:
12+
uses: ./.github/workflows/test-PyQt5.yml
13+
14+
test-pyqt6:
15+
uses: ./.github/workflows/test-PyQt6.yml
16+
17+
test-pyside6:
18+
uses: ./.github/workflows/test-PySide6.yml
19+
1120
deploy:
21+
needs: [test-pyqt5, test-pyqt6, test-pyside6]
1222

1323
runs-on: ubuntu-latest
1424

.github/workflows/test-PyQt5.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010
branches: [ "master" ]
1111
pull_request:
1212
branches: [ "master" ]
13+
workflow_call:
1314

1415
jobs:
1516
build:

.github/workflows/test-PyQt6.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010
branches: [ "master" ]
1111
pull_request:
1212
branches: [ "master" ]
13+
workflow_call:
1314

1415
jobs:
1516
build:

.github/workflows/test-PySide6.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ on:
1010
branches: [ "master" ]
1111
pull_request:
1212
branches: [ "master" ]
13+
workflow_call:
1314

1415
jobs:
1516
build:

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,3 +85,12 @@ docs/_build/
8585

8686
# PyBuilder
8787
target/
88+
89+
# Local benchmark venvs (issue #93)
90+
.venvs/
91+
92+
# Performance investigation artifacts (see scripts/README.md)
93+
shots/
94+
profile.out
95+
*.prof_stats
96+
*.lprof

.vscode/settings.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
},
1717
"files.trimFinalNewlines": true,
1818
"files.trimTrailingWhitespace": true,
19-
"python.defaultInterpreterPath": "${env:PPSTACK_PYTHONEXE}",
2019
"editor.formatOnSave": true,
2120
"python.analysis.autoFormatStrings": true,
2221
"python.testing.unittestEnabled": false,

.vscode/tasks.json

Lines changed: 95 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,18 @@
4949
"statusbar": {
5050
"hide": true,
5151
},
52+
"cwd": "${workspaceFolder}",
53+
"statusbar": {
54+
"hide": true,
55+
},
5256
},
5357
"group": {
5458
"kind": "build",
5559
"isDefault": true,
60+
"isDefault": true,
5661
},
5762
"presentation": {
63+
"clear": true,
5864
"clear": true,
5965
"echo": true,
6066
"focus": false,
@@ -81,6 +87,7 @@
8187
"focus": false,
8288
"panel": "dedicated",
8389
"reveal": "always",
90+
"reveal": "always",
8491
"showReuseMessage": true,
8592
},
8693
"type": "shell",
@@ -133,12 +140,14 @@
133140
"group": {
134141
"kind": "build",
135142
"isDefault": true,
143+
"isDefault": true,
136144
},
137145
"presentation": {
146+
"clear": true,
138147
"echo": true,
139-
"reveal": "always",
140148
"focus": false,
141149
"panel": "dedicated",
150+
"reveal": "always",
142151
"showReuseMessage": true,
143152
"clear": true,
144153
},
@@ -220,37 +229,42 @@
220229
"isDefault": true,
221230
},
222231
"presentation": {
232+
"clear": true,
223233
"echo": true,
224-
"reveal": "always",
225234
"focus": false,
226235
"panel": "dedicated",
236+
"reveal": "always",
227237
"showReuseMessage": true,
228238
"clear": true,
229239
},
230240
},
231241
{
232-
"label": "Clean Up",
233-
"type": "shell",
234-
"command": "cmd",
242+
"label": "🔦 Pylint",
243+
"command": "${command:python.interpreterPath}",
235244
"args": [
236-
"/c",
237-
"clean_up.bat"
245+
"scripts/run_with_env.py",
246+
"${command:python.interpreterPath}",
247+
"-m",
248+
"pylint",
249+
"qwt",
250+
"--disable=fixme,C,R,W",
238251
],
239252
"options": {
240-
"cwd": "scripts"
253+
"cwd": "${workspaceFolder}",
241254
},
242255
"group": {
243256
"kind": "build",
244-
"isDefault": true
257+
"isDefault": true,
245258
},
246259
"presentation": {
260+
"clear": true,
247261
"echo": true,
248-
"reveal": "always",
249262
"focus": false,
250-
"panel": "shared",
263+
"panel": "dedicated",
264+
"reveal": "always",
251265
"showReuseMessage": true,
252-
"clear": false
253-
}
266+
},
267+
"type": "shell",
254268
},
255269
{
256270
"label": "Build documentation",
@@ -265,27 +279,61 @@
265279
"command": "${command:python.interpreterPath} scripts/run_with_env.py ${command:python.interpreterPath} -m sphinx -b html doc build/doc && open build/doc/index.html"
266280
},
267281
"options": {
282+
"cwd": "${workspaceFolder}",
268283
"cwd": "${workspaceFolder}",
269284
"env": {
270285
"UNATTENDED": "1"
271286
}
272287
},
273288
"problemMatcher": [],
289+
},
290+
{
291+
"label": "📷 Take screenshots",
292+
"dependsOrder": "sequence",
293+
"dependsOn": [
294+
"📷 Take test screenshots",
295+
"📷 Take doc screenshots",
296+
"📷 Take symbol screenshots",
297+
],
274298
"group": {
275299
"kind": "build",
276-
"isDefault": true
300+
"isDefault": true,
301+
},
302+
"presentation": {
303+
"clear": true,
304+
"panel": "dedicated",
305+
},
306+
},
307+
{
308+
"label": "🧹 Clean Up",
309+
"type": "shell",
310+
"windows": {
311+
"command": "Get-ChildItem -Recurse -Directory -Filter __pycache__ | Remove-Item -Recurse -Force; Remove-Item -Recurse -Force -ErrorAction SilentlyContinue build, dist, PythonQwt.egg-info, MANIFEST, htmlcov, .coverage, coverage.xml, sitecustomize.py; Remove-Item -Force -ErrorAction SilentlyContinue .coverage.*",
312+
},
313+
"linux": {
314+
"command": "find . -type d -name __pycache__ -exec rm -rf {} + ; rm -rf build dist PythonQwt.egg-info MANIFEST htmlcov .coverage coverage.xml sitecustomize.py .coverage.*",
315+
},
316+
"osx": {
317+
"command": "find . -type d -name __pycache__ -exec rm -rf {} + ; rm -rf build dist PythonQwt.egg-info MANIFEST htmlcov .coverage coverage.xml sitecustomize.py .coverage.*",
318+
},
319+
"options": {
320+
"cwd": "${workspaceFolder}",
321+
},
322+
"group": {
323+
"kind": "build",
324+
"isDefault": true,
277325
},
278326
"presentation": {
279327
"echo": true,
280328
"reveal": "always",
281329
"focus": false,
282330
"panel": "shared",
283331
"showReuseMessage": true,
284-
"clear": true
285-
}
332+
"clear": false,
333+
},
286334
},
287335
{
288-
"label": "Build Python packages",
336+
"label": "📚 Build documentation",
289337
"type": "shell",
290338
"windows": {
291339
"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 }"
@@ -305,25 +353,29 @@
305353
"problemMatcher": [],
306354
"group": {
307355
"kind": "build",
308-
"isDefault": true
356+
"isDefault": true,
309357
},
310358
"presentation": {
359+
"clear": true,
311360
"echo": true,
312-
"reveal": "always",
313361
"focus": false,
314-
"panel": "shared",
362+
"panel": "dedicated",
363+
"reveal": "always",
315364
"showReuseMessage": true,
316-
"clear": true
317365
},
318-
"dependsOrder": "sequence",
319-
"dependsOn": [
320-
"Clean Up",
321-
]
322366
},
323367
{
324-
"label": "Run test venv",
368+
"label": "🌐 Open HTML doc",
325369
"type": "shell",
326-
"command": "cmd",
370+
"windows": {
371+
"command": "start build/doc/index.html",
372+
},
373+
"linux": {
374+
"command": "xdg-open build/doc/index.html",
375+
},
376+
"osx": {
377+
"command": "open build/doc/index.html",
378+
},
327379
"options": {
328380
"cwd": "scripts",
329381
"env": {
@@ -332,22 +384,27 @@
332384
}
333385
},
334386
"args": [
335-
"/c",
336-
"run_test_venv.bat"
387+
"scripts/run_with_env.py",
388+
"${command:python.interpreterPath}",
389+
"-m",
390+
"build",
337391
],
338-
"problemMatcher": [],
392+
"options": {
393+
"cwd": "${workspaceFolder}",
394+
},
339395
"group": {
340396
"kind": "build",
341-
"isDefault": true
397+
"isDefault": false,
342398
},
343399
"presentation": {
344-
"echo": true,
345-
"reveal": "always",
346-
"focus": false,
347-
"panel": "shared",
348-
"showReuseMessage": true,
349-
"clear": true
400+
"clear": true,
401+
"panel": "dedicated",
350402
},
403+
"problemMatcher": [],
404+
"dependsOrder": "sequence",
405+
"dependsOn": [
406+
"🧹 Clean Up",
407+
],
351408
},
352-
]
409+
],
353410
}

0 commit comments

Comments
 (0)