py-teststand 0.2.0__tar.gz → 0.2.1__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.
- {py_teststand-0.2.0 → py_teststand-0.2.1}/.gitignore +1 -1
- {py_teststand-0.2.0 → py_teststand-0.2.1}/CLAUDE.md +10 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/PKG-INFO +15 -11
- {py_teststand-0.2.0 → py_teststand-0.2.1}/README.md +12 -5
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/analyzer_step_name_length.py +16 -13
- py_teststand-0.2.1/examples/data_type_manage.py +148 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/execution_run_test_headless.py +5 -2
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/launch_all_examples.py +2 -2
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/property_object_serialize.py +1 -1
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/sequence_build.py +25 -21
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/step_insert.py +2 -2
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/ui_messages_handle.py +5 -4
- py_teststand-0.2.1/examples/variables_manage.py +152 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/workspace_create.py +33 -25
- {py_teststand-0.2.0 → py_teststand-0.2.1}/pyproject.toml +140 -135
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/__init__.py +2 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/activex.py +657 -657
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/engine/engine.py +1 -1
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/exceptions.py +1 -2
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/watch_expression.py +187 -186
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/messaging/output_messages.py +63 -61
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/property/property_object.py +1328 -1328
- py_teststand-0.2.1/src/py_teststand/py.typed +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/code_template.py +63 -63
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/sequence.py +553 -553
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/sequence_file.py +461 -461
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/station/search_directories.py +127 -125
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/command.py +256 -256
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/connections.py +31 -31
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/entry_point.py +81 -81
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/events.py +534 -505
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/integration/test_examples.py +3 -3
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/integration/test_property_object_serialize.py +2 -2
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/test_com_contract.py +25 -0
- py_teststand-0.2.1/uv.lock +808 -0
- py_teststand-0.2.0/examples/data_type_create_custom.py +0 -83
- py_teststand-0.2.0/examples/variables_create.py +0 -107
- {py_teststand-0.2.0 → py_teststand-0.2.1}/.markdownlint-cli2.jsonc +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/.python-version +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/LICENSE +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/execution_run_subsequence.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/station_options_update.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/step_insert_from_template.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/examples/users_manage.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/.graphify_labels.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/.graphify_root +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/GRAPH_REPORT.md +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/0041043937ad3008273915d37b7f4b2d48ca2c4612d45ae3f8cd0cb931b90f9f.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/021c67591ed36baaccec5597b1aaa5da45a3d107860151d0c14da8d8e82d13fe.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/023707fc22c5dae0fe050b058cef36e8166178bd19bf64c19d1d5769193e0b66.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/040ee1db9c6b7f496603e954cded103cc0a695fdff0107104d1971e6bd77fa80.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/05037a9ec557a4372515feea0cb82e6b8112ac7c5e298565964fbd270f96bb55.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/0524858e50a4d2f7d2ac92c57ca3c87df637bf4c3158c7092a413e4393c857a4.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/0561a3660d3619ac6a5591c0657208ef1151afc18df8f2fd6f97de8670d8eb60.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/057056cc111fdb36b69e58f64079572f5c47872e0727d1ad3dfc0f35e7d39a4f.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/057e562996ba53b27fd80676787dca1563c48de754f9cd7932562ae64c3b5489.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/064e97d62db5d77399540dec673d05b900a3e29224bb4e45bc3e879729f20003.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/06c31bd2b14400097f1e5123a6f39525ba4c4e5e2a5e7ff4c38a43b224d20a0d.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/070c095dddd2f798973cbb1332d344bf81370ea5a6eda28e88b1f7a27ef6c709.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/094e59f0e4cdb42feca81333bf3bf014eca76ad887ef1490483f798c17d40cd5.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/0aec586f84490fed93173f8a2200485ceffc529450740dcf5edbe12a7d89f781.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/0af23434a97b56cbda3aaf2de520ee9e18a629be0ef406a90dac45260481c1bf.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/0bd90bc4c1dd73076d8627f6ea7be67faaf504d30221b1dce45cb1c443755fb5.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/1051e1923497524696fb7fa1b71ba3a9d3cf12ec8519b1e8209d9d5eac717990.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/1086f0d1446ee0d57fc4c325f3828ff783e328ced88aac13b45f718161499e53.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/10fe404eb03263a768b27a2e92b2fe20e33cda3eab265a84860286430be0a49b.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/13bdd9d4f7de5ab5fbb955890067eb3772a2302e014480243ae141a4eee8b4f7.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/17de4e480542b25d6f2a11461ae4f41a6282c3ecbeb3619b0b42fdbb7f31939c.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/1d601091a3312ce89ddc9523bffccf41742eb6ea1223a6b4f751c210ffce1fb4.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/1e4d42449081955231608e3fa48b5c3102243d55a80e9064b88440669ed821b2.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/1f727c948a41c946dd0aa376993d5620f226497d49404c03b3c175d057b4ab29.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/1f7c2be5abf85169f9c409d39e58419418193281eeb391dc3ec0d1f6784f40dc.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/2165f2f41684c71dbce5e6edf7262786c5aa8518828e00e2a4dce75492f53aa3.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/22e04e79d7912eb1b7e3bca68279f3fa7e2936b3d2706fcdf688fff96f7c30c8.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/252d1adbbb189a3636432d8de48b5ed7c8d1f185c5ea46ceb616071960b1be42.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/25ab62b76a5f58693d5161dabf0a58862a7d6d5e9b054cc2347ffb79d4468f65.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/2b7f894857506a93df04568d3bc252c6883ac4010ba64b49a8c13c9cd06330ca.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/2bbb54bb8f3b91b33e7e872ea5e2b129079a60fe8284b8dd8bf5488b2f76b55d.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/2d70a40698b885cb7705c0d57922dfc922ef6b90e9a4580935d170395bc51a6e.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/2ddf8f9e5aa81db1e984bd5812d91143f64ab806a7b5676d6e7f23d1d08f677f.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/3289a80010b6c0faed89308018fa31f7031f27ae0d853299443c23ba8a4d6e6b.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/3312f8a2eccbfd08fabdba5d2af656bfbcb95e5b7e5390abf35ad5140759a710.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/35d6fee40fd65a1c224aa8320fbd8ef959f6975b16cc89fc2cfbb3c1b4e95641.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/37cb92f2f6a01d4862632405ced4934cc003818147fd14ea9a636bc7336d3af1.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/3ace387692703afd7ecab2396d8eb8b3dc6411c0931ebf68ff5370013c707fa9.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/3b65d0f842b856818ed2510234a106990e02450d60aed9075cc4c9f4b14101bc.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/3b90f45c585a53b5f55ef2c3761eef4b97fcef1eb344f9a4819c989b174b52e5.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/3cf920bfdd765673b964deab1cf13959604b7648091d4c58209f818cc3fede98.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/3d97defd459d93180b984ca62794c47f1da9a8dc105175bfc1d8948fc8dc3f29.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/4096008e37ad33f487fa031012fdc7f354edbb3e2c3d82eeeae616e8e1ae75fa.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/4278f99739c7c54475247d2cfb57eda95ad3cc39d7bbaf04729c04932d9fef12.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/44963597cd3ea0c48e79c9aeb4e7838f1faa5bcde319b7ff81b29aa6549d551f.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/49e757465d8e83eb1ea11482682a0dc9bf8dd399847c883954925749ad6470c2.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/4e9f3dd260b769260bab0fd12ca46ae6b3b17221c6968fed8b7907173b05fc2d.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/519a945f4a84c930588f887f3b23f13102ea6138645d177cef5f98b7b91e6229.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/531a38ee0ed1035f37eecda69c27f43d9a0ecd6fea2fc6127c3a3318f5f06dad.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/535082e7e072de1deb460d4d58ba560c76f4c0ffdba7836846c3699d4c47fc5a.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/563deb73b3327340c242a025beeca43321716dfbcea23fac9c89875d67a08f72.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/584d486255b4cee316ca9e6e3656c989d600ac403ccf01bdb3d548606678b17b.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/589dad68071e187dbb2fbbaa04d83c88bf219f7d428bfe1aa5a1ff7dbf023a23.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/5a4e9b332727fe6e94e1548fb31f14aef41966f5ead08e7dde780b02d60148f5.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/5bd0ff70a33bedbee8d278646e92ab57e29a43867cd60e7fb918508833117b56.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/5c088e2c173f3f6dd18f3df4cd20a198a76d4d5da9db7f8b749b55ea97210f05.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/627d8be024734a3d490521cd423e9db4c50870f3ca6ac761e75f86ea55eb9491.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/62ace6fa362a937c7d2e645eea0192df37d1de5fc0fcc9f0a16f708b74ecd48a.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/6464e2cd097df4628226ba38836dd4d55ea4b97dba4dd952e1a34c84fa00e914.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/6469622a3449ce827fd414b465085e38a53133a20024b6c30e13c6fab1cbd06e.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/68806e21c83d8f6bb9b7deaf161a26e2543fb6a6052839b92fd229c44de4785d.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/689e2aa834fc2b6c42e3a6ad0c9b2a9060d968a9a8dd8d1c47be911b5a7347c6.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/6a583adb3c041e3e49886b4b96a73494fdb8c677ac28463c037845ba616348a3.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/6b39e36d9b59b214516369764a7c635e8b6af335c69fd2ab4fbd3be0aa12f539.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/6bae4a41d4b3c584b87f6e963948951164f820ba2f77065856e93fa5fb77da4f.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/6d775401047dd566d5fcab422fdb64798fc85eef1ccd9444c43376314a7e81ba.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/6e8481e9dad0e6c1793e5f6ccbbf1dfb5ba88a09fb9e326425df6bf3b5b10e33.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/70ac455c2976654f81e4ada2accbeb9a0ed097e513ee641a1767038b60f3d058.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/73190900d1852a833a8e0c0cc86f2a1083d4b3ffcdd36ccf239bf3fefe2be9b9.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/731a07b1575dc21af660051d44974822d16d4d07e0ff8c959f3e7971c16e9a7a.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/73ee87e06204f3346bd71d9107d89a9171428bacf3611019cdfcfd4aef224acb.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/73f5451927075637af3c96c14efec5d69b6da496baee2dc759048edc9b12c232.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/74c85d86a6d8483900d3fa46e3dd606f54d64af4ae6e5b75421fe1c6788b3c60.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/77cefb8a568e79bbbf5ea2f16eca5b1dedef30fde3405aab81eec97baf84f827.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/79ce979e77967e52a44d8579c4303ab655f65ad9bc258c3bd96c3dd7305cae06.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/7d5f935bff18ec87a6c7a089cd08c4d89cc922a0e020c1fb1b57f13ed586358c.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/7dc6b1a6affc2de030eaa790e0826a3797ed82b2f5e6df1481df872f1f511e9e.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/81a280d2907246e14a57096449e036eb0363da6f0074ecedf14879d6f09a826c.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/82cad94a35ab2d431beb0f15d5d13decd59ab65525dfc802995ddc7fbacedc21.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/83d57f81198fde4ad8a03bbe0f9d80058eb82724505cb31283206d38486285cc.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/85c074209d24896e542e425b1fb9fad5d2704db1286e406b25fbe2a9e1c62ac8.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/86332e56e1d088488a3378a8ffb47b13abb39e8c81cdeb5f1d546a14a5d4e03f.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/8b4f66ce9958d1bb4077dfe1d0e4df2f7f4642a838714dbc93316dc3c8523534.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/8b9eaad4dfb5c0936cebcafde3c3b368c71c5c2e7f4fbc282c887051e25567e5.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/8e73cca8cf7e6238b5a9e4a46b62d2cf8968fb9e071c8ff8e21a55b1cbb1cd46.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/8f1414450de85a7ca36b1c4508c946084f9eaa83eee74f709dd09ebb7fc9e773.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/9811147e5abebc52edff502471a40f369ee1329e9f029ef3258976404f06a8f9.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/98270c04210ce70f7197fd3c1df74140159aed78f3d6b0c736b9fd1de4309b68.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/98f967e9230b612cb641244c969d3461874f40a74d00096217c05b4ca3cc5163.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/9cce4a16b043c387789e0867504b51418b27f557bf5874111ac917bde8e0b109.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/9d3d1aee5a15a733c47dd04fdb5943d68a49f8ce13d67b05bc0a14497328f58d.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/9d440f60091a4f93dcf1d78367e2c71755a3acdfe8844a1b5f756a235b763488.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/9fd47dbb9db188abce18b1f3063253323bca0327c3362dbe36ee49250e348d54.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/9fe051f8082e371f9df5f940b8f071800623a9ad5b40755285095658d8f28b5a.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/a06be12e9602b3b595742d0cad924633191314032eaf6acaba75ae02c60a9811.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/a67e0d0fc7ebb86fc0e08ddc07be6131e22b253ad50fb36935e7901dec5977b7.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/a86964aa1cbd83641808a11c8ec3231008bae1345219c2a5646e36a8e06599a5.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/a93efc87b8b26bb8e00bc3bb298aedd3d7ac45ceb950802398d2414bbf47c0dc.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/aa76182d9de824910acfbbfc5ea8f46681debd787c018927147e47b85f056e8e.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/ac62f874e909973d6a406359c3a3331861f7775ce15427c629754984e6c2bc59.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/acf05ae7385ed2c7fc6639333fe802f06a0ae3b54b7dc2704234673a41328154.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/ad228703c7b568b72aee72ca2c50dc043ba963295abff15d0f2eced3379378dd.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/ae24c1a5d0d0a7e29eec5c4f95e19009825ded2c622d288ba63e6b25de7524b5.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/aedd4475f0cf7c73ea7553423af3f920eb19c3efa9eb2f8a611f6e898dfe2a44.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/b079373b22270ed561a40ead88df318a0b3cd52b143607c34f7340508f6e390e.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/b15b8672daa3f5df56cc7f97ee8294dd2d23b975dc9e34256c69726676be3daa.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/b5a337d95da18b2c918d1be090cf235c67a7a09cd60f23033e8c570fa8dbb748.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/b60d2e0d59f626d9ff57d7230795b09be357a37343d0d2c0d1ca958a1857d8bd.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/b710a0414f46ecb976cc66ac059d3a74dbd64d0bf8f1116de968837e581b6422.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/b73436f8a0e225ea354ec4ad7993c5d5887b7227f7545e2ead47ac03ccc082cd.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/ba1fcae5bd482a5ee1095215721f18a5951393e75bb88a9df1b3e1922e2202ef.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/ba646e84c605179808ec987d421f534a1c4af669a910fdd1ac75bad73d8b587e.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/be18c3a11472b8d81adfe9761be1ff309c93c04be3f69d56638efb019757f8f7.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/c018635d30a0f5436fc124a28ca204b8199b2dcec3335147150e0d34b9e1f82a.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/cb761115d0ed359fc4e55ad0c40245352cc091c68e5171ac20ef5e6d9d9832d1.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/cc658b209eeaf4c9249998a1534cefdf6837ce3a7de82fc62202102fe09957a2.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/cd2ce8667e344c6769096140ab1e4d9829ba2424eb9bdb65dee55f09469fecc8.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/cd8ce55adda67b165bf6272936d26dc172ba4d7a5fbfa4d5142181855c40f02d.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/cecb346166b599b5343dad969681c67168e5130e3a4018ee8fc903efc273fe04.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/ced68cd7e814d7774ffbdc161d16335221561854b99e12f107671e17337504b1.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/d08762a2d53ea94992d179f3affdd360ad2d58277024715af643374e65e62606.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/d48e2ae9efb9c635d241fe4f1d65e0ec51c9ac3740c29a0db58e3bcccc0e2466.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/d54b3634353a29d5fc12e6ccc72ca587a9b2676489bf893524c004d4afdefa51.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/d8ad7e776fd4b3708759b004e7ed524ff77a988d48237e5d357dc99a9a3bb79d.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/d9dd2631fda1b4480019731d75b0a908a057084bc22ad2ca66a2c381b86e0a38.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/dd430a8b0bc073c8deb7e7be1ca766292097b47301797452810293d73d53ff70.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/e1713cdd15edde27fe7f01c40841ee3ede0d411e350e2b31b9e8b5b2f9ce6feb.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/e5581298f1ebdbc113077df91f6215a07ddde68e9a45c01035f87d241062abd2.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/e5dcdfd16046923e879eb93db75c0df5067b2859f57259df63cdcce61ef2c03e.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/e5e9a12f89839a814832a5d5c375d4f6da3f81197790d2d52467fca122f43fd8.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/ef396e2cc36a574a59a95bf95caae976ec92698d1b43a1fdca8e7a20609d6aa3.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/f1607b2d6749b8e2f1b21e6985fa4da4077d01500b190e20b3d4ac89c8cd0e69.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/f68a4af4ef4d24cc0416195c9b123d0cb4f6811c08554914866d4a86835dab24.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/f9ee28f629cd46d9b44cdd1dfa64aadb0231af8002093266902d90e1f2f9fc88.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/ast/faabe069e0568dabcc65124f0fa7d56e3ddfadf62523fc3f208ee4ad11c46f8d.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/cache/stat-index.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/graph.html +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/graph.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/manifest.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/graphify-out/merged-graph.json +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/adapter.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/cvi.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/dll.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/dotnet.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/htbasic.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/labview.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/labview_nxg.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/python.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/adapters/sequence.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/analyzer/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/analyzer/analysis_context.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/analyzer/analysis_message.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/analyzer/analysis_utilities.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/analyzer/rule.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/analyzer/rule_configuration.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/analyzer/rule_setting_values.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/analyzer/types.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/com_wrapper.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/engine/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/engine/enums.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/external_report_viewers.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/file_information.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/images.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/search.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/core/utility.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/additional_results.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/breakpoint.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/database_options.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/edit_args.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/execution.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/interactive_args.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/output_record_stream.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/report.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/result_log.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/sync_manager.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/execution/thread.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ext/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ext/events.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ext/step_types.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/messaging/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/messaging/output_message.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/messaging/ui_message.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/property/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/property/array_dimensions.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/property/data_type.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/property/property_object_file.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/expression.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/location.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/sequence_context.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/step.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/step_group.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/step_type.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/sequence/type_palette.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/station/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/station/station_options.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/application_manager.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/button_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/checkbox_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/combobox_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/execution_view_manager.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/expression_edit_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/insertion_palette.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/label_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/list_box_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/listbar_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/menu_item.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/report_view_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/sequence_file_view_manager.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/sequence_view_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/status_bar.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/styles.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/ui/variables_view_ctrl.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/undo/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/undo/undo_item.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/undo/undo_item_creator.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/undo/undo_stack.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/users/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/users/user.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/users/users_file.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/workspace/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/workspace/workspace_file.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/src/py_teststand/workspace/workspace_object.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/conftest.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/integration/_ui_message_stress.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/integration/test_api_compatibility.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/integration/test_memory_leaks.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/integration/test_ui_messages.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/test_core.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/adapters/test_activex_adapter.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/adapters/test_dotnet_adapter.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/adapters/test_labview_adapter.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/adapters/test_python_adapter.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/analyzer/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/analyzer/test_rule_authoring.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/__init__.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/test_engine.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/test_enums.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/test_errors.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/test_expression.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/test_property_object_file.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/test_sequence.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/test_sequence_file.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/core/test_step.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/execution/test_database_options.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/execution/test_execution.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/sequence/test_sequence.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/sequence/test_sequence_file.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/test_core_mechanics.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/test_lifecycle.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/ui/test_events.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/ui/test_execution_view_manager.py +0 -0
- {py_teststand-0.2.0 → py_teststand-0.2.1}/tests/unit/ui/test_sequence_file_view_manager.py +0 -0
|
@@ -201,6 +201,16 @@ Prefer extending this facade over deep imports in user-facing code and examples.
|
|
|
201
201
|
typing (`list[str]`, `str | None`); do not import `List`/`Optional`/`Union`.
|
|
202
202
|
The codebase targets Python 3.8 syntax (Windows 7 support), so avoid 3.9+/3.10+
|
|
203
203
|
only syntax such as `match`.
|
|
204
|
+
- Ruff lint selects `ANN` (flake8-annotations): every function parameter and
|
|
205
|
+
return needs a type, including in `examples/` (tests are exempt via
|
|
206
|
+
per-file-ignores). `ANN401` is ignored on purpose: COM members return
|
|
207
|
+
VARIANT/IDispatch, so `typing.Any` is the *correct* annotation, not a missing
|
|
208
|
+
one. So annotate from the wrapper body, never guess: a member that returns
|
|
209
|
+
`bool(...)`/`int(...)`/`str(...)`/`float(...)` is typed accordingly, one that
|
|
210
|
+
wraps `Foo(...)` returns `Foo`, and a raw `return self._com_obj.X` (a VARIANT)
|
|
211
|
+
is `typing.Any`. Generator `__iter__` methods are `typing.Iterator[typing.Any]`.
|
|
212
|
+
Run `uv run ruff check` after typing changes; do not add blanket `# noqa` to
|
|
213
|
+
silence ANN.
|
|
204
214
|
- Compatibility matrix is real and must hold: Python 3.8–3.14, Windows 7–11,
|
|
205
215
|
32-bit and 64-bit, TestStand 2016 through 2026+. Do not drop a path because the
|
|
206
216
|
current dev box is 64-bit / TestStand 2026.
|
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: py-teststand
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.1
|
|
4
4
|
Summary: Community object-oriented Python 3 bindings for the National Instruments TestStand™ COM API
|
|
5
|
-
Project-URL: Homepage, https://github.com/TheDomcio/py-teststand
|
|
6
5
|
Project-URL: Repository, https://github.com/TheDomcio/py-teststand
|
|
7
6
|
Project-URL: Issues, https://github.com/TheDomcio/py-teststand/issues
|
|
8
|
-
Project-URL:
|
|
9
|
-
Project-URL: Source Code, https://github.com/TheDomcio/py-teststand
|
|
10
|
-
Project-URL: TestStand API Reference, https://www.ni.com/docs/en-US/bundle/teststand-api-reference/page/tshelp/teststand-api-reference.html
|
|
7
|
+
Project-URL: TestStand™ API Reference, https://www.ni.com/docs/en-US/bundle/teststand-api-reference/page/tshelp/teststand-api-reference.html
|
|
11
8
|
Author: Dominik Rajchel
|
|
12
9
|
License: MIT
|
|
13
10
|
License-File: LICENSE
|
|
14
|
-
Keywords: automation,com,manufacturing,national-instruments,ni,python,pywin32,station-provisioning,test-automation,teststand,windows
|
|
11
|
+
Keywords: automation,com,manufacturing,national-instruments,ni,python,pywin32,scripting,station-provisioning,sugaring,test-automation,teststand,windows
|
|
15
12
|
Classifier: Development Status :: 3 - Alpha
|
|
16
13
|
Classifier: Intended Audience :: Developers
|
|
17
14
|
Classifier: Intended Audience :: Manufacturing
|
|
@@ -39,9 +36,14 @@ Description-Content-Type: text/markdown
|
|
|
39
36
|
|
|
40
37
|
# py-teststand
|
|
41
38
|
|
|
39
|
+
[](https://pypi.org/project/py-teststand/)
|
|
40
|
+
[](https://pypi.org/project/py-teststand/)
|
|
41
|
+
[](https://opensource.org/licenses/MIT)
|
|
42
|
+
[](https://pepy.tech/projects/py-teststand)
|
|
43
|
+
|
|
42
44
|
Community object-oriented Python 3 bindings (twin API) for the [National Instruments TestStand™ COM API](https://www.ni.com/docs/en-US/bundle/teststand-api-reference/page/tshelp/teststand-api-reference.html).
|
|
43
45
|
|
|
44
|
-
> ⚠️ **Early Implementation Stage**: Treat it as experimental.
|
|
46
|
+
> ⚠️ **Early Implementation Stage**: Treat it as experimental. Wrapper behaviour may change between releases without notice (like error catching).
|
|
45
47
|
> 🤖 **AI Disclaimer**: This project uses LLMs for codebase and coverage audits and does not replace or integrate with the [NIGEL™ AI Advisor](https://www.ni.com/en/support/software-support/nigel-ai.html).
|
|
46
48
|
|
|
47
49
|
## 📖 Overview
|
|
@@ -129,17 +131,17 @@ This approach means the bindings target a specific version of the TestStand™ t
|
|
|
129
131
|
|
|
130
132
|
## 🚀 Installation
|
|
131
133
|
|
|
132
|
-
###
|
|
134
|
+
### ⚡ uv
|
|
133
135
|
|
|
134
136
|
```powershell
|
|
135
|
-
|
|
137
|
+
uv add py-teststand
|
|
136
138
|
|
|
137
139
|
```
|
|
138
140
|
|
|
139
|
-
###
|
|
141
|
+
### 📦 pip
|
|
140
142
|
|
|
141
143
|
```powershell
|
|
142
|
-
|
|
144
|
+
pip install py-teststand
|
|
143
145
|
|
|
144
146
|
```
|
|
145
147
|
|
|
@@ -147,6 +149,8 @@ uv add py-teststand
|
|
|
147
149
|
|
|
148
150
|
## 📈 Popularity Over Time
|
|
149
151
|
|
|
152
|
+
[](https://star-history.com/#TheDomcio/py-teststand&Date)
|
|
153
|
+
|
|
150
154
|
---
|
|
151
155
|
|
|
152
156
|
## ⚖️ Legal
|
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
# py-teststand
|
|
2
2
|
|
|
3
|
+
[](https://pypi.org/project/py-teststand/)
|
|
4
|
+
[](https://pypi.org/project/py-teststand/)
|
|
5
|
+
[](https://opensource.org/licenses/MIT)
|
|
6
|
+
[](https://pepy.tech/projects/py-teststand)
|
|
7
|
+
|
|
3
8
|
Community object-oriented Python 3 bindings (twin API) for the [National Instruments TestStand™ COM API](https://www.ni.com/docs/en-US/bundle/teststand-api-reference/page/tshelp/teststand-api-reference.html).
|
|
4
9
|
|
|
5
|
-
> ⚠️ **Early Implementation Stage**: Treat it as experimental.
|
|
10
|
+
> ⚠️ **Early Implementation Stage**: Treat it as experimental. Wrapper behaviour may change between releases without notice (like error catching).
|
|
6
11
|
> 🤖 **AI Disclaimer**: This project uses LLMs for codebase and coverage audits and does not replace or integrate with the [NIGEL™ AI Advisor](https://www.ni.com/en/support/software-support/nigel-ai.html).
|
|
7
12
|
|
|
8
13
|
## 📖 Overview
|
|
@@ -90,17 +95,17 @@ This approach means the bindings target a specific version of the TestStand™ t
|
|
|
90
95
|
|
|
91
96
|
## 🚀 Installation
|
|
92
97
|
|
|
93
|
-
###
|
|
98
|
+
### ⚡ uv
|
|
94
99
|
|
|
95
100
|
```powershell
|
|
96
|
-
|
|
101
|
+
uv add py-teststand
|
|
97
102
|
|
|
98
103
|
```
|
|
99
104
|
|
|
100
|
-
###
|
|
105
|
+
### 📦 pip
|
|
101
106
|
|
|
102
107
|
```powershell
|
|
103
|
-
|
|
108
|
+
pip install py-teststand
|
|
104
109
|
|
|
105
110
|
```
|
|
106
111
|
|
|
@@ -108,6 +113,8 @@ uv add py-teststand
|
|
|
108
113
|
|
|
109
114
|
## 📈 Popularity Over Time
|
|
110
115
|
|
|
116
|
+
[](https://star-history.com/#TheDomcio/py-teststand&Date)
|
|
117
|
+
|
|
111
118
|
---
|
|
112
119
|
|
|
113
120
|
## ⚖️ Legal
|
|
@@ -17,6 +17,9 @@ from typing import Any, cast
|
|
|
17
17
|
|
|
18
18
|
from py_teststand import Engine, StepGroup
|
|
19
19
|
from py_teststand.analyzer import AnalysisContext, AnalysisTransition, RuleSeverity, rule
|
|
20
|
+
from py_teststand.sequence.sequence import Sequence
|
|
21
|
+
from py_teststand.sequence.sequence_file import SequenceFile
|
|
22
|
+
from py_teststand.sequence.step import Step
|
|
20
23
|
|
|
21
24
|
RULE_ID = "PyTS_CheckStepNameLength"
|
|
22
25
|
MAXIMUM_STEP_NAME_LENGTH = 15
|
|
@@ -30,8 +33,8 @@ MAXIMUM_STEP_NAME_LENGTH = 15
|
|
|
30
33
|
)
|
|
31
34
|
def check_step_name_length(context: Any) -> None:
|
|
32
35
|
"""Report any step whose name is longer than MAXIMUM_STEP_NAME_LENGTH."""
|
|
33
|
-
step = context.object
|
|
34
|
-
name = step.name
|
|
36
|
+
step: Any = context.object
|
|
37
|
+
name: Any = step.name
|
|
35
38
|
if len(name) > MAXIMUM_STEP_NAME_LENGTH:
|
|
36
39
|
context.report(
|
|
37
40
|
RULE_ID,
|
|
@@ -43,9 +46,9 @@ def check_step_name_length(context: Any) -> None:
|
|
|
43
46
|
|
|
44
47
|
class _Violation:
|
|
45
48
|
def __init__(self, rule_id: str, text: str, location: Any) -> None:
|
|
46
|
-
self.rule_id = rule_id
|
|
47
|
-
self.text = text
|
|
48
|
-
self.location = location
|
|
49
|
+
self.rule_id: str = rule_id
|
|
50
|
+
self.text: str = text
|
|
51
|
+
self.location: Any = location
|
|
49
52
|
|
|
50
53
|
|
|
51
54
|
class _OfflineStepContext:
|
|
@@ -57,7 +60,7 @@ class _OfflineStepContext:
|
|
|
57
60
|
"""
|
|
58
61
|
|
|
59
62
|
def __init__(self, analyzed_object: Any) -> None:
|
|
60
|
-
self.object = analyzed_object
|
|
63
|
+
self.object: Any = analyzed_object
|
|
61
64
|
self.transition = AnalysisTransition.BeforeStep
|
|
62
65
|
self.findings: list[_Violation] = []
|
|
63
66
|
|
|
@@ -65,13 +68,13 @@ class _OfflineStepContext:
|
|
|
65
68
|
self.findings.append(_Violation(rule_id, text, location_object))
|
|
66
69
|
|
|
67
70
|
|
|
68
|
-
def _build_sequence(engine: Engine):
|
|
69
|
-
sequence_file = engine.new_sequence_file()
|
|
70
|
-
main_sequence = sequence_file.get_sequence_by_name("MainSequence")
|
|
71
|
+
def _build_sequence(engine: Engine) -> Sequence:
|
|
72
|
+
sequence_file: SequenceFile = engine.new_sequence_file()
|
|
73
|
+
main_sequence: Sequence = sequence_file.get_sequence_by_name("MainSequence")
|
|
71
74
|
for name in ("Init", "Temperature Check", "Measure Output Voltage Rail", "Cleanup"):
|
|
72
|
-
step = engine.new_step(adapter_key_name="", step_type_name="Action")
|
|
75
|
+
step: Step = engine.new_step(adapter_key_name="", step_type_name="Action")
|
|
73
76
|
step.name = name
|
|
74
|
-
main_sequence.insert_step(step, main_sequence.get_num_steps(), StepGroup.Main)
|
|
77
|
+
main_sequence.insert_step(step, index=main_sequence.get_num_steps(), group=StepGroup.Main)
|
|
75
78
|
return main_sequence
|
|
76
79
|
|
|
77
80
|
|
|
@@ -83,10 +86,10 @@ def main() -> None:
|
|
|
83
86
|
violations = 0
|
|
84
87
|
for i in range(main_sequence.get_num_steps()):
|
|
85
88
|
step = main_sequence.get_step(i)
|
|
86
|
-
context = _OfflineStepContext(step)
|
|
89
|
+
context = _OfflineStepContext(analyzed_object=step)
|
|
87
90
|
# The analyzer would pass a real AnalysisContext; the offline stand-in
|
|
88
91
|
# provides the same surface the rule uses.
|
|
89
|
-
check_step_name_length.invoke(cast("AnalysisContext", context))
|
|
92
|
+
check_step_name_length.invoke(context=cast(typ="AnalysisContext", val=context))
|
|
90
93
|
status = "VIOLATION" if context.findings else "ok"
|
|
91
94
|
print(f" [{status:9}] {step.name!r} (length {len(step.name)})")
|
|
92
95
|
for finding in context.findings:
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"""Create and evolve custom TestStand data types in a sequence file.
|
|
2
|
+
|
|
3
|
+
A custom data type can be a Number, Enumeration, String, Boolean, Object
|
|
4
|
+
Reference, Container, or an n-dimensional array of those. This example registers
|
|
5
|
+
two of them in a sequence file and then evolves one, which is the part that
|
|
6
|
+
matters in practice: a type ships, instances of it exist, and later you need to
|
|
7
|
+
change the type without breaking those instances.
|
|
8
|
+
|
|
9
|
+
It builds:
|
|
10
|
+
- DigitalMultimeter, a container type (Resolution, AutoZero, Mode, Range).
|
|
11
|
+
- Coupling, a strict enumeration (AC = 0, DC = 1). Strict means a variable of
|
|
12
|
+
this type only accepts the defined enumerators, which is the default in the
|
|
13
|
+
sequence editor, so the example sets it explicitly.
|
|
14
|
+
|
|
15
|
+
Then it evolves Coupling: prints the current TypeVersion, adds a GND enumerator,
|
|
16
|
+
and bumps the minor version (0.0.0.0 to 0.1.0.0). TestStand type versions are
|
|
17
|
+
"major.minor.revision.build". A bump of the build field (the lowest) signals an
|
|
18
|
+
automatic conversion that updates instances silently; bumping a higher field
|
|
19
|
+
like minor marks a deliberate change. UpdateEnumerators updates every loaded
|
|
20
|
+
instance of the type, so the InputCoupling variable created here reflects the
|
|
21
|
+
new enumerator immediately.
|
|
22
|
+
"""
|
|
23
|
+
|
|
24
|
+
from __future__ import annotations
|
|
25
|
+
|
|
26
|
+
import tempfile
|
|
27
|
+
import uuid
|
|
28
|
+
from pathlib import Path
|
|
29
|
+
|
|
30
|
+
from py_teststand import Engine, PropertyOption, PropValType, TypeCategory, TypeUsageList
|
|
31
|
+
from py_teststand.property.property_object import PropertyObject
|
|
32
|
+
|
|
33
|
+
ROOT_TEMP_DIR: Path = Path(tempfile.gettempdir()) / "py-teststand"
|
|
34
|
+
INSERT_IF_MISSING = int(PropertyOption.InsertIfMissing)
|
|
35
|
+
COERCE_TO_NUMBER = int(PropertyOption.CoerceToNumber)
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
def _build_digital_multimeter_type(engine: Engine) -> PropertyObject:
|
|
39
|
+
"""Build the DigitalMultimeter container type; field defaults define field types."""
|
|
40
|
+
data_type: PropertyObject = engine.new_property_object(
|
|
41
|
+
value_type=PropValType.Container, as_array=False, type_name_param="", options=0
|
|
42
|
+
)
|
|
43
|
+
data_type.set_val_number(lookup_string="Resolution", options=INSERT_IF_MISSING, value=6.5)
|
|
44
|
+
data_type.set_val_boolean(lookup_string="AutoZero", options=INSERT_IF_MISSING, value=False)
|
|
45
|
+
data_type.set_val_string(lookup_string="Mode", options=INSERT_IF_MISSING, value="Voltage")
|
|
46
|
+
data_type.set_val_number(lookup_string="Range", options=INSERT_IF_MISSING, value=100.0)
|
|
47
|
+
data_type.name = "DigitalMultimeter"
|
|
48
|
+
return data_type
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
def _enumerator_array(
|
|
52
|
+
engine: Engine, named_values: list[tuple[str, float]], *, strict: bool
|
|
53
|
+
) -> PropertyObject:
|
|
54
|
+
"""Build the array UpdateEnumerators expects: one container per enumerator.
|
|
55
|
+
|
|
56
|
+
Each element carries EnumeratorName and EnumeratorValue. IsStrict rides along
|
|
57
|
+
as a boolean attribute on the array, not as a sub-property.
|
|
58
|
+
"""
|
|
59
|
+
array: PropertyObject = engine.new_property_object(PropValType.Container, True, "", 0)
|
|
60
|
+
array.set_num_elements(len(named_values), 0)
|
|
61
|
+
for index, (name, value) in enumerate(named_values):
|
|
62
|
+
element = array.get_property_object_by_offset(index, 0)
|
|
63
|
+
assert element is not None
|
|
64
|
+
element.set_val_string("EnumeratorName", INSERT_IF_MISSING, name)
|
|
65
|
+
element.set_val_number("EnumeratorValue", INSERT_IF_MISSING, value)
|
|
66
|
+
array.attributes.set_val_boolean("TestStand.Enum.IsStrict", INSERT_IF_MISSING, strict)
|
|
67
|
+
return array
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def _register_enum(
|
|
71
|
+
engine: Engine,
|
|
72
|
+
type_usage_list: TypeUsageList,
|
|
73
|
+
name: str,
|
|
74
|
+
named_values: list[tuple[str, float]],
|
|
75
|
+
*,
|
|
76
|
+
strict: bool,
|
|
77
|
+
) -> PropertyObject:
|
|
78
|
+
"""Register an empty enumeration type, then set its enumerators on the root definition."""
|
|
79
|
+
enum_type = engine.new_property_object(PropValType.Enum, False, "", 0)
|
|
80
|
+
enum_type.name = name
|
|
81
|
+
type_usage_list.insert_type(enum_type, type_usage_list.num_types, TypeCategory.CustomDataTypes)
|
|
82
|
+
# UpdateEnumerators only works on the registered root definition, not the loose object.
|
|
83
|
+
definition = type_usage_list.get_type_definition(type_usage_list.get_type_index(name))
|
|
84
|
+
definition.update_enumerators(_enumerator_array(engine, named_values, strict=strict))
|
|
85
|
+
return definition
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def _print_enumerators(definition: PropertyObject) -> None:
|
|
89
|
+
enumerators = definition.enumerators
|
|
90
|
+
assert enumerators is not None
|
|
91
|
+
strict = enumerators.attributes.get_val_boolean("TestStand.Enum.IsStrict", 0)
|
|
92
|
+
print(f" {definition.name} v{definition.type_version} (strict={strict}):")
|
|
93
|
+
for index in range(enumerators.get_num_elements()):
|
|
94
|
+
element = enumerators.get_property_object_by_offset(index, 0)
|
|
95
|
+
assert element is not None
|
|
96
|
+
value = int(element.get_val_number("", COERCE_TO_NUMBER))
|
|
97
|
+
print(f" {element.get_value_display_name('', 0)} -> {value}")
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def main() -> None:
|
|
101
|
+
run_dir = ROOT_TEMP_DIR / uuid.uuid4().hex
|
|
102
|
+
run_dir.mkdir(parents=True, exist_ok=True)
|
|
103
|
+
sequence_path = run_dir / "with_custom_types.seq"
|
|
104
|
+
|
|
105
|
+
with Engine() as engine:
|
|
106
|
+
sequence_file = engine.new_sequence_file()
|
|
107
|
+
property_object_file = sequence_file.as_property_object_file()
|
|
108
|
+
type_usage_list = property_object_file.type_usage_list
|
|
109
|
+
|
|
110
|
+
type_usage_list.insert_type(
|
|
111
|
+
_build_digital_multimeter_type(engine),
|
|
112
|
+
type_usage_list.num_types,
|
|
113
|
+
TypeCategory.CustomDataTypes,
|
|
114
|
+
)
|
|
115
|
+
coupling = _register_enum(
|
|
116
|
+
engine, type_usage_list, "Coupling", [("AC", 0), ("DC", 1)], strict=True
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
# A variable typed as the enum, so the type change below has an instance to update.
|
|
120
|
+
main_sequence = sequence_file.get_sequence_by_name("MainSequence")
|
|
121
|
+
main_sequence.locals.new_sub_property(
|
|
122
|
+
"InputCoupling", PropValType.NamedType, False, "Coupling", INSERT_IF_MISSING
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
property_object_file.inc_change_count()
|
|
126
|
+
sequence_file.save(str(sequence_path))
|
|
127
|
+
print("Registered custom data types:")
|
|
128
|
+
_print_enumerators(coupling)
|
|
129
|
+
|
|
130
|
+
# Evolve the type: read the current version, add an enumerator, bump minor.
|
|
131
|
+
print(f"\nCoupling version before update: {coupling.type_version}")
|
|
132
|
+
coupling.update_enumerators(
|
|
133
|
+
_enumerator_array(engine, [("AC", 0), ("DC", 1), ("GND", 2)], strict=True)
|
|
134
|
+
)
|
|
135
|
+
major, minor, *_rest = (coupling.type_version + ".0.0.0").split(".")
|
|
136
|
+
coupling.type_version = f"{int(major)}.{int(minor) + 1}.0.0"
|
|
137
|
+
print(f"Coupling version after update: {coupling.type_version}")
|
|
138
|
+
|
|
139
|
+
property_object_file.inc_change_count()
|
|
140
|
+
sequence_file.save(path=str(object=sequence_path))
|
|
141
|
+
|
|
142
|
+
print("\nCoupling now defines (the InputCoupling variable reflects this):")
|
|
143
|
+
_print_enumerators(definition=coupling)
|
|
144
|
+
print(f"\nSaved sequence file with the evolved types to {sequence_path}")
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
if __name__ == "__main__":
|
|
148
|
+
main()
|
|
@@ -22,15 +22,18 @@ records Passed or Failed, which we read from each entry in the ResultList.
|
|
|
22
22
|
from __future__ import annotations
|
|
23
23
|
|
|
24
24
|
from py_teststand import AdapterKeyName, Engine, StepGroup
|
|
25
|
+
from py_teststand.sequence.sequence import Sequence
|
|
25
26
|
|
|
26
27
|
# (name, measurement expression, low limit, high limit)
|
|
27
|
-
TESTS = [
|
|
28
|
+
TESTS: list[tuple[str, str, float, float]] = [
|
|
28
29
|
("Supply Voltage", "5.0", 4.75, 5.25),
|
|
29
30
|
("Bias Current", "9.0", 1.0, 8.0),
|
|
30
31
|
]
|
|
31
32
|
|
|
32
33
|
|
|
33
|
-
def _add_numeric_limit_test(
|
|
34
|
+
def _add_numeric_limit_test(
|
|
35
|
+
engine: Engine, sequence: Sequence, name: str, data_source: str, low: float, high: float
|
|
36
|
+
) -> None:
|
|
34
37
|
"""Append a runnable NumericLimitTest to a sequence's Main step group."""
|
|
35
38
|
step = engine.new_step(AdapterKeyName.NoneAdapterKeyName, "NumericLimitTest")
|
|
36
39
|
step.name = name
|
|
@@ -9,8 +9,8 @@ EXAMPLES_DIR: Path = Path(__file__).resolve().parent
|
|
|
9
9
|
# Script name, and what it does / how it relates to the rest.
|
|
10
10
|
EXAMPLES: list[tuple[str, str]] = [
|
|
11
11
|
("station_options_update", "Set station and debug options. Start here."),
|
|
12
|
-
("
|
|
13
|
-
("
|
|
12
|
+
("variables_manage", "Create variables across scopes, then retype and remove one."),
|
|
13
|
+
("data_type_manage", "Create and evolve custom data types (container + strict enum)."),
|
|
14
14
|
("property_object_serialize", "Dump variables and typedefs to JSON and back."),
|
|
15
15
|
("sequence_build", "Build a sequence file with steps and save it."),
|
|
16
16
|
("step_insert", "Insert a step into the sequence sequence_build made."),
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
TestStand keeps variables, parameters, and custom data types as PropertyObjects: a
|
|
4
4
|
tree of named sub-properties. A sub-property can be a scalar (number, string,
|
|
5
5
|
boolean), a nested container (including a typedef such as the DigitalMultimeter
|
|
6
|
-
type from
|
|
6
|
+
type from data_type_manage.py), or an array of any of those.
|
|
7
7
|
|
|
8
8
|
property_object_to_dict walks that tree into an ordinary dict; dict_to_property_object
|
|
9
9
|
rebuilds an equivalent PropertyObject. The walk asks PropertyObject.get_type what
|
|
@@ -24,60 +24,64 @@ import uuid
|
|
|
24
24
|
from pathlib import Path
|
|
25
25
|
|
|
26
26
|
from py_teststand import Engine, StepGroup
|
|
27
|
+
from py_teststand.property.property_object import PropertyObject
|
|
28
|
+
from py_teststand.sequence.sequence import Sequence
|
|
29
|
+
from py_teststand.sequence.sequence_file import SequenceFile
|
|
30
|
+
from py_teststand.sequence.step import Step
|
|
27
31
|
|
|
28
|
-
ROOT_TEMP_DIR = Path(tempfile.gettempdir()) / "py-teststand"
|
|
29
|
-
LATEST_POINTER = ROOT_TEMP_DIR / "latest_sequence.txt"
|
|
32
|
+
ROOT_TEMP_DIR: Path = Path(tempfile.gettempdir()) / "py-teststand"
|
|
33
|
+
LATEST_POINTER: Path = ROOT_TEMP_DIR / "latest_sequence.txt"
|
|
30
34
|
|
|
31
35
|
|
|
32
36
|
def main() -> None:
|
|
33
|
-
run_dir = ROOT_TEMP_DIR / uuid.uuid4().hex
|
|
37
|
+
run_dir: Path = ROOT_TEMP_DIR / uuid.uuid4().hex
|
|
34
38
|
run_dir.mkdir(parents=True, exist_ok=True)
|
|
35
|
-
output_path = run_dir / "test_sequence.seq"
|
|
39
|
+
output_path: Path = run_dir / "test_sequence.seq"
|
|
36
40
|
|
|
37
41
|
with Engine() as engine:
|
|
38
|
-
sequence_file = engine.new_sequence_file()
|
|
39
|
-
main_sequence = sequence_file.get_sequence_by_name("MainSequence")
|
|
42
|
+
sequence_file: SequenceFile = engine.new_sequence_file()
|
|
43
|
+
main_sequence: Sequence = sequence_file.get_sequence_by_name("MainSequence")
|
|
40
44
|
|
|
41
|
-
first_step = engine.new_step(adapter_key_name="", step_type_name="NumericLimitTest")
|
|
45
|
+
first_step: Step = engine.new_step(adapter_key_name="", step_type_name="NumericLimitTest")
|
|
42
46
|
first_step.name = "Temperature Check"
|
|
43
47
|
first_step.precondition = "Locals.TempSensorPresent == True"
|
|
44
48
|
first_step.record_result = True
|
|
45
49
|
|
|
46
|
-
first_step_property_object = first_step.as_property_object()
|
|
50
|
+
first_step_property_object: PropertyObject = first_step.as_property_object()
|
|
47
51
|
first_step_property_object["Limits.High"] = 85.0
|
|
48
52
|
first_step_property_object["Limits.Low"] = 15.0
|
|
49
53
|
|
|
50
|
-
main_sequence.insert_step(first_step, 0, StepGroup.Main)
|
|
54
|
+
main_sequence.insert_step(first_step, index=0, group=StepGroup.Main)
|
|
51
55
|
|
|
52
|
-
second_step = engine.new_step(adapter_key_name="", step_type_name="NumericLimitTest")
|
|
56
|
+
second_step: Step = engine.new_step(adapter_key_name="", step_type_name="NumericLimitTest")
|
|
53
57
|
second_step.name = "Voltage Monitor"
|
|
54
58
|
second_step.precondition = "Locals.DUTPowered == True"
|
|
55
59
|
|
|
56
|
-
second_step_property_object = second_step.as_property_object()
|
|
60
|
+
second_step_property_object: PropertyObject = second_step.as_property_object()
|
|
57
61
|
second_step_property_object["Limits.High"] = 5.25
|
|
58
62
|
second_step_property_object["Limits.Low"] = 4.75
|
|
59
63
|
|
|
60
|
-
main_sequence.insert_step(second_step, 1, StepGroup.Main)
|
|
64
|
+
main_sequence.insert_step(second_step, index=1, group=StepGroup.Main)
|
|
61
65
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
sequence_file.insert_sequence(
|
|
66
|
+
subsequence: Sequence = engine.new_sequence()
|
|
67
|
+
subsequence.name = "CustomSubsequence"
|
|
68
|
+
sequence_file.insert_sequence(sequence=subsequence)
|
|
65
69
|
|
|
66
|
-
init_step = engine.new_step(adapter_key_name="", step_type_name="Action")
|
|
70
|
+
init_step: Step = engine.new_step(adapter_key_name="", step_type_name="Action")
|
|
67
71
|
init_step.name = "Initialize Hardware"
|
|
68
|
-
|
|
72
|
+
subsequence.insert_step(init_step, index=0, group=StepGroup.Main)
|
|
69
73
|
|
|
70
74
|
print(f"Created sequence with {main_sequence.get_num_steps()} steps:")
|
|
71
75
|
for i in range(main_sequence.get_num_steps()):
|
|
72
|
-
s = main_sequence.get_step(i)
|
|
73
|
-
po_s = s.as_property_object()
|
|
76
|
+
s: Step = main_sequence.get_step(index=i)
|
|
77
|
+
po_s: PropertyObject = s.as_property_object()
|
|
74
78
|
|
|
75
79
|
print(f" [{i}] {s.name}")
|
|
76
80
|
print(f" Limits: Low={po_s['Limits.Low']}, High={po_s['Limits.High']}")
|
|
77
81
|
print(f" Precond: {s.precondition}")
|
|
78
82
|
|
|
79
|
-
sequence_file.save(str(output_path))
|
|
80
|
-
LATEST_POINTER.write_text(str(output_path), encoding="utf-8")
|
|
83
|
+
sequence_file.save(path=str(object=output_path))
|
|
84
|
+
LATEST_POINTER.write_text(data=str(object=output_path), encoding="utf-8")
|
|
81
85
|
print(f"\nSaved sequence file to {output_path}")
|
|
82
86
|
print(f"Pointer written to {LATEST_POINTER}")
|
|
83
87
|
|
|
@@ -25,7 +25,7 @@ from __future__ import annotations
|
|
|
25
25
|
import tempfile
|
|
26
26
|
from pathlib import Path
|
|
27
27
|
|
|
28
|
-
from py_teststand import AdapterKeyName, Engine, Error, RunMode, StepGroup
|
|
28
|
+
from py_teststand import AdapterKeyName, Engine, Error, RunMode, Step, StepGroup
|
|
29
29
|
|
|
30
30
|
|
|
31
31
|
def _new_vi_call_step(
|
|
@@ -35,7 +35,7 @@ def _new_vi_call_step(
|
|
|
35
35
|
project_path: str = "",
|
|
36
36
|
icon: str = "",
|
|
37
37
|
run_mode: RunMode = RunMode.Normal,
|
|
38
|
-
):
|
|
38
|
+
) -> Step:
|
|
39
39
|
"""Build a configured LabVIEW VI-call step ready for insertion."""
|
|
40
40
|
step = engine.new_step(
|
|
41
41
|
adapter_key_name=AdapterKeyName.LVAdapterKeyName,
|
|
@@ -23,7 +23,8 @@ plus the execution id that identifies who posted.
|
|
|
23
23
|
|
|
24
24
|
from __future__ import annotations
|
|
25
25
|
|
|
26
|
-
from py_teststand import AdapterKeyName, Engine, StepGroup, UIMessageCode
|
|
26
|
+
from py_teststand import AdapterKeyName, Engine, StepGroup, UIMessage, UIMessageCode
|
|
27
|
+
from py_teststand.sequence.sequence import Sequence
|
|
27
28
|
|
|
28
29
|
STAGE_MESSAGE = int(UIMessageCode.UserMessageBase) + 1
|
|
29
30
|
PROGRESS_MESSAGE = int(UIMessageCode.UserMessageBase) + 2
|
|
@@ -37,7 +38,7 @@ POST_FOR_THREAD = (
|
|
|
37
38
|
)
|
|
38
39
|
|
|
39
40
|
|
|
40
|
-
def _add_statement_step(engine, sequence, name, expression):
|
|
41
|
+
def _add_statement_step(engine: Engine, sequence: Sequence, name: str, expression: str) -> None:
|
|
41
42
|
"""Append a Statement step whose expression runs when the step executes."""
|
|
42
43
|
step = engine.new_step(AdapterKeyName.NoneAdapterKeyName, "Statement")
|
|
43
44
|
step.name = name
|
|
@@ -48,7 +49,7 @@ def _add_statement_step(engine, sequence, name, expression):
|
|
|
48
49
|
def main() -> None:
|
|
49
50
|
received = []
|
|
50
51
|
|
|
51
|
-
def on_stage(message) -> None:
|
|
52
|
+
def on_stage(message: UIMessage) -> None:
|
|
52
53
|
execution = message.execution
|
|
53
54
|
received.append(
|
|
54
55
|
f"stage message (execution {execution.id if execution else '?'}): "
|
|
@@ -56,7 +57,7 @@ def main() -> None:
|
|
|
56
57
|
f"synchronous={message.is_synchronous}"
|
|
57
58
|
)
|
|
58
59
|
|
|
59
|
-
def on_progress(message) -> None:
|
|
60
|
+
def on_progress(message: UIMessage) -> None:
|
|
60
61
|
received.append(
|
|
61
62
|
f"progress message (thread-posted): "
|
|
62
63
|
f"numeric={message.numeric_data} string={message.string_data!r} "
|