openprocess 0.7.1__tar.gz → 0.7.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {openprocess-0.7.1/openprocess.egg-info → openprocess-0.7.2}/PKG-INFO +1 -1
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/__init__.py +1 -1
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/flow/page.py +49 -4
- {openprocess-0.7.1 → openprocess-0.7.2/openprocess.egg-info}/PKG-INFO +1 -1
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_flow_gui.py +37 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/LICENSE +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/README.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/cpnpy/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/analysis/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/analysis/state_space.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/analysis/state_space_process.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/cli.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/1 Petri nets/Exercise 1.1 Order handling/answer.pnml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/1 Petri nets/Exercise 1.1 Order handling/question.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/answer.pnml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/net.pnml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/2 Soundness/Exercise 2.1 Spot the flaw/question.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/3 Discovery/Exercise 3.1 The alpha-algorithm/log.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/3 Discovery/Exercise 3.1 The alpha-algorithm/question.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/4 Regions/Exercise 4.1 Regions of a transition system/question.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/4 Regions/Exercise 4.1 Regions of a transition system/ts.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/5 Markings/Exercise 5.1 Markings and matrices/net.pnml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/5 Markings/Exercise 5.1 Markings and matrices/question.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/6 Inductive Miner/Exercise 6.1 Cuts and trees/log.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/6 Inductive Miner/Exercise 6.1 Cuts and trees/question.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/log.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m1.pnml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m2.pnml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/m3.pnml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/net.pnml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/7 Conformance/Exercise 7.1 Replay, alignments and workflows/question.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/exercises/pack.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/box.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/check.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/compare.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/cpn.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/discover.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/filter.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/input.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/output.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/predict.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/science.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/boxes/sweeps.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/convert.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/datasets.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/explain.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/library.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/record.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/runner.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/sweep.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/types.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/flow/workflow.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/app.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/arc_editing.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/canvas.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/flow/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/flow/canvas.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/flow/templates.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/flow/viewers.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/items.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/learn/answer_boxes.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/learn/concealment.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/learn/mode.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/panning.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/resources/openprocess-icon.png +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/__main__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/app.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/charts.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/compare_page.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/cpn_page.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/definition_view.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/derivation_view.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/documents.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/dotted_chart.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/file_dialogs.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/filter_dialog.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/graph_builders.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/graph_view.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/instances.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/log_editor.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/log_page.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/markdown_view.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/mathtext.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/ml_highlighter.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/model_page.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/net_comparison.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/notes_overlay.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/petri_page.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/regions_view.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/sidebar.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/style.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/tool_icons.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/updates.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/widgets.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/workers.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/studio/workspace.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/theme.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/gui/tidy.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/io/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/io/cpn_reader.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/io/cpn_writer.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/answers.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/checks.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/computed.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/context.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/exam.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/exercise-packs.md +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/importer.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/notation.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/pack.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/learn/sheet.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/analysis.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/columns.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/compare_nets.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/conformance/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/conformance/alignments.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/conformance/quality.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/conformance/token_replay.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/csv_import.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/definitions.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/dfg.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/discovery/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/discovery/alpha.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/discovery/heuristics.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/discovery/inductive.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/discovery/state_regions.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/filtering.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/footprint.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/invariants.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/layout.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/log.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/petrinet.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/playout.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/pm4py_bridge.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/pnml.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/processtree.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/regions.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/stats.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/structure.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/transition_system.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/mining/xes.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/ast_nodes.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/builtins.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/colorsets.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/errors.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/evaluator.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/lexer.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/multiset.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/parser.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/ml/values.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/model/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/model/declarations.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/model/examples.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/model/net.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/model/plain.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/references.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/sim/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/sim/binding.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/sim/export.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/sim/simulator.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/teaching/__init__.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/teaching/answers.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/teaching/checks.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/teaching/pack.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess/teaching/sheet.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess.egg-info/SOURCES.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess.egg-info/dependency_links.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess.egg-info/entry_points.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess.egg-info/requires.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/openprocess.egg-info/top_level.txt +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/pyproject.toml +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/setup.cfg +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_arc_editing.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_colorsets.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_columns.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_cpn_course_model.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_definitions.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_exercises_gui.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_flow.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_hierarchy.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_io.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_learn.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_learn_gui.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_log_editing.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_mining.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_ml.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_multiset.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_regions.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_rename.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_simulation.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_state_space.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_studio_gui.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_teaching.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_tidy.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_updates.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_wf_structure.py +0 -0
- {openprocess-0.7.1 → openprocess-0.7.2}/tests/test_workspace.py +0 -0
|
@@ -48,7 +48,7 @@ from .sim.simulator import Simulator
|
|
|
48
48
|
#: The one place the version number is written (pyproject.toml, the update
|
|
49
49
|
#: check and packaging/build.py read it from here). A release is tagged
|
|
50
50
|
#: "v" + this, e.g. v0.2.0.
|
|
51
|
-
__version__ = "0.7.
|
|
51
|
+
__version__ = "0.7.2"
|
|
52
52
|
|
|
53
53
|
__all__ = [
|
|
54
54
|
"Arc", "BindingElement", "CPNet", "Marking", "Multiset", "Page", "Place",
|
|
@@ -671,10 +671,22 @@ class WorkflowPage(QWidget):
|
|
|
671
671
|
if result is None:
|
|
672
672
|
return label("Runs first; the result shows here.", "muted", wrap=True)
|
|
673
673
|
if result.status == FAILED:
|
|
674
|
+
# The box's own words first (a missing file, a dataset to fetch
|
|
675
|
+
# by hand, a setting out of range), with any address or folder
|
|
676
|
+
# in them clickable; the traceback is for whoever fixes the box.
|
|
677
|
+
kind, text = _error_message(result.error)
|
|
678
|
+
message = label(_linkified(text), "failedMessage", wrap=True, selectable=True)
|
|
679
|
+
message.setTextFormat(Qt.RichText)
|
|
680
|
+
message.setOpenExternalLinks(True)
|
|
681
|
+
parts = [label("WHAT WENT WRONG", "sectionLabel"), message]
|
|
682
|
+
if kind:
|
|
683
|
+
parts.append(label(kind, "muted"))
|
|
684
|
+
if result.traceback:
|
|
685
|
+
parts += [label("DETAILS", "sectionLabel"), _error_box(result.traceback)]
|
|
686
|
+
parts.append(label("The rest of the workflow keeps working. Fix the setting or the file, and "
|
|
687
|
+
"it runs again on its own.", "muted", wrap=True))
|
|
674
688
|
host = QWidget()
|
|
675
|
-
host.setLayout(vbox(
|
|
676
|
-
label("The rest of the workflow keeps working. Fix the setting or the file, and "
|
|
677
|
-
"it runs again on its own.", "muted", wrap=True)))
|
|
689
|
+
host.setLayout(vbox(*parts))
|
|
678
690
|
return host
|
|
679
691
|
if result.status == BLOCKED:
|
|
680
692
|
host = QWidget()
|
|
@@ -963,10 +975,43 @@ def _delete_layout(layout) -> None:
|
|
|
963
975
|
_delete_layout(item.layout())
|
|
964
976
|
|
|
965
977
|
|
|
978
|
+
def _error_message(error: str) -> tuple[str, str]:
|
|
979
|
+
"""``"DatasetMissing: Sepsis cases is not in the cache…"`` → the kind of error
|
|
980
|
+
(shown small) and what it says; an error without a message keeps its kind
|
|
981
|
+
as the message."""
|
|
982
|
+
error = (error or "The box failed without saying why.").strip()
|
|
983
|
+
kind, separator, text = error.partition(": ")
|
|
984
|
+
if separator and text.strip() and " " not in kind:
|
|
985
|
+
return kind.rsplit(".", 1)[-1], text.strip() # the class, not its module path
|
|
986
|
+
return "", error
|
|
987
|
+
|
|
988
|
+
|
|
989
|
+
def _linkified(text: str) -> str:
|
|
990
|
+
"""The text as rich text, with web addresses and folder paths as links."""
|
|
991
|
+
from html import escape
|
|
992
|
+
from urllib.parse import quote
|
|
993
|
+
|
|
994
|
+
def link(match) -> str:
|
|
995
|
+
address = match.group(0)
|
|
996
|
+
trailing = ""
|
|
997
|
+
while address and address[-1] in ".,;:)”\"'":
|
|
998
|
+
trailing = address[-1] + trailing
|
|
999
|
+
address = address[:-1]
|
|
1000
|
+
shown = escape(address)
|
|
1001
|
+
if address.startswith("http"):
|
|
1002
|
+
return f'<a href="{escape(address)}">{shown}</a>{escape(trailing)}'
|
|
1003
|
+
folder = Path(address)
|
|
1004
|
+
target = folder if folder.is_dir() else folder.parent
|
|
1005
|
+
if target.is_dir():
|
|
1006
|
+
return f'<a href="file://{quote(str(target))}">{shown}</a>{escape(trailing)}'
|
|
1007
|
+
return shown + escape(trailing)
|
|
1008
|
+
return re.sub(r"https?://\S+|(?<![\w/])(?:/|[A-Za-z]:\\)[^\s“”\"']+", link, escape(text)).replace("\n", "<br>")
|
|
1009
|
+
|
|
1010
|
+
|
|
966
1011
|
def _error_box(text: str) -> QPlainTextEdit:
|
|
967
1012
|
box = QPlainTextEdit(text)
|
|
968
1013
|
box.setReadOnly(True)
|
|
969
1014
|
box.setFont(theme.mono_font(10))
|
|
970
|
-
box.setMaximumHeight(
|
|
1015
|
+
box.setMaximumHeight(160)
|
|
971
1016
|
box.setStyleSheet(f"color: {style.STATUS['critical']};")
|
|
972
1017
|
return box
|
|
@@ -325,3 +325,40 @@ def test_quick_actions_make_workflows(app):
|
|
|
325
325
|
for document in window.documents:
|
|
326
326
|
document.dirty = False
|
|
327
327
|
window.close()
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def test_a_failed_box_says_what_went_wrong_in_its_own_words(app, tmp_path, monkeypatch):
|
|
331
|
+
"""Open dataset without the file in the cache: the message and its links
|
|
332
|
+
come first, the traceback under Details."""
|
|
333
|
+
from PySide6.QtWidgets import QLabel, QPlainTextEdit
|
|
334
|
+
|
|
335
|
+
from openprocess.flow import datasets
|
|
336
|
+
from openprocess.gui.flow.page import _error_message, _linkified
|
|
337
|
+
|
|
338
|
+
from PySide6.QtCore import QPointF
|
|
339
|
+
|
|
340
|
+
from openprocess.gui.studio.app import StudioWindow
|
|
341
|
+
|
|
342
|
+
monkeypatch.setattr(datasets, "cache_dir", lambda: tmp_path)
|
|
343
|
+
window = StudioWindow()
|
|
344
|
+
window.resize(1400, 900)
|
|
345
|
+
window.show()
|
|
346
|
+
window.action_new_workflow() # empty
|
|
347
|
+
page = window.current_page()
|
|
348
|
+
node = page.scene.add_node("open_dataset", QPointF(0, 300))
|
|
349
|
+
_wait_run(app, page)
|
|
350
|
+
result = page.run.result(node)
|
|
351
|
+
assert result.status == "failed" and "not in the cache" in result.error
|
|
352
|
+
page.select(node.id, 0)
|
|
353
|
+
_pump(app, 0.1)
|
|
354
|
+
labels = page.panel_host.findChildren(QLabel)
|
|
355
|
+
texts = [w.text() for w in labels]
|
|
356
|
+
assert any("not in the cache" in t and 'href="https://doi.org' in t for t in texts)
|
|
357
|
+
assert "DatasetMissing" in texts
|
|
358
|
+
assert "Traceback" in page.panel_host.findChild(QPlainTextEdit).toPlainText()
|
|
359
|
+
assert _error_message("ValueError: the noise must be 0..1") == ("ValueError", "the noise must be 0..1")
|
|
360
|
+
assert _error_message("Not a box error") == ("", "Not a box error")
|
|
361
|
+
assert _linkified(f"put it in {tmp_path}.") == f'put it in <a href="file://{tmp_path}">{tmp_path}</a>.'
|
|
362
|
+
assert _linkified("see https://doi.org/10.1/x, then") == 'see <a href="https://doi.org/10.1/x">https://doi.org/10.1/x</a>, then'
|
|
363
|
+
page.document.dirty = False # closing would otherwise ask to save
|
|
364
|
+
window.close()
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|