ophyd-async 0.8.0a6__tar.gz → 0.9.0__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.
Files changed (296) hide show
  1. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.copier-answers.yml +1 -1
  2. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.devcontainer/devcontainer.json +4 -4
  3. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/CONTRIBUTING.md +1 -1
  4. ophyd_async-0.9.0/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +10 -0
  5. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/pages/make_switcher.py +1 -1
  6. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_test.yml +1 -0
  7. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/ci.yml +1 -1
  8. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.gitignore +3 -1
  9. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.pre-commit-config.yaml +8 -0
  10. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/PKG-INFO +4 -2
  11. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/examples/epics_demo.py +7 -7
  12. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/examples/tango_demo.py +5 -5
  13. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0009-procedural-vs-declarative-devices.md +1 -1
  14. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/event-loop-choice.rst +8 -8
  15. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/compound-devices.rst +2 -2
  16. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/make-a-simple-device.rst +4 -4
  17. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/write-tests-for-devices.rst +6 -6
  18. ophyd_async-0.9.0/docs/images/set_and_wait_for_other_value.svg +2 -0
  19. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/tutorials/using-existing-devices.rst +2 -2
  20. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/pyproject.toml +34 -4
  21. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/_version.py +2 -2
  22. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/__init__.py +15 -46
  23. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_detector.py +68 -44
  24. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_device.py +120 -79
  25. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_device_filler.py +17 -8
  26. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_flyer.py +2 -2
  27. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_protocol.py +0 -28
  28. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_readable.py +30 -23
  29. ophyd_async-0.9.0/src/ophyd_async/core/_settings.py +104 -0
  30. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_signal.py +91 -151
  31. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_signal_backend.py +4 -1
  32. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_soft_signal_backend.py +2 -1
  33. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_table.py +18 -10
  34. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_utils.py +30 -5
  35. ophyd_async-0.9.0/src/ophyd_async/core/_yaml_settings.py +64 -0
  36. ophyd_async-0.9.0/src/ophyd_async/epics/adandor/__init__.py +9 -0
  37. ophyd_async-0.9.0/src/ophyd_async/epics/adandor/_andor.py +45 -0
  38. ophyd_async-0.9.0/src/ophyd_async/epics/adandor/_andor_controller.py +49 -0
  39. ophyd_async-0.9.0/src/ophyd_async/epics/adandor/_andor_io.py +36 -0
  40. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adaravis/__init__.py +3 -1
  41. ophyd_async-0.9.0/src/ophyd_async/epics/adaravis/_aravis.py +47 -0
  42. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adaravis/_aravis_controller.py +21 -30
  43. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adaravis/_aravis_io.py +4 -4
  44. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/__init__.py +15 -8
  45. ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_core_detector.py +41 -0
  46. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/_core_io.py +56 -31
  47. ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_core_logic.py +121 -0
  48. ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_core_writer.py +219 -0
  49. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/_hdf_writer.py +33 -59
  50. ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_jpeg_writer.py +26 -0
  51. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/_single_trigger.py +5 -4
  52. ophyd_async-0.9.0/src/ophyd_async/epics/adcore/_tiff_writer.py +26 -0
  53. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adcore/_utils.py +37 -36
  54. ophyd_async-0.9.0/src/ophyd_async/epics/adkinetix/_kinetix.py +49 -0
  55. ophyd_async-0.9.0/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +42 -0
  56. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adkinetix/_kinetix_io.py +7 -7
  57. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adpilatus/__init__.py +2 -2
  58. ophyd_async-0.9.0/src/ophyd_async/epics/adpilatus/_pilatus.py +46 -0
  59. ophyd_async-0.9.0/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +101 -0
  60. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adpilatus/_pilatus_io.py +5 -5
  61. ophyd_async-0.9.0/src/ophyd_async/epics/adsimdetector/__init__.py +7 -0
  62. ophyd_async-0.9.0/src/ophyd_async/epics/adsimdetector/_sim.py +51 -0
  63. ophyd_async-0.9.0/src/ophyd_async/epics/advimba/_vimba.py +43 -0
  64. ophyd_async-0.9.0/src/ophyd_async/epics/advimba/_vimba_controller.py +52 -0
  65. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/advimba/_vimba_io.py +23 -23
  66. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_aioca.py +52 -21
  67. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_p4p.py +59 -16
  68. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_pvi_connector.py +4 -2
  69. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_signal.py +9 -2
  70. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_util.py +10 -1
  71. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/_eiger_controller.py +4 -4
  72. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/_eiger_io.py +3 -3
  73. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/motor.py +26 -15
  74. ophyd_async-0.9.0/src/ophyd_async/epics/sim/_ioc.py +29 -0
  75. {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/_mover.py +12 -6
  76. {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/_sensor.py +2 -2
  77. ophyd_async-0.9.0/src/ophyd_async/epics/testing/__init__.py +24 -0
  78. ophyd_async-0.9.0/src/ophyd_async/epics/testing/_example_ioc.py +91 -0
  79. ophyd_async-0.9.0/src/ophyd_async/epics/testing/_utils.py +50 -0
  80. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/testing/test_records.db +22 -0
  81. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/core.py +2 -2
  82. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/__init__.py +0 -2
  83. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_block.py +9 -9
  84. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_control.py +9 -4
  85. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_hdf_panda.py +7 -2
  86. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_table.py +4 -1
  87. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_trigger.py +7 -7
  88. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/plan_stubs/__init__.py +14 -0
  89. ophyd_async-0.9.0/src/ophyd_async/plan_stubs/_ensure_connected.py +27 -0
  90. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/plan_stubs/_fly.py +2 -2
  91. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/plan_stubs/_nd_attributes.py +7 -5
  92. ophyd_async-0.9.0/src/ophyd_async/plan_stubs/_panda.py +13 -0
  93. ophyd_async-0.9.0/src/ophyd_async/plan_stubs/_settings.py +125 -0
  94. ophyd_async-0.9.0/src/ophyd_async/plan_stubs/_wait_for_awaitable.py +13 -0
  95. {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/_pattern_detector_controller.py +9 -2
  96. {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/_pattern_generator.py +13 -6
  97. {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_sim_motor.py +34 -32
  98. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/_signal.py +3 -1
  99. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/_tango_transport.py +13 -15
  100. {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_mover.py +5 -2
  101. ophyd_async-0.9.0/src/ophyd_async/testing/__init__.py +52 -0
  102. ophyd_async-0.9.0/src/ophyd_async/testing/__pytest_assert_rewrite.py +4 -0
  103. ophyd_async-0.9.0/src/ophyd_async/testing/_assert.py +176 -0
  104. {ophyd_async-0.8.0a6/src/ophyd_async/core → ophyd_async-0.9.0/src/ophyd_async/testing}/_mock_signal_utils.py +15 -11
  105. ophyd_async-0.9.0/src/ophyd_async/testing/_one_of_everything.py +126 -0
  106. ophyd_async-0.9.0/src/ophyd_async/testing/_wait_for_pending.py +22 -0
  107. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/PKG-INFO +4 -2
  108. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/SOURCES.txt +47 -31
  109. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/requires.txt +1 -0
  110. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/system_tests/epics/eiger/test_eiger_system.py +4 -4
  111. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/conftest.py +67 -12
  112. ophyd_async-0.8.0a6/tests/core/test_device_collector.py → ophyd_async-0.9.0/tests/core/test_auto_init_devices.py +27 -17
  113. ophyd_async-0.9.0/tests/core/test_detector.py +120 -0
  114. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_device.py +44 -6
  115. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_flyer.py +32 -37
  116. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_mock_signal_backend.py +11 -10
  117. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_observe.py +26 -7
  118. ophyd_async-0.9.0/tests/core/test_protocol.py +18 -0
  119. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_readable.py +30 -11
  120. ophyd_async-0.9.0/tests/core/test_signal.py +903 -0
  121. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_soft_signal_backend.py +24 -8
  122. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_subset_enum.py +6 -6
  123. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_table.py +25 -1
  124. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_utils.py +7 -7
  125. ophyd_async-0.9.0/tests/epics/adandor/test_andor.py +123 -0
  126. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adaravis/test_aravis.py +35 -40
  127. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adcore/test_drivers.py +31 -33
  128. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adcore/test_scans.py +27 -18
  129. ophyd_async-0.9.0/tests/epics/adcore/test_single_trigger.py +60 -0
  130. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adcore/test_writers.py +49 -16
  131. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adkinetix/test_kinetix.py +19 -18
  132. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adpilatus/test_pilatus.py +47 -40
  133. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/adsimdetector/test_sim.py +67 -46
  134. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/advimba/test_vimba.py +37 -33
  135. ophyd_async-0.9.0/tests/epics/conftest.py +69 -0
  136. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/eiger/test_eiger_controller.py +3 -5
  137. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/eiger/test_eiger_detector.py +5 -4
  138. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/eiger/test_odin_io.py +3 -2
  139. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/pvi/test_pvi.py +2 -2
  140. ophyd_async-0.9.0/tests/epics/signal/test_signals.py +737 -0
  141. ophyd_async-0.9.0/tests/epics/signal/test_yaml_save_ca.yaml +23 -0
  142. ophyd_async-0.9.0/tests/epics/signal/test_yaml_save_pva.yaml +42 -0
  143. ophyd_async-0.8.0a6/tests/epics/demo/test_demo.py → ophyd_async-0.9.0/tests/epics/sim/test_epics_sim.py +51 -47
  144. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/test_motor.py +56 -30
  145. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_hdf_panda.py +9 -16
  146. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_panda_connect.py +6 -4
  147. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_panda_control.py +6 -6
  148. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_panda_utils.py +16 -14
  149. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_seq_table.py +1 -2
  150. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_trigger.py +4 -3
  151. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/test_writer.py +5 -6
  152. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/plan_stubs/test_fly.py +11 -9
  153. ophyd_async-0.9.0/tests/plan_stubs/test_settings.py +95 -0
  154. ophyd_async-0.9.0/tests/plan_stubs/test_setup.py +25 -0
  155. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/sim/conftest.py +1 -1
  156. ophyd_async-0.9.0/tests/sim/test_pattern_generator.py +67 -0
  157. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/sim/test_sim_detector.py +25 -12
  158. ophyd_async-0.9.0/tests/sim/test_sim_motor.py +93 -0
  159. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/sim/test_sim_writer.py +3 -3
  160. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/sim/test_streaming_plan.py +5 -4
  161. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/tango/test_base_device.py +11 -11
  162. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/tango/test_tango_signals.py +214 -355
  163. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/tango/test_tango_transport.py +4 -2
  164. ophyd_async-0.9.0/tests/test_data/test_yaml_save.yaml +119 -0
  165. ophyd_async-0.8.0a6/.github/PULL_REQUEST_TEMPLATE/pull_request_template.md +0 -8
  166. ophyd_async-0.8.0a6/.mailmap +0 -18
  167. ophyd_async-0.8.0a6/docs/images/set_and_wait_for_other_value.svg +0 -10
  168. ophyd_async-0.8.0a6/src/ophyd_async/core/_device_save_loader.py +0 -274
  169. ophyd_async-0.8.0a6/src/ophyd_async/epics/adaravis/_aravis.py +0 -61
  170. ophyd_async-0.8.0a6/src/ophyd_async/epics/adcore/_core_logic.py +0 -108
  171. ophyd_async-0.8.0a6/src/ophyd_async/epics/adkinetix/_kinetix.py +0 -44
  172. ophyd_async-0.8.0a6/src/ophyd_async/epics/adkinetix/_kinetix_controller.py +0 -54
  173. ophyd_async-0.8.0a6/src/ophyd_async/epics/adpilatus/_pilatus.py +0 -58
  174. ophyd_async-0.8.0a6/src/ophyd_async/epics/adpilatus/_pilatus_controller.py +0 -79
  175. ophyd_async-0.8.0a6/src/ophyd_async/epics/adsimdetector/__init__.py +0 -7
  176. ophyd_async-0.8.0a6/src/ophyd_async/epics/adsimdetector/_sim.py +0 -35
  177. ophyd_async-0.8.0a6/src/ophyd_async/epics/adsimdetector/_sim_controller.py +0 -51
  178. ophyd_async-0.8.0a6/src/ophyd_async/epics/advimba/_vimba.py +0 -43
  179. ophyd_async-0.8.0a6/src/ophyd_async/epics/advimba/_vimba_controller.py +0 -66
  180. ophyd_async-0.8.0a6/src/ophyd_async/epics/testing/__init__.py +0 -24
  181. ophyd_async-0.8.0a6/src/ophyd_async/epics/testing/_example_ioc.py +0 -105
  182. ophyd_async-0.8.0a6/src/ophyd_async/epics/testing/_utils.py +0 -78
  183. ophyd_async-0.8.0a6/src/ophyd_async/fastcs/panda/_utils.py +0 -16
  184. ophyd_async-0.8.0a6/src/ophyd_async/plan_stubs/_ensure_connected.py +0 -33
  185. ophyd_async-0.8.0a6/src/ophyd_async/tango/__init__.py +0 -0
  186. ophyd_async-0.8.0a6/src/ophyd_async.egg-info/entry_points.txt +0 -2
  187. ophyd_async-0.8.0a6/tests/core/test_device_save_loader.py +0 -317
  188. ophyd_async-0.8.0a6/tests/core/test_protocol.py +0 -33
  189. ophyd_async-0.8.0a6/tests/core/test_signal.py +0 -376
  190. ophyd_async-0.8.0a6/tests/epics/adcore/test_single_trigger.py +0 -52
  191. ophyd_async-0.8.0a6/tests/epics/conftest.py +0 -59
  192. ophyd_async-0.8.0a6/tests/epics/signal/test_signals.py +0 -934
  193. ophyd_async-0.8.0a6/tests/sim/__init__.py +0 -0
  194. ophyd_async-0.8.0a6/tests/sim/demo/__init__.py +0 -0
  195. ophyd_async-0.8.0a6/tests/sim/demo/test_sim_motor.py +0 -54
  196. ophyd_async-0.8.0a6/tests/sim/test_pattern_generator.py +0 -34
  197. ophyd_async-0.8.0a6/tests/test_data/test_yaml_save.yml +0 -40
  198. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.codecov.yml +0 -0
  199. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.git-blame-ignore-revs +0 -0
  200. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  201. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/ISSUE_TEMPLATE/issue.md +0 -0
  202. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/actions/install_requirements/action.yml +0 -0
  203. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/dependabot.yml +0 -0
  204. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/pages/index.html +0 -0
  205. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_check.yml +0 -0
  206. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_dist.yml +0 -0
  207. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_docs.yml +0 -0
  208. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_pypi.yml +0 -0
  209. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_release.yml +0 -0
  210. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/_tox.yml +0 -0
  211. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/.github/workflows/periodic.yml +0 -0
  212. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/Dockerfile +0 -0
  213. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/LICENSE +0 -0
  214. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/README.md +0 -0
  215. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/_api.rst +0 -0
  216. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/_templates/custom-module-template.rst +0 -0
  217. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/conf.py +0 -0
  218. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/examples/foo_detector.py +0 -0
  219. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0001-record-architecture-decisions.md +0 -0
  220. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0002-switched-to-python-copier-template.md +0 -0
  221. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0003-ophyd-async-migration.rst +0 -0
  222. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0004-repository-structure.rst +0 -0
  223. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0005-respect-black-line-length.rst +0 -0
  224. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0006-procedural-device-definitions.rst +0 -0
  225. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0007-subpackage-structure.md +0 -0
  226. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/0008-signal-types.md +0 -0
  227. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions/COPYME +0 -0
  228. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/decisions.md +0 -0
  229. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/design-goals.rst +0 -0
  230. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations/flyscanning.rst +0 -0
  231. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/explanations.md +0 -0
  232. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/genindex.rst +0 -0
  233. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/choose-interfaces-for-devices.md +0 -0
  234. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/contribute.md +0 -0
  235. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/make-a-standard-detector.rst +0 -0
  236. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to/use_set_and_wait_for_other_value.md +0 -0
  237. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/how-to.md +0 -0
  238. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/images/ophyd-async-logo.svg +0 -0
  239. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/images/ophyd-favicon.svg +0 -0
  240. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/index.md +0 -0
  241. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/reference.md +0 -0
  242. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/tutorials/installation.md +0 -0
  243. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/docs/tutorials.md +0 -0
  244. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/setup.cfg +0 -0
  245. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/__init__.py +0 -0
  246. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/__main__.py +0 -0
  247. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_hdf_dataset.py +0 -0
  248. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_log.py +0 -0
  249. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_mock_signal_backend.py +0 -0
  250. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_providers.py +0 -0
  251. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/core/_status.py +0 -0
  252. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/__init__.py +0 -0
  253. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/adkinetix/__init__.py +0 -0
  254. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/advimba/__init__.py +0 -0
  255. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/__init__.py +0 -0
  256. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_epics_connector.py +0 -0
  257. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/core/_epics_device.py +0 -0
  258. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/__init__.py +0 -0
  259. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/_eiger.py +0 -0
  260. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/eiger/_odin_io.py +0 -0
  261. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/signal.py +0 -0
  262. {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/__init__.py +0 -0
  263. {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/mover.db +0 -0
  264. {ophyd_async-0.8.0a6/src/ophyd_async/epics/demo → ophyd_async-0.9.0/src/ophyd_async/epics/sim}/sensor.db +0 -0
  265. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/epics/testing/test_records_pva.db +0 -0
  266. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/__init__.py +0 -0
  267. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/odin/__init__.py +0 -0
  268. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/fastcs/panda/_writer.py +0 -0
  269. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/py.typed +0 -0
  270. {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/__init__.py +0 -0
  271. {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/__init__.py +0 -0
  272. {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/_pattern_detector.py +0 -0
  273. {ophyd_async-0.8.0a6/src/ophyd_async/sim/demo → ophyd_async-0.9.0/src/ophyd_async/sim}/_pattern_detector/_pattern_detector_writer.py +0 -0
  274. {ophyd_async-0.8.0a6/src/ophyd_async/sim → ophyd_async-0.9.0/src/ophyd_async/tango}/__init__.py +0 -0
  275. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/__init__.py +0 -0
  276. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/_base_device.py +0 -0
  277. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async/tango/core/_tango_readable.py +0 -0
  278. {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/__init__.py +0 -0
  279. {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_counter.py +0 -0
  280. {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_detector.py +0 -0
  281. {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_tango/__init__.py +0 -0
  282. {ophyd_async-0.8.0a6/src/ophyd_async/tango/demo → ophyd_async-0.9.0/src/ophyd_async/tango/sim}/_tango/_servers.py +0 -0
  283. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/dependency_links.txt +0 -0
  284. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/src/ophyd_async.egg-info/top_level.txt +0 -0
  285. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/system_tests/epics/eiger/README.md +0 -0
  286. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/system_tests/epics/eiger/start_iocs_and_run_tests.sh +0 -0
  287. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_log.py +0 -0
  288. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_providers.py +0 -0
  289. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_status.py +0 -0
  290. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/core/test_watchable_async_status.py +0 -0
  291. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/signal/test_common.py +0 -0
  292. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/epics/test_areadetector_subclass_naming.py +0 -0
  293. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/fastcs/panda/db/panda.db +0 -0
  294. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/plan_stubs/test_ensure_connected.py +0 -0
  295. {ophyd_async-0.8.0a6/src/ophyd_async/sim/testing → ophyd_async-0.9.0/tests/sim}/__init__.py +0 -0
  296. {ophyd_async-0.8.0a6 → ophyd_async-0.9.0}/tests/test_cli.py +0 -0
@@ -1,5 +1,5 @@
1
1
  # Changes here will be overwritten by Copier
2
- _commit: 2.5.0
2
+ _commit: 2.6.0
3
3
  _src_path: gh:DiamondLightSource/python-copier-template
4
4
  author_email: tom.cobb@diamond.ac.uk
5
5
  author_name: Tom Cobb
@@ -37,11 +37,11 @@
37
37
  }
38
38
  },
39
39
  "features": {
40
- // Some default things like git config
41
- "ghcr.io/devcontainers/features/common-utils:2": {
42
- "upgradePackages": false
43
- }
40
+ // add in eternal history and other bash features
41
+ "ghcr.io/diamondlightsource/devcontainer-features/bash-config:1.0.0": {}
44
42
  },
43
+ // Create the config folder for the bash-config feature
44
+ "initializeCommand": "mkdir -p ${localEnv:HOME}/.config/bash-config",
45
45
  "runArgs": [
46
46
  // Allow the container to access the host X11 display and EPICS CA
47
47
  "--net=host",
@@ -24,4 +24,4 @@ It is recommended that developers use a [vscode devcontainer](https://code.visua
24
24
 
25
25
  This project was created using the [Diamond Light Source Copier Template](https://github.com/DiamondLightSource/python-copier-template) for Python projects.
26
26
 
27
- For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.5.0/how-to.html).
27
+ For more information on common tasks like setting up a developer environment, running the tests, and setting a pre-commit hook, see the template's [How-to guides](https://diamondlightsource.github.io/python-copier-template/2.6.0/how-to.html).
@@ -0,0 +1,10 @@
1
+ Fixes #ISSUE
2
+
3
+ ### Instructions to reviewer on how to test:
4
+ 1. Do thing x
5
+ 2. Confirm thing y happens
6
+
7
+ ### Checks for reviewer
8
+ - [ ] Would the PR title make sense to a user on a set of release notes
9
+ - [ ] If the change requires a bump in an IOC version, is that specified in a `##Changes` section in the body of the PR
10
+ - [ ] If the change requires a bump in the PandABlocks-ioc version, is the `ophyd_async.fastcs.panda._hdf_panda.MINIMUM_PANDA_IOC` variable updated to match
@@ -33,7 +33,7 @@ def get_versions(ref: str, add: str | None) -> list[str]:
33
33
  builds = set(get_branch_contents(ref))
34
34
  except CalledProcessError:
35
35
  builds = set()
36
- logging.warning(f"Cannot get {ref} contents")
36
+ logging.warning(f"Cannot get {ref} contents") # noqa: LOG015
37
37
 
38
38
  # Add and remove from the list of builds
39
39
  if add:
@@ -49,6 +49,7 @@ jobs:
49
49
  with:
50
50
  python-version: ${{ inputs.python-version }}
51
51
  pip-install: ".[dev]"
52
+
52
53
  - name: Run tests
53
54
  run: tox -e tests
54
55
 
@@ -21,7 +21,7 @@ jobs:
21
21
  strategy:
22
22
  matrix:
23
23
  runs-on: ["ubuntu-latest", "windows-latest"] # can add macos-latest
24
- python-version: ["3.10","3.11"] # 3.12 should be added when p4p is updated
24
+ python-version: ["3.10","3.11","3.12"]
25
25
  include:
26
26
  # Include one that runs in the dev environment
27
27
  - runs-on: "ubuntu-latest"
@@ -87,6 +87,8 @@ docs/savefig
87
87
  # generated version number
88
88
  ophyd_async/_version.py
89
89
 
90
-
91
90
  # ruff cache
92
91
  .ruff_cache/
92
+
93
+ # import linter cache
94
+ .import_linter_cache/
@@ -22,3 +22,11 @@ repos:
22
22
  entry: ruff format --force-exclude
23
23
  types: [python]
24
24
  require_serial: true
25
+
26
+ - id: import-contracts
27
+ name: Ensure import directionality
28
+ pass_filenames: false
29
+ language: system
30
+ entry: lint-imports
31
+ types: [python]
32
+ require_serial: false
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: ophyd-async
3
- Version: 0.8.0a6
3
+ Version: 0.9.0
4
4
  Summary: Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango
5
5
  Author-email: Tom Cobb <tom.cobb@diamond.ac.uk>
6
6
  License: BSD 3-Clause License
@@ -37,6 +37,7 @@ Classifier: Development Status :: 3 - Alpha
37
37
  Classifier: License :: OSI Approved :: BSD License
38
38
  Classifier: Programming Language :: Python :: 3.10
39
39
  Classifier: Programming Language :: Python :: 3.11
40
+ Classifier: Programming Language :: Python :: 3.12
40
41
  Requires-Python: >=3.10
41
42
  Description-Content-Type: text/markdown
42
43
  License-File: LICENSE
@@ -67,6 +68,7 @@ Requires-Dist: ophyd_async[tango]; extra == "dev"
67
68
  Requires-Dist: inflection; extra == "dev"
68
69
  Requires-Dist: ipython; extra == "dev"
69
70
  Requires-Dist: ipywidgets; extra == "dev"
71
+ Requires-Dist: import-linter; extra == "dev"
70
72
  Requires-Dist: matplotlib; extra == "dev"
71
73
  Requires-Dist: myst-parser; extra == "dev"
72
74
  Requires-Dist: numpydoc; extra == "dev"
@@ -7,8 +7,8 @@ from bluesky.plans import grid_scan # noqa
7
7
  from bluesky.utils import ProgressBarManager, register_transform
8
8
  from ophyd import Component, Device, EpicsSignal, EpicsSignalRO
9
9
 
10
- from ophyd_async.core import DeviceCollector
11
- from ophyd_async.epics import demo
10
+ from ophyd_async.core import init_devices
11
+ from ophyd_async.epics import sim
12
12
 
13
13
  # Create a run engine, with plotting, progressbar and transform
14
14
  RE = RunEngine({}, call_returns_result=True)
@@ -19,7 +19,7 @@ plt.ion()
19
19
  register_transform("RE", prefix="<")
20
20
 
21
21
  # Start IOC with demo pvs in subprocess
22
- pv_prefix = demo.start_ioc_subprocess()
22
+ pv_prefix = sim.start_ioc_subprocess()
23
23
 
24
24
 
25
25
  # Create ophyd devices
@@ -31,7 +31,7 @@ class OldSensor(Device):
31
31
  det_old = OldSensor(pv_prefix, name="det_old")
32
32
 
33
33
  # Create ophyd-async devices
34
- with DeviceCollector():
35
- det = demo.Sensor(pv_prefix)
36
- det_group = demo.SensorGroup(pv_prefix)
37
- samp = demo.SampleStage(pv_prefix)
34
+ with init_devices():
35
+ det = sim.Sensor(pv_prefix)
36
+ det_group = sim.SensorGroup(pv_prefix)
37
+ samp = sim.SampleStage(pv_prefix)
@@ -4,7 +4,7 @@ import bluesky.plan_stubs as bps
4
4
  import bluesky.plans as bp
5
5
  from bluesky import RunEngine
6
6
 
7
- from ophyd_async.tango.demo import (
7
+ from ophyd_async.tango.sim import (
8
8
  DemoCounter,
9
9
  DemoMover,
10
10
  TangoDetector,
@@ -14,11 +14,11 @@ from tango.test_context import MultiDeviceTestContext
14
14
  content = (
15
15
  {
16
16
  "class": DemoMover,
17
- "devices": [{"name": "demo/motor/1"}],
17
+ "devices": [{"name": "sim/motor/1"}],
18
18
  },
19
19
  {
20
20
  "class": DemoCounter,
21
- "devices": [{"name": "demo/counter/1"}, {"name": "demo/counter/2"}],
21
+ "devices": [{"name": "sim/counter/1"}, {"name": "sim/counter/2"}],
22
22
  },
23
23
  )
24
24
 
@@ -30,8 +30,8 @@ async def main():
30
30
  detector = TangoDetector(
31
31
  trl="",
32
32
  name="detector",
33
- counters_kwargs={"prefix": "demo/counter/", "count": 2},
34
- mover_kwargs={"trl": "demo/motor/1"},
33
+ counters_kwargs={"prefix": "sim/counter/", "count": 2},
34
+ mover_kwargs={"trl": "sim/motor/1"},
35
35
  )
36
36
  await detector.connect()
37
37
 
@@ -62,7 +62,7 @@ The two approaches now look like:
62
62
 
63
63
  ```python
64
64
  class Sensor(StandardReadable, EpicsDevice):
65
- """A demo sensor that produces a scalar value based on X and Y Movers"""
65
+ """A sim sensor that produces a scalar value based on X and Y Movers"""
66
66
 
67
67
  value: A[SignalR[float], PvSuffix("Value"), Format.HINTED_SIGNAL]
68
68
  mode: A[SignalRW[EnergyMode], PvSuffix("Mode"), Format.CONFIG_SIGNAL]
@@ -1,7 +1,7 @@
1
1
  Device Collector Event-Loop Choice
2
2
  ----------------------------------
3
3
 
4
- In a sync context, the ophyd-async :python:`DeviceCollector` requires the bluesky event-loop
4
+ In a sync context, the ophyd-async :python:`init_devices` requires the bluesky event-loop
5
5
  to connect to devices. In an async context, it does not.
6
6
 
7
7
  Sync Context
@@ -14,25 +14,25 @@ The following will fail if :python:`RE = RunEngine()` has not been called alread
14
14
 
15
15
  .. code:: python
16
16
 
17
- with DeviceCollector():
17
+ with init_devices():
18
18
  device1 = Device1(prefix)
19
19
  device2 = Device2(prefix)
20
20
  device3 = Device3(prefix)
21
21
 
22
- The :python:`DeviceCollector` connects to devices in the event-loop created in the run-engine.
22
+ The :python:`init_devices` connects to devices in the event-loop created in the run-engine.
23
23
 
24
24
 
25
25
  Async Context
26
26
  =============
27
27
 
28
28
  In an async context device connection is decoupled from the run-engine.
29
- The following attempts connection to all the devices in the :python:`DeviceCollector`
29
+ The following attempts connection to all the devices in the :python:`init_devices`
30
30
  before or after run-engine initialization.
31
31
 
32
32
  .. code:: python
33
33
 
34
34
  async def connection_function() :
35
- async with DeviceCollector():
35
+ async with init_devices():
36
36
  device1 = Device1(prefix)
37
37
  device2 = Device2(prefix)
38
38
  device3 = Device3(prefix)
@@ -43,8 +43,8 @@ The devices will be unable to be used in the run-engine unless they share the sa
43
43
  When the run-engine is initialised it will create a new background event-loop to use if one
44
44
  is not passed in with :python:`RunEngine(loop=loop)`.
45
45
 
46
- If the user wants to use devices in the async :python:`DeviceCollector` within the run-engine
46
+ If the user wants to use devices in the async :python:`init_devices` within the run-engine
47
47
  they can either:
48
48
 
49
- * Run the :python:`DeviceCollector` first and pass the event-loop into the run-engine.
50
- * Initialize the run-engine first and run the :python:`DeviceCollector` using the bluesky event-loop.
49
+ * Run the :python:`init_devices` first and pass the event-loop into the run-engine.
50
+ * Initialize the run-engine first and run the :python:`init_devices` using the bluesky event-loop.
@@ -11,7 +11,7 @@ Assembly
11
11
 
12
12
  Compound assemblies can be used to group Devices into larger logical Devices:
13
13
 
14
- .. literalinclude:: ../../src/ophyd_async/epics/demo/_mover.py
14
+ .. literalinclude:: ../../src/ophyd_async/epics/sim/_mover.py
15
15
  :pyobject: SampleStage
16
16
 
17
17
  This applies prefixes on construction:
@@ -35,7 +35,7 @@ Grouping by Index
35
35
 
36
36
  Sometimes, it makes sense to group devices by number, say an array of sensors:
37
37
 
38
- .. literalinclude:: ../../src/ophyd_async/epics/demo/_sensor.py
38
+ .. literalinclude:: ../../src/ophyd_async/epics/sim/_sensor.py
39
39
  :pyobject: SensorGroup
40
40
 
41
41
  :class:`~ophyd-async.core.DeviceVector` allows writing maintainable, arbitrary-length device groups instead of fixed classes for each possible grouping. A :class:`~ophyd-async.core.DeviceVector` can be accessed via indices, for example: ``my_sensor_group.sensors[2]``. Here ``sensors`` is a dictionary with integer indices rather than a list so that the most semantically sensible indices may be used, the sensor group above may be 1-indexed, for example, because the sensors' datasheet calls them "sensor 1", "sensor 2" etc.
@@ -13,7 +13,7 @@ To make a simple device, you need to subclass from the
13
13
  other suitable Bluesky `Protocols <hardware_interface>` like
14
14
  :external+bluesky:py:class:`bluesky.protocols.Movable`.
15
15
 
16
- The rest of this guide will show examples from ``src/ophyd_async/epics/demo/__init__.py``
16
+ The rest of this guide will show examples from ``src/ophyd_async/epics/sim/__init__.py``
17
17
 
18
18
  Readable
19
19
  --------
@@ -22,7 +22,7 @@ For a simple :external+bluesky:py:class:`bluesky.protocols.Readable` object like
22
22
  define some signals, then tell the superclass which signals should contribute to
23
23
  ``read()`` and ``read_configuration()``:
24
24
 
25
- .. literalinclude:: ../../src/ophyd_async/epics/demo/_sensor.py
25
+ .. literalinclude:: ../../src/ophyd_async/epics/sim/_sensor.py
26
26
  :pyobject: Sensor
27
27
 
28
28
  First some Signals are constructed and stored on the Device. Each one is passed
@@ -54,7 +54,7 @@ Movable
54
54
  For a more complicated device like a `Mover`, you can still use `StandardReadable`
55
55
  and implement some addition protocols:
56
56
 
57
- .. literalinclude:: ../../src/ophyd_async/epics/demo/_mover.py
57
+ .. literalinclude:: ../../src/ophyd_async/epics/sim/_mover.py
58
58
  :pyobject: Mover
59
59
 
60
60
  The ``set()`` method implements :external+bluesky:py:class:`bluesky.protocols.Movable`. This
@@ -71,7 +71,7 @@ Assembly
71
71
 
72
72
  Compound assemblies can be used to group Devices into larger logical Devices:
73
73
 
74
- .. literalinclude:: ../../src/ophyd_async/epics/demo/_mover.py
74
+ .. literalinclude:: ../../src/ophyd_async/epics/sim/_mover.py
75
75
  :pyobject: SampleStage
76
76
 
77
77
  This applies prefixes on construction:
@@ -24,9 +24,9 @@ Async Tests
24
24
  Mock Backend
25
25
  ------------
26
26
 
27
- Ophyd devices initialized with a mock backend behave in a similar way to mocks, without requiring you to mock out all the dependencies and internals. The `DeviceCollector` can initialize any number of devices, and their signals and sub-devices (recursively), with a mock backend.
27
+ Ophyd devices initialized with a mock backend behave in a similar way to mocks, without requiring you to mock out all the dependencies and internals. The `init_devices` can initialize any number of devices, and their signals and sub-devices (recursively), with a mock backend.
28
28
 
29
- .. literalinclude:: ../../tests/epics/demo/test_demo.py
29
+ .. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
30
30
  :pyobject: mock_sensor
31
31
 
32
32
 
@@ -37,26 +37,26 @@ Mock signals behave as simply as possible, holding a sensible default value when
37
37
 
38
38
  In addition this example also utilizes helper functions like ``assert_reading`` and ``assert_value`` to ensure the validity of device readings and values. For more information see: :doc:`API.core<../_api/ophyd_async.core>`
39
39
 
40
- .. literalinclude:: ../../tests/epics/demo/test_demo.py
40
+ .. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
41
41
  :pyobject: test_sensor_reading_shows_value
42
42
 
43
43
 
44
44
  Given that the mock signal holds a ``unittest.mock.Mock`` object you can retrieve this object and assert that the device has been set correctly using ``get_mock_put``. You are also free to use any other behaviour that ``unittest.mock.Mock`` provides, such as in this example which sets the parent of the mock to allow ordering across signals to be asserted:
45
45
 
46
- .. literalinclude:: ../../tests/epics/demo/test_demo.py
46
+ .. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
47
47
  :pyobject: test_retrieve_mock_and_assert
48
48
 
49
49
  There are several other test utility functions:
50
50
 
51
51
  Use ``callback_on_mock_put``, for hooking in logic when a mock value changes (e.g. because someone puts to it). This can be called directly, or used as a context, with the callbacks ending after exit.
52
52
 
53
- .. literalinclude:: ../../tests/epics/demo/test_demo.py
53
+ .. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
54
54
  :pyobject: test_mover_stopped
55
55
 
56
56
 
57
57
  Testing a Device in a Plan with the RunEngine
58
58
  ---------------------------------------------
59
- .. literalinclude:: ../../tests/epics/demo/test_demo.py
59
+ .. literalinclude:: ../../tests/epics/sim/test_epics_sim.py
60
60
  :pyobject: test_sensor_in_plan
61
61
 
62
62
 
@@ -0,0 +1,2 @@
1
+ <svg version="1.1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1187.8240472771774 784.5838303364346" width="1187.8240472771774" height="784.5838303364346"><!-- svg-source:excalidraw --><metadata><!-- payload-type:application/vnd.excalidraw+json --><!-- payload-version:2 --><!-- payload-start -->eyJ2ZXJzaW9uIjoiMSIsImVuY29kaW5nIjoiYnN0cmluZyIsImNvbXByZXNzZWQiOnRydWUsImVuY29kZWQiOiJ4nO1cXGtT28hcdTAwMTL9nl/hYr+uZ6fnPVu1XHUwMDFmeL9cdGAg4LtblLBcdTAwMDU2yI/YMrbZyn+/PVwitmRLSkxQXHUwMDE1cK+VSlx1MDAwMlx1MDAxYUlcdTAwMWVPn3Ome7pH/34qlVbCcddf+bO04o9qXtCs97zhyu/u/KPf6zc7bWxi0e/9zqBXi65shGG3/+dcdTAwMWZ/xHeQWqf1fJdcdTAwMWb4Lb9cdTAwMWT28br/4O+l0r/Rv9jSrLt7d1x1MDAwZvbOzcBcdTAwMWLv8NP9w+1t9dS4236Kbo0umnQmaLb9+OzIdcIoorlQTEkqQVs9bVx1MDAxZLtWLVxilVSBppZyUHzaOmzWw4a7XHUwMDAyXGZRXHUwMDFjrNKUWrBcdTAwMTTiS1x1MDAxYX7zrlx1MDAxMeI1dHrKa99cdTAwMDX+zJl+2Os8+OudoNNzXHUwMDFk/FxyfPcn7uONV3u463VcdTAwMDbt+vSasOe1+12vh+NcdTAwMTFfd9tcZoJKOI6ejmOK47cy91x1MDAxOV8mPZ47n3dcdTAwMTd+6F2j7ffdmMP0bKfr1ZqhXHUwMDFiXHUwMDFioPG3cD3s7tYj8/xcdTAwMTP3qee1/F1nn/YgXGKmp5vtuu+GfsXTM5/Wrn//tIltY8Ox72e+xX33ffdg4NQoSpPDXHUwMDFlXHUwMDAzjKv5k0eddoQ10MBcdTAwMDAsmPiLNftcdTAwMWJcYrIweuqtXHUwMDE39P3YXHUwMDA0rmubXHRcdTAwMDDG33DQrXvPt4DmIC1cYnyskdN2xNvD/NdcdTAwMGY6tYeMT+l2mkl8uyP+qVx1MDAxNCMm+mX68z+/Z16dj8q52z/NPWYl8PrheqfVaob4vY5dn+b731x1MDAwZr1euIZGbLbv5tv8dj2nJbprtdfrXGZcdTAwMWK+l4JcdTAwMDTeN9/2KWHvObLLSnBTvX06OdLXltc26eZVfTRehOxIccKVkpZLXHUwMDEwXFxZk1wiO8LCNTFcdTAwMDaW2Vx1MDAxNNljwE+5XHJKXHUwMDEyI43mXHUwMDFjn1xu2sSQW3J9huvm9Vxcl4ZZq1xmj/lcdTAwMTVzXaZcdTAwMDRgwnWpQSpcdTAwMDGxNVx1MDAwYmK6NlrHXHUwMDAweiumz1xcXU6h8aMzfWdw3FxizvaHrcv7p4PLe749XHUwMDFhfVmM6UC0YtpcdTAwMWGqwf1cdTAwMTBj5lx1MDAxOc+SXGIhXHUwMDEwXHUwMDFhilx1MDAxYamVjFxyOeE6ylx1MDAwNEE7K2NcdTAwMTjKhqKxYzDlPidGUFx1MDAwMdxSfJax2i7Jn0P+1VeTX1xuLVx1MDAwNVozi/vI79yJnlkpuaE2lodi6C9cdTAwMTmjXHRn8a3on4tSd5TTXHUwMDAw/eB6cPxggro9XHUwMDFiqTXjs2FzNVx1MDAxOHVH54voXHUwMDAxgDJESKMkXHUwMDE4I4DyXHUwMDE4XHUwMDBmz1x1MDAxMOdcdTAwMDRcdTAwMDTljGNcdTAwMWNgqY6pM/XzXHSnglx0w1x1MDAwNVPKclx1MDAxNuMw4VxuUMLQXHUwMDAzxFx1MDAwYimCTibmqaVcdTAwMWPMyMHaq+VAS6lcZloq7mAsXHUwMDA3JtdcdTAwMTVcdTAwMDCjMYpcdTAwMDOdsF5BaiCYZuLN1SBcdTAwMTek7kjD84OLQf38er+744l9enmpz8Pg3JfVtVx1MDAwNcXAXHUwMDEyxpSL+5Wwls3FXHUwMDAxSlx1MDAxMMG1Rlx1MDAxOZBMK65jw07UXHUwMDAwuEY/XHUwMDBiXVx1MDAwN0mpQVx1MDAxN0PFT5jKwZwxTMy/pVx1MDAxYcyowfqr1UBYXHSIdpblXHUwMDFjWDF/cqJcdTAwMDZMSJxcdTAwMTk5LTIyYFx1MDAxNKzB2IDFY/VWYpCPUXeUU/D84GrgVeqNzVx1MDAxZF7/utX6Ut7YWq3fXHUwMDFjle/SauC5J87KXHUwMDAxt4pYjUrAmVx1MDAwNvRcdTAwMTBcdTAwMTLepEM4d45cdTAwMDNHt0BKQEmwad/ARVx1MDAxM+hcXEnqllx1MDAxNoRgiVx1MDAwN0zVQCmCkSsqXHUwMDBlSlxuM1bFoFuqwYxcdTAwMWFsvFpcclx1MDAxOLq8Ssgs14Dlilx1MDAwMXqA6FFgSF/0iiBOtWDffkUwXHUwMDFmo+5IofO9i8E8j/3gpjOMx/BcdTAwMDc6MVx1MDAxZdOy1aPu497J9vrZcFx1MDAxZvzbs520ToT+KJyTXHRQhFwiSrimimLIOatcdTAwMTJlMFx1MDAwNJ1LXHUwMDEzSYhCXHUwMDE3i6Z1wrr1xYzAgS1cdTAwMDOFXHUwMDFjMdjMXHUwMDE2g1ncfF8g4JapZJyfWFx1MDAxZmDzJ6cuXHUwMDAwMPbsvVx1MDAxN816zXVcIlx1MDAwZXlcdTAwMDHrI+C5wfbDUs1cdTAwMGJcdTAwMDI/MeK3nXZYaT5FPaczZ7e8VjNwgy5nXHUwMDFltFx1MDAxYTTv2pFcdTAwMTPs3yawgKNcdTAwMTA28eHT5rDTjVtr+DxcdTAwMGad5l7aMp1e867Z9oKzXHUwMDFmdNJcdTAwMWKEnVO//9zNsDfwk6Pg70yjZcLkXHUwMDBmaDqwNHzcqVx1MDAwZcfXm6u6vXNePeWrtYWmc4zvXHUwMDA0wUlcXIGlXHUwMDE2I0SYJSoznGgppKDAuaIssWI/4akhnEtcZlxyjLMkXlx1MDAxNcMnXvozgijGXHUwMDE4PohKXHUwMDA1XHUwMDE4ji4pnE3hrVfP5+iSXHUwMDE5UEon4TtcdPVzmVxyOJ9RKlx1MDAwNC903Vx1MDAxZnshXHUwMDExM1x0QXmr+TxcdTAwMTej7kij8393Pu96Z9XDrduB199f2zp73LjqXbTsXCLzOY5cdTAwMWHGQFx1MDAxYbVAXHUwMDAws5bPZv6VUYQroVxyM2Ckzcj8u9u1ZlK6RZWZ5Z+pSlxiQ5ihXHUwMDE2/0pEXHUwMDBmzlDxNUuVmFGJ7cUneuDIbGGtykxcdTAwMDWI1NlpXHUwMDFlMPJcdTAwMTCEKjrc10Zp9Utrf5OpvuJm0U6rXHUwMDFi9eXvduZ8XHUwMDBmlnBgXFyjw0KVXHUwMDE1kEhoveH8n9vzYpyAo3p1yK5cdTAwMGY2dqrdx4C1XHUwMDFiI713lOFcdTAwMDRkVfVcdTAwMTiiMPTSqJDS2WiG25IxYlx1MDAxMSnGXCKUXHUwMDE4+lx1MDAwYiluY1x1MDAwMInc5lxcUFxmmVDxM5b3MJxyy0fCKLfIQlx1MDAxNSyTfznc3nt95t9aXGZYXHUwMDE1miqD8jrlXHUwMDE4JHxcdTAwMDDDjVx1MDAwMVF0TK9cXFx1MDAxMVx0TUL6TXyAXFyUuqOcXHUwMDA26Ht3XHUwMDAyfrLCd2Iq/Vx1MDAwYk94Xs/SS3VVXHUwMDE5X9X8/lwiaqBd2Y8xLtBTVCZzyJFcdTAwMWHgKFpFlVx1MDAxMVx1MDAxMlx1MDAwNIbw6XhcdTAwMDDdXHUwMDA0dLMwnlx1MDAxMNrlXGIzKlx1MDAwMUBcdTAwMDGxXHUwMDAyXHUwMDAxylx1MDAwNOMozsvF/jwx2H+9XHUwMDE4oCGNq8bMXG5cYoDmJv9cdTAwMTjGgkZD4Vx1MDAwYnxugjGxU/FWYlDOQ2nUmFx1MDAwNuhcdTAwMDdcdTAwMTeDQ1j1/ftBZet2/CBcdTAwMWFhd9y+3G8uJlx1MDAwNpxQ6rxxXHSIoUSqP1rsl0CEwGGyoGmyPDSu96VEK8M4XHUwMDBlo1x1MDAwNMMzlvrnXGZcdTAwMDGJWoOlXHUwMDE4zIjBQVx1MDAwMTWBnDFU7zTtnanzV1x1MDAwNzCEwGis8GU/JTFcdTAwMWOMIfF25b85IHXHvFAgPj+4XHUwMDE2XFxcdTAwMDSNyv2Td7HfVMdcdTAwMWK1zZOt7mh0tYhcdTAwMTZYYERcdTAwMWFh0EkywpVcdTAwMDXPaoHQxChcdTAwMTffMWGpVlx1MDAxOYk/XHUwMDAy2IBcdTAwMTG+5qhcdTAwMTZuISDLNZBcdTAwMDRtgMDgQkhXdbBUg2w1OHy9XHUwMDFhXGJhjcb4ODNOyF1cdTAwMTkw6DpcdTAwMDNcdTAwMThWuGeguHhcdTAwMGapv1xclEatKXx+cDVYXHIvVoc4f1x1MDAxZldb7ZPH+/2d3aOb3mJqIDBcdTAwMTBwsZ3hjCo2XHUwMDFmJnBcdTAwMTdEoPPktlx1MDAwZliT3lx1MDAxZMBcciNMIPqYlFxiJpGxXHUwMDEzaCYm01bE61xuSy2Y0YKjXHUwMDAyqlx1MDAwMCTXWr20KFxiXWODs2PhXHUwMDFig1x1MDAxMFRKvP12gVxcjLqjnILnXHUwMDA3l4LDLjuiZ8NHM1TlXHUwMDAz8fBwerd7TVx1MDAxN0pcIlqQP4hcdTAwMTIkWIKDZLkrpnRZoZ94XHUwMDA2imeVXHUwMDBic0qsq2HVXHUwMDEw7VGIXHUwMDExt9SCXHUwMDE5Lfj8ei1cdTAwMDBw9W9orlxmLYD88lx1MDAwMFx1MDAxMCCURlx1MDAwYlx1MDAxNVx1MDAxOSe4nIFbwTfvoEQwXHUwMDBmpVHjPD7fu1x1MDAxOPx6XHUwMDBlsex/3Vx0t/nhnq7uhqbSPDg+5seL5Fx1MDAxMHF4XGJFOVx1MDAxNVpcdTAwMGLrXGY7I1x1MDAxM25zhpXMWpeyUZBcdTAwMTCBOIdo8VxuXHUwMDA0pmFCU02zXFyG5e7hXHUwMDFjXTjO1oXsnKFSVKNkZ1x1MDAwNVx1MDAwNkDz64NcXKJcdTAwMTGDP1WkO/A6XHUwMDAxmCRcck/XLkqHXlhr+PXS3+1TP1x1MDAxY/TapYbfS1j/3ZVcdTAwMGIt0OdiXHUwMDEyh1fbtfPxyf3t58HT7nrlZG90vN86XYTQTDJiLDpG0lx1MDAxNYdrSCR2o+IhjozmbkuAxjklWeg7rfGTRC1r/F5C45NcdTAwMTfQWGpKKfqlmTuA8/OA0lVwUFHs0r+rXHUwMDA1clx1MDAwNVx1MDAwNb9cdTAwMTTgJ1P/fWSVXHUwMDE3vGPaZnWyXHUwMDE4nm5Wx/edr5etQy5cdTAwMDJ2trq7a8MhLFa8XHUwMDAzjFxiJiRTOPtcbjNcdTAwMTesa0aJVKCY4NRcdTAwMWGTsZ+PU0OYXHUwMDBiyyZHxtS75GxcdTAwMWVnT1x1MDAxN+ese89cdTAwMDZcdTAwMDcqMzlcdTAwMGI/ekVHtIWN6lwi9+pF9Tr4n3xVae7Qa4bXt53edd9cdTAwMGavv5e/YM//Kp0hXHUwMDBm3jGPXHUwMDE37Hcx1D6RO/f65ubgofbF71x1MDAxZlxmap/LfP1sXHUwMDExamsliOZGaFx0XGJcdTAwMDCQaWZcdTAwMWKDs1x1MDAwMFx1MDAwN2FccqfpXHUwMDE5XHUwMDE4jUxQlVxyn1x1MDAxY0tiL07sylx1MDAwYiZj9GJccjPKZlx1MDAxMjtdrjslNqAuU5Pcu1uUT23Er7175yfELv1V2nLXfzxqp3teXGa5ny79yuOoelC+XHUwMDA3yldcdTAwMGZlY/vOW2jeZorjtK0toP8kuaSz62poPlwiqFx1MDAwMWMsl0InK3WmXHUwMDExM9jlJpqXcfpscU5LbaQrts8qrflBNl1cdTAwMWItXFw+udBt9Uqh/Vx1MDAxNee/lE6fMLrlos3372Fnd7NcdTAwMTiunrY3xGBXXHUwMDFl9PpP7HjfVPf2vcHJXCJcXFx1MDAwNUYp0e7tKVQyKsRcXIG8K6JcdTAwMTUou26/XHKIrFx1MDAwMnlJkMVoR9RlhyqawVrxXHUwMDEy1vo46XP4P2HtxVx1MDAwYmZiJpVcdTAwMDYtWSZt81lrXTWcVoVcdTAwMTbBIGst6OSuql9gLWRSNaFcdTAwMDRvSFUomp9b643zyvaVXHUwMDE4datcdTAwMDftXTa86lxmZMbG9TQ/LXcvp0RyWWqZoGxu8ZlaYo1CS3Anoybj1ZWSPMe/XHUwMDE0g2HDdXz/kp4/peeXxelpLUWFTL5cdTAwMTJcImanyk1EW4raKrgu8sVVxaw8s3fMTvZcbnZ++p7RWvG63UqIo7YySTKuPDb94VpcdTAwMWHOv91Gx8qn79x2UPaj3OS3T9/+XHUwMDBiP9Ji1SJ9<!-- payload-end --></metadata><defs><style class="style-fonts">
2
+ @font-face { font-family: Excalifont; src: url(data:font/woff2;base64,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); }</style></defs><rect x="0" y="0" width="1187.8240472771774" height="784.5838303364346" fill="#ffffff"></rect><g stroke-linecap="round"><g transform="translate(43.84248105120804 302.75444427692025) rotate(0 109.31598350459507 0)"><path d="M-0.45 -0.7 C35.76 -0.86, 180.92 -1.39, 217.58 -1.19 M1.51 1.54 C38.06 1.51, 183.45 0.24, 219.75 -0.28" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(262.4744480603982 302.8253415087969) rotate(0 0 -82.9293667965893)"><path d="M0.64 0.3 C0.59 -27.08, -0.08 -137.51, -0.32 -165.29 M-0.48 -0.59 C-0.72 -28.23, -1.79 -139.66, -1.44 -167.12" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(258.8706526177911 134.14839879518058) rotate(0 332.5798441252804 -1.9202069522244898)"><path d="M-0.18 0.98 C110.67 0.28, 554.82 -2.97, 665.76 -3.76 M-1.73 0.45 C108.95 -0.07, 554.04 -1.71, 665.12 -2.18" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(925.5665064301318 131.8441504525112) rotate(0 1.1521241713346626 80.10711520276767)"><path d="M0.54 0.53 C0.98 27.16, 1.63 133.33, 2.07 159.95 M-0.63 -0.24 C-0.32 26.56, 0.42 134.38, 1 161.35" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(926.3345892110212 293.1415344393678) rotate(0 68.92542750440384 -1.152124171334691)"><path d="M1.09 -0.33 C24.12 -0.33, 115.62 -0.86, 138.29 -1.2 M0.21 -1.54 C23.1 -1.75, 114.33 -2.82, 137.57 -2.74" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(154.08449781789392 67.15748673767692) rotate(0 52.98975332972128 33.34186726364484)"><path d="M-1.06 0.7 C16.59 11.86, 88.97 56.89, 106.91 67.72 M0.58 0.03 C18.07 10.8, 88.85 55.06, 106.45 66.14" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(154.08449781789392 67.15748673767692) rotate(0 52.98975332972128 33.34186726364484)"><path d="M82 60.91 C92.6 64.68, 102.53 66.17, 106.45 66.14 M82 60.91 C86.56 61.38, 93.31 62.59, 106.45 66.14" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(154.08449781789392 67.15748673767692) rotate(0 52.98975332972128 33.34186726364484)"><path d="M91.08 46.42 C98.28 55.67, 104.73 62.72, 106.45 66.14 M91.08 46.42 C93.64 50.1, 98.42 54.45, 106.45 66.14" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(73.11139160618495 10) rotate(0 47.0625 12.5)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">set called</text></g><g stroke-linecap="round"><g transform="translate(931.6644736450401 312.4583673202069) rotate(0 4.167733407955666 192.31112725280877)"><path d="M-0.34 -0.98 C1.13 63.35, 6.73 321.09, 8.05 385.17 M1.68 1.12 C3.03 65.16, 5.56 319.49, 6.94 383.33" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(931.6644736450401 312.4583673202069) rotate(0 4.167733407955666 192.31112725280877)"><path d="M-1.96 359.97 C-1.66 365.01, 2.98 369.66, 6.94 383.33 M-1.96 359.97 C0.77 365.61, 2.46 369.39, 6.94 383.33" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(931.6644736450401 312.4583673202069) rotate(0 4.167733407955666 192.31112725280877)"><path d="M15.14 359.71 C11.41 364.76, 12.02 369.48, 6.94 383.33 M15.14 359.71 C14.41 365.37, 12.64 369.21, 6.94 383.33" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(889.4853986759654 715.0686100052003) rotate(0 66.3862760711362 24.140464025867686)"><text x="0" y="17.014199045431567" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="19.312371220694175px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Set completed</text><text x="0" y="41.15466307129928" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="19.312371220694175px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic"></text></g><g stroke-linecap="round"><g transform="translate(45.723429211048085 551.6184165698157) rotate(0 208.3866703977804 -2.9769524342540308)"><path d="M1.15 -0.09 C70.36 -1.4, 346.52 -5.76, 415.96 -6.64 M0.29 -1.19 C69.83 -1.84, 348.7 -4.42, 418.24 -5.46" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(462.49677000660887 545.6645117013077) rotate(0 -1.190780973701635 -80.97310621170891)"><path d="M-0.62 -0.09 C-1.05 -26.87, -1.53 -134.53, -1.9 -161.39 M1.25 -1.18 C0.65 -28.26, -1.74 -136.22, -2.59 -163.22" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(460.1152080592056 380.14595635678495) rotate(0 105.3841161725918 -1.1907809737016066)"><path d="M0.98 -0.93 C36.1 -1.01, 176.54 -1, 211.51 -1.27 M0.04 1.2 C34.99 0.88, 175.96 -2.39, 210.95 -2.82" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(669.6926594306876 376.57361343568016) rotate(0 0.5953904868507607 82.75927767226133)"><path d="M-0.99 -0.41 C-0.54 27.2, 1.55 136.9, 1.72 164.64 M0.7 -1.68 C1.12 26.16, 0.78 138.12, 1.04 165.72" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(672.0742213780909 542.0921687802029) rotate(0 191.12034627910714 -2.976952434253974)"><path d="M0.95 0.4 C64.42 -0.86, 317.63 -5.42, 381.15 -6.62 M0 -0.44 C63.78 -1.63, 319.76 -4.51, 383.29 -5.43" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g stroke-linecap="round"><g transform="translate(672.1152080592055 548.1907594909206) rotate(0 0.5953904868508175 65.49295355358805)"><path d="M-0.92 1.14 C-0.95 23.33, -0.16 110.39, 0.31 131.92 M0.8 0.7 C1.09 22.66, 2.45 108.52, 2.56 130.29" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(672.1152080592055 548.1907594909206) rotate(0 0.5953904868508175 65.49295355358805)"><path d="M-6.25 106.9 C-1.55 113.53, 1.13 124.19, 2.56 130.29 M-6.25 106.9 C-4.64 113.13, -2.21 118.07, 2.56 130.29" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g><g transform="translate(672.1152080592055 548.1907594909206) rotate(0 0.5953904868508175 65.49295355358805)"><path d="M10.85 106.7 C9.68 113.27, 6.5 123.99, 2.56 130.29 M10.85 106.7 C8.22 113.14, 6.41 118.12, 2.56 130.29" stroke="#1e1e1e" stroke-width="2" fill="none"></path></g></g><mask></mask><g transform="translate(616.1485022952302 694.6568192562175) rotate(0 69.97916412353516 25)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">RBV Matched </text><text x="0" y="42.62" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Return here</text></g><g transform="translate(10 264.6402019077296) rotate(0 47.8125 12.500000000000014)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">Set signal</text></g><g transform="translate(869.5323806105109 749.2654514964912) rotate(0 154.14583333333326 12.5)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">wait_for_set_completion= True</text></g><g transform="translate(521.8463297153439 749.5838303364346) rotate(0 160.32291666666663 12.5)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">wait_for_set_completion = False</text></g><g transform="translate(20.535767711378583 514.1120161220821) rotate(0 59.5625 12.5)"><text x="0" y="17.619999999999997" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="20px" fill="#1e1e1e" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">match signal</text></g><g transform="translate(957.8616550664754 651.6440183607504) rotate(0 7.677083492279053 22.5)"><text x="0" y="31.716" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="36px" fill="#e03131" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">1</text></g><g transform="translate(691.1677036384312 638.6901134922423) rotate(0 12.583333015441895 22.5)"><text x="0" y="31.716" font-family="Excalifont, Xiaolai, Segoe UI Emoji" font-size="36px" fill="#e03131" text-anchor="start" style="white-space: pre;" direction="ltr" dominant-baseline="alphabetic">2</text></g></svg>
@@ -41,13 +41,13 @@ that you can mix Ophyd and Ophyd Async devices in the same RunEngine:
41
41
  :start-after: # Create ophyd devices
42
42
  :end-before: # Create ophyd-async devices
43
43
 
44
- Finally we create the Ophyd Async devices imported from the `epics.demo` module:
44
+ Finally we create the Ophyd Async devices imported from the `epics.sim` module:
45
45
 
46
46
  .. literalinclude:: ../examples/epics_demo.py
47
47
  :language: python
48
48
  :start-after: # Create ophyd-async devices
49
49
 
50
- The first thing to note is `with`. This uses a `DeviceCollector` as a context
50
+ The first thing to note is `with`. This uses `init_devices` as a context
51
51
  manager to collect up the top level `Device` instances created in the context,
52
52
  and run the following:
53
53
 
@@ -9,6 +9,7 @@ classifiers = [
9
9
  "License :: OSI Approved :: BSD License",
10
10
  "Programming Language :: Python :: 3.10",
11
11
  "Programming Language :: Python :: 3.11",
12
+ "Programming Language :: Python :: 3.12",
12
13
  ]
13
14
  description = "Asynchronous Bluesky hardware abstraction code, compatible with control systems like EPICS and Tango"
14
15
  dependencies = [
@@ -42,6 +43,7 @@ dev = [
42
43
  "inflection",
43
44
  "ipython",
44
45
  "ipywidgets",
46
+ "import-linter",
45
47
  "matplotlib",
46
48
  "myst-parser",
47
49
  "numpydoc",
@@ -73,9 +75,6 @@ dev = [
73
75
  "types-pyyaml",
74
76
  ]
75
77
 
76
- [project.scripts]
77
- ophyd-async = "ophyd_async.__main__:main"
78
-
79
78
  [project.urls]
80
79
  GitHub = "https://github.com/bluesky/ophyd-async"
81
80
 
@@ -156,6 +155,11 @@ lint.select = [
156
155
  "UP", # pyupgrade - https://docs.astral.sh/ruff/rules/#pyupgrade-up
157
156
  "SLF", # self - https://docs.astral.sh/ruff/settings/#lintflake8-self
158
157
  "PLC2701", # private import - https://docs.astral.sh/ruff/rules/import-private-name/
158
+ "LOG015", # root logger call - https://docs.astral.sh/ruff/rules/root-logger-call/
159
+ "S101", # assert = https://docs.astral.sh/ruff/rules/assert/
160
+ ]
161
+ lint.ignore = [
162
+ "B901", # Return in a generator is needed for plans
159
163
  ]
160
164
  lint.preview = true # so that preview mode PLC2701 is enabled
161
165
 
@@ -163,4 +167,30 @@ lint.preview = true # so that preview mode PLC2701 is enabled
163
167
  # By default, private member access is allowed in tests
164
168
  # See https://github.com/DiamondLightSource/python-copier-template/issues/154
165
169
  # Remove this line to forbid private member access in tests
166
- "tests/**/*" = ["SLF001"]
170
+ "tests/**/*" = ["SLF001", "S101"]
171
+ "src/ophyd_async/testing/**/*" = ["SLF001", "S101"]
172
+ "system_tests/**/*" = ["SLF001", "S101"]
173
+ "docs/examples/**/*" = ["SLF001", "S101"]
174
+
175
+
176
+ [tool.importlinter]
177
+ root_package = "ophyd_async"
178
+
179
+ [[tool.importlinter.contracts]]
180
+ name = "All runtime modules are in layers"
181
+ type = "layers"
182
+ containers = ["ophyd_async"]
183
+ layers = ["plan_stubs", "fastcs", "epics | tango | sim", "core"]
184
+ exhaustive = true
185
+ exhaustive_ignores = ["testing", "_version", "__main__"]
186
+
187
+ [[tool.importlinter.contracts]]
188
+ name = "Testing and sim modules are not used at runtime"
189
+ type = "forbidden"
190
+ forbidden_modules = ["ophyd_async.testing", "ophyd_async.sim"]
191
+ source_modules = [
192
+ "ophyd_async.plan_stubs",
193
+ "ophyd_async.fast.*",
194
+ "ophyd_async.epics",
195
+ "ophyd_async.tango",
196
+ ]
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.8.0a6'
16
- __version_tuple__ = version_tuple = (0, 8, 0)
15
+ __version__ = version = '0.9.0'
16
+ __version_tuple__ = version_tuple = (0, 9, 0)