Skip to content

Conversation

@tychodub
Copy link
Contributor

Adds type hints to all RobotMBT source files, as far as possible without updating from Python 3.10 to newer versions. The Python 3.10 constraint means that "Self" types have not had type hints added.

Ignore the large amounts of commits, since those are an artifact of the rebasing process.
Should be merged with a squash, so the large amount of commits don't show up.

osingaatje and others added 30 commits September 30, 2025 14:08
* added type hints to modelspace.py, steparguments.py, substitutionmap.py, version.py and __init__.py, a little bit of suitedata.py and to tracestate.py. Reordered classes in tracestate.py for this purpose.

* added nearly all remaining type hints, including missing "Self" types from files typed in earlier commits. Not everything in suitereplacer.py is typed because of severe ambiguity issues

* reformatted according to PEP8 (using  in VSCode)

---------

Co-authored-by: tychodub <t.b.dubbeling@student.utwente.nl>
* Create python-app.yml, for Github actions

Create python-app.yml, runs utests when pushing/merging pull-request into main

* test run actual  python file

* use python latest version

* use python version 3.13

* fix comment

* actually return exit code that robot returns

---------

Co-authored-by: Douwe Osinga <douwe@oscom.nl>
* added ignore for VPP

* added initial VPP

* vpp

* modified gitignore

* added new diagram - extension plan

* added initial renders

* .vpp commit

* added improved event-based design

* changed design to accomodate different graph repr. better

* vpp
* Implement basic scenario graph architecture
(without actual visualisation)

* Also output graph if coverage could not be reached

* from visualiser.graph to networkx graph

* added optional dependencies for visualization feature

* rework scenariograph to use networkx

* Update python-app.yml to install optional dependencies

* moved documentation according to python

* remove static variables

---------

Co-authored-by: Thomas <t.s.kas@student.utwente.nl>
Co-authored-by: jonathan <148167.jw@gmail.com>
Co-authored-by: tychodub <t.b.dubbeling@student.utwente.nl>
Co-authored-by: Jonathan <61787386+JWillegers@users.noreply.github.com>
* Seperated ScenarioInfo, TraceInfo, and ScnearioGraph into seperate file according to architecture

* Don't run automated testing on main

* fixing imports
* commented Self typing annotations

* changed Github actions python-version to 3.10

* change from spring layout to planar layout

---------

Co-authored-by: jonathan <148167.jw@gmail.com>
* add initial readme adjustments for pipenv

* ignore pyenv pipfile

* updated README - windows specific stuff and overall improvement
* add bokeh as optional dependency

* remove dependency on scipy

* bokeh graph with arrows and a start on selfloops

* add labels to vertices

* restructure according to architecture

* fixed self-loops; fixed arrowheads not being at boundary of vertex

* embedded plot in html

* added extra documentation

* fixed edge_case where there is only 1 scenario

* consistently use "node" in the code

* remove draw_from_networkx and draw nodes in a for-loop

* moved width/height/edge styling/... to constants

* fixed zooming with tools

* adding future support for having labels at edges

* reorder imports, prepend private methods with underscore

* fix requested changes (code comments)

* test class traceInfo

---------

Co-authored-by: Douwe Osinga <douwe@oscom.nl>
* removed self.fixed from ScenarioGraph
added self.end_node in ScenarioGraph

* test cases for most methods in models.py (missing: set_ending_node and calculate_pos)

* added unit test for scenariograph.set_end_node()
* initial acceptance test PoC

* added traceInfo generator, adjusted some constructors to work with Robot testing, first working PoC of Atest

* found first bug with Acceptance Test

* fix unit tests

* refactored helper, removed unnecessary logging

* added return type for

* deleted useless testing file

* inlined suite setup

* reduced type of state to ModelSpace, fixed incorrect type hint

* added warning for future state implementations

* changed utest to reflect comments from PR pull #8 (acceptance testing) - TODO add model state Thomas/Tycho

* fixed constructor TraceInfo to require ModelSpace

* Revert accidental change

---------

Co-authored-by: jonathan <148167.jw@gmail.com>
Co-authored-by: Thomas <t.s.kas@student.utwente.nl>
* initial acceptance test PoC

* added traceInfo generator, adjusted some constructors to work with Robot testing, first working PoC of Atest

* refactored helper, removed unnecessary logging

* added edge representation acceptance test
* Refactor node rendering to use rectangles for scenarios

* Improve edge connection points and arrow positioning

* Redesign self-loops for rectangle nodes

* Fix self-loop arrow alignment and improve visual consistency

* Fix visualization issues according to reviwer's feedback

* magic fix from Jonathan

* Simplify self-loop logic and remove invalid edge cases

* redo part of Jonathan fix - makes ERROR:bokeh.core.validation.check:E-1001 (BAD_COLUMN_NAME) disappear

* remove duplicate code from edge calculation

---------

Co-authored-by: Diogo Silva <diogo.xuya@gmail.com>
* Update using final trace info internally

* Add StateInfo abstraction

* Implement StateGraph

* cleaned up StateInfo.__init__ a little

* Merge with main

* Fixed oopsie

* Implement abstract base class for graphs

* Implement per-suite graph choice

* Only generate graph if dependencies are installed

* Don't run our tests without dependencies

* Use empty string instead of None

* doodoo

* Merge and fix some issues

* Run formatter

* Fixed doc

* Implement requested changes

---------

Co-authored-by: tychodub <t.b.dubbeling@student.utwente.nl>
* Seperate network_visualiser from visualiser

* - renamed pos to graph_layout
- moved graph_layout from models to network_visualiser

* refactor file name to not contain underscore

* taking the graphs classes out of models.py

* split unit tests

* added test for scenariograph.set_final_trace

* add arguments to atests

* correct orientation for bfs
* implemented scenario-state (state after scenario has run variant) graph representation

* removed hardcoded starting node id by keeping track of starting node info

* added unit tests for scenariostategraph.py and some supporting code for the unit tests

* renamed unit tests because I forgot initially

* implemented suggestions by Jonathan (moved function into scenariostategraph as static method, de-indented 'if main' in test_visualise_scenariostategraph.py and moved is not None check outside for-loop)

* removed end_node from scenariostategraph.py

* moved is not None check outside of loop in scenariograph.py
* Implement Feature Path Highlighting in Scenario and State Graphs

* Implement State Graph Path highlighting with Stack

* Clean-up of unused features, move some logic, fix empty state entry bug

* Formatting

* Formatting

* Remove unused return value

* Merge with main, fix some bugs, alter ScenarioStateGraph to be in line with the rest and fix up some of its unit tests

* Add short explanation

---------

Co-authored-by: Thomas <t.s.kas@student.utwente.nl>
* Implement Feature Path Highlighting in Scenario and State Graphs

* Implement State Graph Path highlighting with Stack

* Clean-up of unused features, move some logic, fix empty state entry bug

* Formatting

* Formatting

* Remove unused return value

* Fix bug

* StateInfo unit tests

* StateGraph unit tests

* Merge with main, fix some bugs, alter ScenarioStateGraph to be in line with the rest and fix up some of its unit tests

* Add short explanation

* Test self-loops

* Minor tweaks

* Remove trailing newline

* Fix nuking of stack

* Better formatting of state info

* Spam __update_visualisation all over the place for refinement

* Fix nuking in scenario-state graph

* Warn instead of crashing

* Sanity check

* Do add edge with start node

* Expand tests

* Merge mistake

* Fix oopsie

* Move helper to StateInfo

* Protected helper

* Forgot this one

* added graph getter for resources

---------

Co-authored-by: Diogo Silva <diogo.xuya@gmail.com>
Co-authored-by: Douwe Osinga <douwe@oscom.nl>
* handle optional argument's default values

* optional arguments stay hidden when not mentioned

* fix argument text for POSITIONAL_OR_NAMED cases

Now keeps the notation as used in the scenario (with or without the argument's name) in the generated keyword arguments.

* fix failure on empty varargs

* workaround for embedded argument name mismatch

Accept that names of embedded arguments in the @Keyword decorator must match their Python argument counterparts.

* support step modifiers for non-embedded arguments

* handling vararg modifiers

* add tests for step modifier with free named arguments

* add error message for vararg and free named arg modifiers

* docu update for step modifiers on non-embedded arguments

* promote random seed logging to info level

Logging the seed at info level allows to run without debug logging for smaller log files, without losing the ability to rerun an interesting trace.

* promote random seed logging to info level

* make tests independent

* Remove embedded-arguments-only restriction for modifiers

* bump version to 0.10

* Implement Feature Path Highlighting in Scenario and State Graphs

* Implement State Graph Path highlighting with Stack

* Clean-up of unused features, move some logic, fix empty state entry bug

* Formatting

* Formatting

* Remove unused return value

* Fix bug

* StateInfo unit tests

* StateGraph unit tests

* Merge with main, fix some bugs, alter ScenarioStateGraph to be in line with the rest and fix up some of its unit tests

* Add short explanation

* Test self-loops

* Minor tweaks

* Remove trailing newline

* Fix nuking of stack

* Better formatting of state info

* Spam __update_visualisation all over the place for refinement

* Fix nuking in scenario-state graph

* Warn instead of crashing

* Sanity check

* Do add edge with start node

* Expand tests

* Merge mistake

* Fix oopsie

* Format and fix type

* Move helper to StateInfo

* Protected helper

* Forgot this one

* Fix nuked graphs

* Implement feedback

---------

Co-authored-by: JFoederer <32476108+JFoederer@users.noreply.github.com>
Co-authored-by: Diogo Silva <diogo.xuya@gmail.com>
* Clean-up of unused features, move some logic, fix empty state entry bug

* Merge with main, fix some bugs, alter ScenarioStateGraph to be in line with the rest and fix up some of its unit tests

* Merge mistake

* Start of rework

* Rework TraceInfo, extract common graph logic

* Fix unit tests

* Bug fixes and minor changes

* Fix nuked graphs

* Remove outdate acceptance tests

* Generics

* Proper type

* Fix bug in Johan's code

* More sanity, implement feedback
* updated design with rework from Thomas

* refactored design - Thomas comments

* removed pdf version of 2025-12-08 render

* refactored design - Thomas comments

* add 'graph_type' to 'process_test_suite'
* added initial autopep8 CI/CD

* different autopep8 now, lets see...

* new autopep8 that actually should work

* now one that also adds a commit that fixes it

* fix try 2

* revert to just check

* remove redundant stuff

* added max-line-length 120 to autopep8 check

* formatted code with autopep8 (max-line-length 120)

* made formatting issues check also pass for purely whitespace output
* changed part of abstractgraph interface for delta graph development

* implemented scenariodeltavaluegraph

* implemented reduced-scenariodeltavaluegraph, but should still discuss how to label equivalence classes (currently just picks a representative). Fixed part of vertex info being indicated as edge info for scenariodeltavaluegraph. Trace highlighting is still broken for reducedSDV

* removed redundant code in __init__ of reducedSDVgraph and added code to update final_trace to make trace highlighting work

* initial test commit for SDVGraphs

* documentation for SDV graphs

* added TODO comment

* implemented comments from Douwe (added comments and reset graph setting in suiteprocessors.py)

---------

Co-authored-by: tychodub <t.b.dubbeling@student.utwente.nl>
* Make HTML generation static

* Added a fullscreen button in the graph visualization toolbar

* Added the suite name as the graph title

* Fixed generate_html method to use NetworkVisualiser class

* Changed generate_visualisation return to use GRAPH_SIZE_PX constant

---------

Co-authored-by: Thomas Kas <t.s.kas@student.utwente.nl>
…rrounding Scenario.data_choices, Step.model_info and SuiteReplacer._processor_lib, since those required further input from Johan, and __handle_non_embedded_arguments, since I could still not find out the type for the argument using the robotframework documentation.
@tychodub
Copy link
Contributor Author

I pushed a commit with all the changes except for those that required further elaboration.

@JFoederer
Copy link
Owner

Great progress! Let's conclude the remaining open conversations and work towards the merge. Amazing how much insights this typing exercise brought up!

JFoederer and others added 2 commits January 18, 2026 11:35
…ndle_non_embedded_arguments. Added object to the union of types at SuiteReplacer._processor_lib. Reordered imports in suitereplacer.py to group the two import types together.
@tychodub
Copy link
Contributor Author

The last commit message also mentions the changes that were made in commit a95c0ef, because I did not see said commit until I committed my local changes which contained the same changes.

@JFoederer
Copy link
Owner

Compatibility check with Robot framework 7.3.2 passed.

@JFoederer
Copy link
Owner

From the three enum vs. literal discussions I updated the argument kind to use enum. If we like this approach better, then the gherkin_kw is also a candidate for conversion. The ROBOT_LIBRARY_SCOPE is not our type, so that will not change in this pull request.

@JFoederer
Copy link
Owner

I did not opt to change gherkin_kw to enum. It did not help the readability of the code, due to the frequent checking of subsets and checking its boolean/None value in if gherkin_kw.

@JFoederer
Copy link
Owner

@tychodub, are there still open items on your list where you needed clarification to complete the type hints?

Other than that there is just one discussion still open. To conclude whether we accept a dict type to be a stub for ModelSpace and str for Scenario in TraceState, or that we create proper types for these stubs.

@tychodub
Copy link
Contributor Author

@tychodub, are there still open items on your list where you needed clarification to complete the type hints?

Other than that there is just one discussion still open. To conclude whether we accept a dict type to be a stub for ModelSpace and str for Scenario in TraceState, or that we create proper types for these stubs.

I think there are no open items left.
For the discussion surrounding types that are only used in test: I personally think type hints should reflect intended usage of methods and not be influenced by unit tests.

  1. If a test ends up going wrong because a wrong type gets used, it will be easier to find out the root cause if it is specifically indicated that said type is not truly supported.
  2. Adding types that only get used for small tests (and are not truly supported by the method) may confuse end-users of the methods. Since type hints serve as a form of documentation, it is important that type hints can be trusted to be accurate.

@JFoederer
Copy link
Owner

Ok. I think we already agreed that no test-specific typing would be left in production code. There is still a couple to be removed then.

If I interpret your remark correctly, then you also propose to use proper typing the other way around. In which case we can add simple stubs like class Scenario(str): pass to the test file.

@tychodub
Copy link
Contributor Author

Ok. I think we already agreed that no test-specific typing would be left in production code. There is still a couple to be removed then.

If I interpret your remark correctly, then you also propose to use proper typing the other way around. In which case we can add simple stubs like class Scenario(str): pass to the test file.

Is the second part of your message directed to @osingaatje? He suggested also fixing the types used in the unit tests. While I do think it's better for unit tests to be written with the correct types, I don't think updating the unit tests to do so is a priority right now. Also, Scenario can already be constructed with just a string, so no stub definition is necessary.

@JFoederer
Copy link
Owner

I updated utest\test_tracestate.py but didn't have the time to do utest\test_tracestate_refinement.py.
Also, my pylance does show the type hints, but does not complain when using a different type in a call. Can you check if the current solution is good enough to prevent the warnings you were getting?

@osingaatje
Copy link
Contributor

Argument of type "Scenario" cannot be assigned to parameter "scenario" of type "Scenario" in function "confirm_full_scenario"
  "utest.test_tracestate.Scenario" is not assignable to "robotmbt.suitedata.Scenario"PylancereportArgumentType

We cannot use stubs here to get Pylance to shut up.

I suggest:

from robotmbt.suitedata import Scenario
from robotmbt.modelspace import ModelSpace

Because Scenario already has a string-only constructor no code changes are needed (except explicit Scenario(name=...), but for ModelSpace I'd suggest a _from_dict function, and then changing ModelSpace(a=3) to ModelSpace.from_dict({a:3}) (or using a private method in the utest itself)

@JFoederer
Copy link
Owner

How is this for e.g. TestSteps in test_suitedata.py? Where we patch the unit to import the stub instead of the real thing?

I do not want to import cross dependencies for a unit test, because that would make it an integration test.

@JFoederer
Copy link
Owner

I reproduced the error message after finding the relevant settings in pylance. Getting them fixed is another story. It expects type stubs in .pyi files, but that is about as far as I got today. I got distracted by all the other files it also marks red.

@JFoederer
Copy link
Owner

I will try to draw some conclusions and wrap up an (intermediate) solution tomorrow. Otherwise this merge will get too close to your final presentation.

@JFoederer
Copy link
Owner

Status on type hints

Included type hints for:

  • arguments
  • return types, except return None
  • member variables

Excluded:

  • local variables
  • warnings on optional variables (... | None)
  • stub/mock type warnings in test files
  • Self type (pending dropping Python 3.10 support)

@JFoederer JFoederer merged commit 4e473a5 into JFoederer:main Jan 23, 2026
3 checks passed
@Egietje Egietje deleted the TypeHintPR branch January 23, 2026 14:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants