toio-py-fork 1.1.0.post2.dev2__tar.gz → 1.1.0.post2.dev3__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 (183) hide show
  1. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/CHANGELOG_FORK.ja.md +9 -0
  2. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/CHANGELOG_FORK.md +9 -0
  3. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/CONTRIBUTING.md +7 -7
  4. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/PKG-INFO +2 -2
  5. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/TESTING.ja.md +8 -3
  6. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/TESTING.md +8 -4
  7. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/pyproject.toml +1 -1
  8. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/pythonista3/install_toio.py.in +54 -39
  9. toio_py_fork-1.1.0.post2.dev3/pythonista3/make_install_script.sh +40 -0
  10. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/conftest.py +23 -13
  11. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/make_cube_list.py +3 -1
  12. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_10_two_cubes/test_2cubes_connect_v1_2.py +21 -0
  13. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_10_two_cubes/test_2cubes_scanner.py +100 -21
  14. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_10_two_cubes/test_multiple_class.py +30 -0
  15. toio_py_fork-1.1.0.post2.dev3/tests/test_20_interactive/test_savable_configuration_interactive.py +135 -0
  16. toio_py_fork-1.1.0.post2.dev3/tests/test_50_definition/test_configuration_v250.py +90 -0
  17. toio_py_fork-1.1.0.post2.dev3/tests/test_50_definition/test_indicator_v250.py +35 -0
  18. toio_py_fork-1.1.0.post2.dev3/tests/test_50_definition/test_pythonista3_backend.py +653 -0
  19. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_definition/test_scanner.py +4 -2
  20. toio_py_fork-1.1.0.post2.dev3/tests/test_50_definition/test_sensor.py +87 -0
  21. toio_py_fork-1.1.0.post2.dev3/tests/test_50_definition/test_syntax_sugar.py +47 -0
  22. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_definition/test_toio_core_cube.py +7 -1
  23. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_single_cube/test_connect_v1_2.py +50 -0
  24. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_single_cube/test_indicator_v1_2.py +3 -1
  25. toio_py_fork-1.1.0.post2.dev3/tests/test_50_single_cube/test_savable_configuration.py +89 -0
  26. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/__init__.py +2 -0
  27. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/__init__.py +4 -1
  28. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/button.py +0 -1
  29. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/configuration.py +9 -10
  30. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/id_information.py +6 -7
  31. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/indicator.py +12 -6
  32. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/motor.py +0 -1
  33. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/sensor.py +1 -2
  34. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/sound.py +0 -1
  35. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/ble.py +2 -10
  36. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/pythonista3corebluetooth/CentralManagerDelegate.py +75 -75
  37. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/pythonista3corebluetooth/PeripheralDelegate.py +96 -63
  38. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/pythonista3corebluetooth/client.py +95 -122
  39. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/pythonista3corebluetooth/objc_types.py +4 -6
  40. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/pythonista3corebluetooth/scanner.py +29 -49
  41. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/pythonista3corebluetooth/utils.py +37 -2
  42. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/uv.lock +28 -28
  43. toio_py_fork-1.1.0.post2.dev2/pythonista3/make_install_script.sh +0 -25
  44. toio_py_fork-1.1.0.post2.dev2/tests/test_20_interactive/test_savable_configuration.py +0 -170
  45. toio_py_fork-1.1.0.post2.dev2/tests/test_50_definition/test_syntax_sugar.py +0 -56
  46. toio_py_fork-1.1.0.post2.dev2/tests/test_50_single_cube/test_savable_configuration.py +0 -141
  47. toio_py_fork-1.1.0.post2.dev2/toio/device_interface/pythonista3corebluetooth/characteristic.py +0 -125
  48. toio_py_fork-1.1.0.post2.dev2/toio/device_interface/pythonista3corebluetooth/descriptor.py +0 -49
  49. toio_py_fork-1.1.0.post2.dev2/toio/device_interface/pythonista3corebluetooth/service.py +0 -49
  50. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/.flake8 +0 -0
  51. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/.gitignore +0 -0
  52. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/CHANGELOG.md +0 -0
  53. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/CODE_OF_CONDUCT.md +0 -0
  54. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/LICENSE +0 -0
  55. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/README.ja.md +0 -0
  56. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/README.md +0 -0
  57. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/SETUP_GUIDE.en.md +0 -0
  58. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/SETUP_GUIDE.ja.md +0 -0
  59. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/SETUP_GUIDE.zh.md +0 -0
  60. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/SIMPLE_API.en.md +0 -0
  61. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/SIMPLE_API.ja.md +0 -0
  62. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/INSTALL_TO_PYTHONISTA3.en.rst +0 -0
  63. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/INSTALL_TO_PYTHONISTA3.ja.rst +0 -0
  64. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/Makefile +0 -0
  65. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/_templates/version.html +0 -0
  66. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/conf.py +0 -0
  67. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/index.rst +0 -0
  68. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/make.bat +0 -0
  69. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.coordinate_systems.rst +0 -0
  70. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.base_class.rst +0 -0
  71. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.battery.rst +0 -0
  72. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.button.rst +0 -0
  73. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.configuration.rst +0 -0
  74. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.id_information.rst +0 -0
  75. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.indicator.rst +0 -0
  76. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.motor.rst +0 -0
  77. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.rst +0 -0
  78. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.sensor.rst +0 -0
  79. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.api.sound.rst +0 -0
  80. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.multi_cubes.rst +0 -0
  81. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.notification_handler_info.rst +0 -0
  82. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.cube.rst +0 -0
  83. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.device_interface.ble.rst +0 -0
  84. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.device_interface.dummy.rst +0 -0
  85. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.device_interface.rst +0 -0
  86. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.logger.rst +0 -0
  87. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.position.rst +0 -0
  88. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.rst +0 -0
  89. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.scanner.ble.rst +0 -0
  90. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.scanner.rst +0 -0
  91. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.simple.async_simple.rst +0 -0
  92. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.simple.rst +0 -0
  93. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.standard_id.rst +0 -0
  94. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.toio_uuid.rst +0 -0
  95. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/docs-conf/toio.utility.rst +0 -0
  96. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/async_gather.py +0 -0
  97. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/async_gather_multi.py +0 -0
  98. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/async_task_group.py +0 -0
  99. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/detect_mat.py +0 -0
  100. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/motor_control.py +0 -0
  101. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/multi_cubes_with_attribute.py +0 -0
  102. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/multi_cubes_with_named.py +0 -0
  103. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/read_position.py +0 -0
  104. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/scan_and_connect.py +0 -0
  105. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples/tutorial_pursuer.py +0 -0
  106. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/angle_control.py +0 -0
  107. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/basic_motor_control.py +0 -0
  108. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/concurrent_futures_simple.py +0 -0
  109. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/get_current_grid.py +0 -0
  110. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/get_information_1.py +0 -0
  111. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/get_information_2.py +0 -0
  112. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/get_standard_id.py +0 -0
  113. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/goto_a_gird.py +0 -0
  114. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/lamp.py +0 -0
  115. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/move_to.py +0 -0
  116. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/multi_cubes_async_simple.py +0 -0
  117. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/sound.py +0 -0
  118. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/examples-simple/step.py +0 -0
  119. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2022-12-05-09-46-13.png +0 -0
  120. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2022-12-05-09-47-14.png +0 -0
  121. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2022-12-05-09-53-08.png +0 -0
  122. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2022-12-08-13-58-34.png +0 -0
  123. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2022-12-16-14-16-29.png +0 -0
  124. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2022-12-16-14-20-09.png +0 -0
  125. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2022-12-16-14-23-28.png +0 -0
  126. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2022-12-16-14-24-35.png +0 -0
  127. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2023-01-06-09-38-30.png +0 -0
  128. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2023-01-06-09-39-00.png +0 -0
  129. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2023-01-06-09-39-51.png +0 -0
  130. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2023-01-06-09-40-03.png +0 -0
  131. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2023-01-06-09-41-19.png +0 -0
  132. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2023-02-27-15-14-45.png +0 -0
  133. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/image/IMG-2023-02-27-15-15-11.png +0 -0
  134. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/mkdocs/_templates/version.html +0 -0
  135. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/mkdocs/add_noindex.py +0 -0
  136. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/mkdocs/conf.py +0 -0
  137. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/mkdocs/index.html +0 -0
  138. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/mkdocs/mkdocs.sh +0 -0
  139. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/pythonista3/INSTALL_TO_PYTHONISTA3.en.md +0 -0
  140. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/pythonista3/INSTALL_TO_PYTHONISTA3.ja.md +0 -0
  141. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/__init__.py +0 -0
  142. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/_cubes.py +0 -0
  143. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/check_coverage.sh +0 -0
  144. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_10_two_cubes/_cubes.py +0 -0
  145. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_11_cube_off/test_cube_off.py +0 -0
  146. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_20_interactive/test_id_information.py +0 -0
  147. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_20_interactive/test_indicator.py +0 -0
  148. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_20_interactive/test_notification_handler_v1_2.py +0 -0
  149. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_20_interactive/test_sensor_v1_2.py +0 -0
  150. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_definition/test_ble_interface.py +0 -0
  151. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_definition/test_configuration.py +0 -0
  152. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_definition/test_misc.py +0 -0
  153. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_mat/test_motor.py +0 -0
  154. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_mat/test_motor_v1_2.py +0 -0
  155. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_single_cube/test_battery.py +0 -0
  156. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_single_cube/test_button.py +0 -0
  157. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_single_cube/test_configuration.py +0 -0
  158. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_single_cube/test_connect.py +0 -0
  159. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_single_cube/test_connection_interval_v1_2.py +0 -0
  160. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tests/test_50_single_cube/test_sound.py +0 -0
  161. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/coordinate_systems.py +0 -0
  162. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/__init__.py +0 -0
  163. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/base_class.py +0 -0
  164. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/api/battery.py +0 -0
  165. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/multi_cubes.py +0 -0
  166. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/cube/notification_handler_info.py +0 -0
  167. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/__init__.py +0 -0
  168. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/dummy.py +0 -0
  169. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/device_interface/pythonista3corebluetooth/__init__.py +0 -0
  170. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/logger.py +0 -0
  171. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/position.py +0 -0
  172. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/py.typed +0 -0
  173. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/scanner/__init__.py +0 -0
  174. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/scanner/ble.py +0 -0
  175. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/scanner/platform/windows_ble.py +0 -0
  176. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/simple/__init__.py +0 -0
  177. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/simple/async_simple.py +0 -0
  178. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/standard_id.py +0 -0
  179. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/toio_uuid.py +0 -0
  180. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/toio/utility.py +0 -0
  181. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tutorial/tutorial.en.py +0 -0
  182. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tutorial/tutorial.ja.py +0 -0
  183. {toio_py_fork-1.1.0.post2.dev2 → toio_py_fork-1.1.0.post2.dev3}/tutorial/tutorial.zh.py +0 -0
@@ -29,6 +29,8 @@
29
29
  - `best` / `quick` の scanner strategy 動作。
30
30
  - `CubeInfo` からの `ToioCoreCube` 初期化。
31
31
  - この fork 専用の changelog を追加しました。
32
+ - `objc_util` のスタブを使う、Pythonista3 向け CoreBluetooth バックエンドの definition テストを追加しました。
33
+ - scanner strategy と、`CubeInfo` からの `ToioCoreCube` 初期化の実機テストを追加しました。
32
34
 
33
35
  ### 変更
34
36
 
@@ -41,6 +43,8 @@
41
43
  - Bleak の requirement を `bleak>=3,<4` に更新しました。
42
44
  - development dependency group から Poetry 自体を削除しました。
43
45
  - uv ベースの project layout に合わせて tests と tooling metadata を更新しました。
46
+ - Pythonista3 向け CoreBluetooth バックエンドを Bleak 3 に対応させました。service、characteristic、descriptor のラッパーと KVO の監視を削除し、Bleak 3 の接続、スキャナ、エラーの API に合わせています。
47
+ - Pythonista3 用インストーラが `toio-py-fork` と Bleak 3.0.2 をインストールし、サンプルを `toio.py-fork` のドキュメントサイトから取得するようにしました。
44
48
 
45
49
  ### 修正
46
50
 
@@ -56,6 +60,11 @@
56
60
  - README sample の古い argument や末尾の不要な空行を修正しました。
57
61
  - definition-only test 実行時に、実機 cube の setup を skip するよう修正しました。
58
62
  - `_cubes.py` を生成する test helper command で、正しい script path を使い path を安全に quote するよう修正しました。
63
+ - 削除済みの `_RawAdvData` を import していた WinRT の古い回避コードを削除し、Bleak 3 の Windows でスキャンできるよう修正しました。
64
+ - `BleCube.connected` が常に `bool` を保持するよう修正しました。
65
+ - `_cubes.py` を再生成する実機テストの実行で、前回ではなく再生成後のキューブ一覧を使うよう修正しました。
66
+ - Windows での `_cubes.py` の生成を修正しました。
67
+ - 通常の `pytest` の実行が同名モジュールで止まらないよう、対話型の savable configuration テストの名前を変更しました。
59
68
 
60
69
  ### ドキュメント
61
70
 
@@ -28,6 +28,8 @@ For the upstream project changelog, see [CHANGELOG.md](./CHANGELOG.md).
28
28
  - Scanner strategy behavior for `best` and `quick`.
29
29
  - `ToioCoreCube` initialization from `CubeInfo`.
30
30
  - Added this fork-specific changelog.
31
+ - Added definition-level tests for the Pythonista3 CoreBluetooth backend, using an `objc_util` stub.
32
+ - Added real-cube tests for the scanner strategies and for `ToioCoreCube` initialization from `CubeInfo`.
31
33
 
32
34
  ### Changed
33
35
 
@@ -40,6 +42,8 @@ For the upstream project changelog, see [CHANGELOG.md](./CHANGELOG.md).
40
42
  - Updated the Bleak requirement to `bleak>=3,<4`.
41
43
  - Removed Poetry itself from the development dependency group.
42
44
  - Updated tests and tooling metadata for the uv-based project layout.
45
+ - Updated the Pythonista3 CoreBluetooth backend for Bleak 3: removed its service, characteristic and descriptor wrappers and its KVO observer, and followed the Bleak 3 connection, scanner and error APIs.
46
+ - Changed the Pythonista3 installer to install `toio-py-fork` and Bleak 3.0.2, and to download the examples from the `toio.py-fork` documentation site.
43
47
 
44
48
  ### Fixed
45
49
 
@@ -55,6 +59,11 @@ For the upstream project changelog, see [CHANGELOG.md](./CHANGELOG.md).
55
59
  - Fixed README sample cleanup issues, including outdated arguments and trailing blank lines.
56
60
  - Fixed definition-only test runs so they skip physical cube setup.
57
61
  - Fixed the test helper command that generates `_cubes.py` to use the correct script path and safely quote paths.
62
+ - Fixed scanning on Windows with Bleak 3 by removing the obsolete WinRT advertisement workaround, which imported the removed `_RawAdvData`.
63
+ - Fixed `BleCube.connected` to always hold a `bool`.
64
+ - Fixed hardware test runs that regenerate `_cubes.py` so that they use the regenerated cube list instead of the previous one.
65
+ - Fixed the generation of `_cubes.py` on Windows.
66
+ - Renamed the interactive savable configuration test so that a plain `pytest` run does not stop on a duplicate module name.
58
67
 
59
68
  ### Documentation
60
69
 
@@ -7,7 +7,7 @@ Before contributing to toio.py, please read our [Code of Conduct](./CODE_OF_COND
7
7
 
8
8
  ### Setup
9
9
 
10
- 1. [Install poetry](https://python-poetry.org/docs/#installing-with-the-official-installer)
10
+ 1. [Install uv](https://docs.astral.sh/uv/getting-started/installation/)
11
11
 
12
12
  2. Clone the toio.py repository
13
13
 
@@ -15,11 +15,11 @@ Before contributing to toio.py, please read our [Code of Conduct](./CODE_OF_COND
15
15
  git clone https://github.com/kaz399/toio.py-fork
16
16
  ```
17
17
 
18
- 3. Run `poetry install` in toio.py repository
18
+ 3. Run `uv sync` in toio.py repository
19
19
 
20
20
  ```
21
21
  cd toio.py-fork
22
- poetry install
22
+ uv sync
23
23
  ```
24
24
 
25
25
  ### Lint and format
@@ -29,8 +29,8 @@ poetry install
29
29
  [`black`](https://black.readthedocs.io/en/stable/) and [`isort`](https://pycqa.github.io/isort/) is used in this project.
30
30
 
31
31
  ```
32
- poetry run black
33
- poetry run isort
32
+ uv run black
33
+ uv run isort
34
34
  ```
35
35
 
36
36
  #### Optional:
@@ -38,11 +38,11 @@ poetry run isort
38
38
  Checking with [`flake8`](https://flake8.pycqa.org/en/latest/) or [`mypy`](https://www.mypy-lang.org/) is recommended.
39
39
 
40
40
  ```
41
- poetry run flake8
41
+ uv run flake8
42
42
  ```
43
43
 
44
44
  ```
45
- poetry run mypy
45
+ uv run mypy
46
46
  ```
47
47
 
48
48
 
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: toio-py-fork
3
- Version: 1.1.0.post2.dev2
3
+ Version: 1.1.0.post2.dev3
4
4
  Summary: Unofficial maintained fork of toio.py for controlling toio Core Cube
5
5
  Project-URL: Homepage, https://github.com/kaz399/toio.py-fork
6
6
  Project-URL: Documentation, https://kaz399.github.io/toio.py-fork/
@@ -79,9 +79,12 @@ uv run coverage report
79
79
  主な確認内容:
80
80
 
81
81
  - mock した Bleak client を使った BLE connection state handling。
82
- - collision detection threshold command を含む configuration command byte の生成。
83
- - `best` と `quick` の scanner strategy 動作。
82
+ - collision detection threshold command を含む configuration および indicator command の
83
+ byte 生成と response の parse。
84
+ - `best` と `quick` の scanner strategy 動作と、cube initializer が受け付ける
85
+ scanner のキーワード引数。
84
86
  - `CubeInfo` からの `ToioCoreCube` 初期化。
87
+ - 姿勢角 notification の sensor payload dispatch。
85
88
  - BLE hardware なしで確認できる definition や import-level の挙動。
86
89
 
87
90
  CI やローカルでの regression check では、このテストグループを最初に実行するのが安全です。
@@ -106,6 +109,7 @@ CI やローカルでの regression check では、このテストグループ
106
109
  主な確認内容:
107
110
 
108
111
  - 複数 cube がある場合の scanner behavior。
112
+ - `best` と `quick` の scan strategy とそのタイミング。
109
113
  - RSSI と local name による sort。
110
114
  - cube ID と BLE address による scan。
111
115
  - scan 結果からの `ToioCoreCube` instance 作成。
@@ -388,7 +392,8 @@ cube button を押さないでください。button press は中断扱いにな
388
392
  ### `tests/test_11_cube_off`
389
393
 
390
394
  特定の cube だけが電源 ON の状態での cube discovery behavior を確認する hardware test
391
- です。手動で cube の電源状態を操作する必要があります。
395
+ です。remote power off command で片方の cube の電源を落とすため、開始時には 2 台の
396
+ cube の電源を入れておく必要があります。
392
397
 
393
398
  ## Cube 設定ファイル
394
399
 
@@ -80,10 +80,12 @@ Definition-level tests that do not require physical cubes.
80
80
  Coverage includes:
81
81
 
82
82
  - BLE connection state handling with mocked Bleak clients.
83
- - Configuration command byte generation, including collision detection
84
- threshold commands.
85
- - Scanner strategy behavior for `best` and `quick`.
83
+ - Command byte generation and response parsing for the configuration and
84
+ indicator commands, including the collision detection threshold command.
85
+ - Scanner strategy behavior for `best` and `quick`, and the scanner keyword
86
+ arguments accepted by the cube initializers.
86
87
  - `ToioCoreCube` initialization from `CubeInfo`.
88
+ - Sensor payload dispatch for the posture angle notifications.
87
89
  - Definition and import-level behavior that can be checked without BLE
88
90
  hardware.
89
91
 
@@ -109,6 +111,7 @@ Two-cube hardware tests.
109
111
  Coverage includes:
110
112
 
111
113
  - Scanner behavior with multiple cubes.
114
+ - Scan strategies `best` and `quick`, including their timing.
112
115
  - Sorting by RSSI and local name.
113
116
  - Scanning by cube ID and BLE address.
114
117
  - Creating one or more `ToioCoreCube` instances from scanned cube data.
@@ -422,7 +425,8 @@ connected.
422
425
  ### `tests/test_11_cube_off`
423
426
 
424
427
  Hardware tests for cube discovery behavior when only selected cubes are powered
425
- on. These tests require manual cube power-state control.
428
+ on. The test powers one cube down through the remote power off command, so two
429
+ powered-on cubes are needed at the start of the run.
426
430
 
427
431
  ## Cube Configuration File
428
432
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "toio-py-fork"
3
- version = "1.1.0.post2.dev2"
3
+ version = "1.1.0.post2.dev3"
4
4
  description = "Unofficial maintained fork of toio.py for controlling toio Core Cube"
5
5
  authors = [
6
6
  {name = "Sony Interactive Entertainment"},
@@ -13,10 +13,6 @@ import shutil
13
13
  import sys
14
14
  import zipfile
15
15
 
16
- import requests
17
-
18
- from packaging.version import Version, parse
19
-
20
16
  site_packages_dir = ""
21
17
  DEVELOPMENT_MODE = False
22
18
 
@@ -29,14 +25,20 @@ if sys.platform != "ios":
29
25
  else:
30
26
  exit(1)
31
27
 
28
+ # Imported here so that an unsupported platform gets the message above, not an
29
+ # ImportError.
30
+ import requests
31
+
32
+ from packaging.version import Version, parse
33
+
32
34
 
33
35
  def get_latest_toio_py(min="1.1.0a1", max="1.2.0"):
34
36
  min_ver = parse(min)
35
37
  max_ver = parse(max)
36
38
  latest = Version("0.0.0")
37
39
  found_specified_version = False
38
- query = "https://pypi.org/pypi/toio-py/json"
39
- # query = "https://test.pypi.org/pypi/toio-py/json"
40
+ query = "https://pypi.org/pypi/${TOIO_PY_PACKAGE}/json"
41
+ # query = "https://test.pypi.org/pypi/${TOIO_PY_PACKAGE}/json"
40
42
  result = requests.get(query).json()
41
43
  # search latest version
42
44
  releases = result["releases"]
@@ -59,17 +61,28 @@ def get_latest_toio_py(min="1.1.0a1", max="1.2.0"):
59
61
  fetch_url = True
60
62
  if fetch_url and key == "url":
61
63
  return value
64
+ print("wheel of toio.py %s is not found" % latest)
65
+ return None
66
+
67
+
68
+ TOIO_PY_WHL = get_latest_toio_py()
69
+ if TOIO_PY_WHL is None:
70
+ # Stop before the cleanup, which would remove the working installation.
71
+ print("installation is cancelled: nothing has been changed")
72
+ exit(1)
62
73
 
63
74
  REQUIRED_WHLS = (
64
75
  "https://files.pythonhosted.org/packages/01/f3/936e209267d6ef7510322191003885de524fc48d1b43269810cd589ceaf5/typing_extensions-4.11.0-py3-none-any.whl",
65
- "https://files.pythonhosted.org/packages/ac/c8/576a25c20d5619576a82b6ec28df9f1d4c867e4fe801531f7d9bb9f49db7/bleak-0.22.1-py3-none-any.whl",
66
- get_latest_toio_py()
76
+ "https://files.pythonhosted.org/packages/26/54/05aceb9cd80073805b3ed8522e3196e8cb22f70e741873fa51406c31f4e7/bleak-3.0.2-py3-none-any.whl",
77
+ TOIO_PY_WHL,
67
78
  )
68
79
 
69
80
  CLEANUP_TARGETS = (
70
81
  "typing_extensions",
71
82
  "bleak",
72
83
  "toio",
84
+ "toio_py",
85
+ "toio_py_fork",
73
86
  )
74
87
 
75
88
  EXAMPLES = (
@@ -81,6 +94,28 @@ ${EXAMPLE_SIMPLE_FILES}
81
94
  )
82
95
 
83
96
 
97
+
98
+ def is_cleanup_target(filename):
99
+ # Compare the whole name: other packages may have "toio" in their names.
100
+ # "bleak-3.0.2.dist-info" and "typing_extensions.py" have the suffix removed.
101
+ return filename.split("-")[0].split(".")[0] in CLEANUP_TARGETS
102
+
103
+
104
+ def install_examples(urls, directory, description):
105
+ os.makedirs(directory, exist_ok=True)
106
+ for url in urls:
107
+ filename = url.split("/")[-1]
108
+ path = os.path.join(directory, filename)
109
+ # An existing file is kept because the user may have edited it.
110
+ if os.path.exists(path):
111
+ print("SKIP: %s is already installed" % filename)
112
+ continue
113
+ print("install %s: %s" % (description, filename))
114
+ data = requests.get(url).content
115
+ with open(path, "wb") as wfh:
116
+ wfh.write(data)
117
+
118
+
84
119
  if not DEVELOPMENT_MODE:
85
120
  for p in sys.path:
86
121
  if p.endswith("site-packages"):
@@ -102,44 +137,24 @@ print("------------------------------------------------------------")
102
137
  os.makedirs(site_packages_dir, exist_ok=True)
103
138
  print("clean previous installation")
104
139
  for filename in os.listdir(site_packages_dir):
105
- for cleanup in CLEANUP_TARGETS:
106
- if cleanup in filename:
107
- print("clean: %s" % filename)
108
- remove_target = os.path.normpath(os.path.join(site_packages_dir, filename))
109
- if os.path.isdir(remove_target):
110
- shutil.rmtree(remove_target)
111
- else:
112
- os.remove(remove_target)
140
+ if is_cleanup_target(filename):
141
+ print("clean: %s" % filename)
142
+ remove_target = os.path.normpath(os.path.join(site_packages_dir, filename))
143
+ if os.path.isdir(remove_target):
144
+ shutil.rmtree(remove_target)
145
+ else:
146
+ os.remove(remove_target)
113
147
  print("------------------------------------------------------------")
114
148
  print("install packages")
115
149
  for whl in REQUIRED_WHLS:
116
- if whl is not None:
117
- print("install module: %s" % whl.split("/")[-1])
118
- zipfile.ZipFile(io.BytesIO(requests.get(whl).content)).extractall(site_packages_dir)
150
+ print("install module: %s" % whl.split("/")[-1])
151
+ zipfile.ZipFile(io.BytesIO(requests.get(whl).content)).extractall(site_packages_dir)
119
152
  print("------------------------------------------------------------")
120
153
  print("install examples")
121
- if not os.path.isdir(examples_dir):
122
- os.makedirs(examples_dir, exist_ok=True)
123
- for example in EXAMPLES:
124
- filename = example.split("/")[-1]
125
- print("install toio.py example: %s" % filename)
126
- data = requests.get(example).content
127
- with open(os.path.join(examples_dir, filename), "wb") as wfh:
128
- wfh.write(data)
129
- else:
130
- print("SKIP: example files are already installed")
154
+ install_examples(EXAMPLES, examples_dir, "toio.py example")
131
155
  print("------------------------------------------------------------")
132
156
  print("install examples-simple")
133
- if not os.path.isdir(examples_simple_dir):
134
- os.makedirs(examples_simple_dir, exist_ok=True)
135
- for example in EXAMPLES_SIMPLE:
136
- filename = example.split("/")[-1]
137
- print("install toio.py example (simple API): %s" % filename)
138
- data = requests.get(example).content
139
- with open(os.path.join(examples_simple_dir, filename), "wb") as wfh:
140
- wfh.write(data)
141
- else:
142
- print("SKIP: example files are already installed")
157
+ install_examples(EXAMPLES_SIMPLE, examples_simple_dir, "toio.py example (simple API)")
143
158
  print("------------------------------------------------------------")
144
159
  print("install completed")
145
160
  print("")
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+ set -euo pipefail
3
+
4
+ if [ "$#" -ne 1 ]; then
5
+ echo "usage: $0 <output file>" >&2
6
+ exit 1
7
+ fi
8
+
9
+ if ! command -v envsubst > /dev/null; then
10
+ echo "envsubst is required (it is included in gettext)" >&2
11
+ exit 1
12
+ fi
13
+
14
+ SCRIPT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" && pwd)
15
+ REPO_TOP=$(git rev-parse --show-toplevel)
16
+
17
+ TOIO_PY_PACKAGE="toio-py-fork"
18
+ DOWNLOAD_BASE_URL="https://kaz399.github.io/toio.py-fork"
19
+ DOWNLOAD_URL="${DOWNLOAD_BASE_URL}/examples"
20
+ DOWNLOAD_URL_SIMPLE="${DOWNLOAD_BASE_URL}/examples-simple"
21
+ EXAMPLES_DIR="${REPO_TOP}/docs/examples"
22
+ EXAMPLES_SIMPLE_DIR="${REPO_TOP}/docs/examples-simple"
23
+
24
+ function examples() {
25
+ local directory="${1}"
26
+ local url="${2}"
27
+ local pyfile
28
+ for pyfile in "${directory}"/*.py ; do
29
+ echo " \"${url}/$(basename "${pyfile}")\","
30
+ done
31
+ }
32
+
33
+ EXAMPLE_FILES=$(examples "${EXAMPLES_DIR}" "${DOWNLOAD_URL}")
34
+ EXAMPLE_SIMPLE_FILES=$(examples "${EXAMPLES_SIMPLE_DIR}" "${DOWNLOAD_URL_SIMPLE}")
35
+ export TOIO_PY_PACKAGE EXAMPLE_FILES EXAMPLE_SIMPLE_FILES
36
+
37
+ # Only these variables are replaced, so a "$" in the template stays as it is.
38
+ # shellcheck disable=SC2016
39
+ envsubst '${TOIO_PY_PACKAGE} ${EXAMPLE_FILES} ${EXAMPLE_SIMPLE_FILES}' \
40
+ < "${SCRIPT_DIR}/install_toio.py.in" > "${1}"
@@ -8,7 +8,9 @@
8
8
  # ************************************************************
9
9
 
10
10
  import os
11
- import shlex
11
+ import runpy
12
+ import subprocess
13
+ import sys
12
14
  import time
13
15
  from pathlib import Path
14
16
  from logging import getLogger
@@ -18,6 +20,9 @@ from colorama import Back, Fore, Style, init
18
20
 
19
21
  logger = getLogger(__name__)
20
22
 
23
+ DEFINITION_TEST_DIR = "test_50_definition"
24
+ CUBE_FILE = os.path.join(os.path.dirname(__file__), "_cubes.py")
25
+
21
26
 
22
27
  @pytest.fixture(scope="function", autouse=True)
23
28
  def wait():
@@ -28,12 +33,12 @@ def wait():
28
33
  def setup(pytestconfig):
29
34
  init()
30
35
  capmanager = pytestconfig.pluginmanager.getplugin("capturemanager")
31
- selected_paths = [
32
- Path(arg)
33
- for arg in pytestconfig.invocation_params.args
34
- if not arg.startswith("-")
35
- ]
36
- if selected_paths and all("test_50_definition" in path.parts for path in selected_paths):
36
+ # config.args holds only the resolved test paths (or testpaths when the
37
+ # command line selects nothing). invocation_params.args cannot be used
38
+ # here because it also contains option values such as the
39
+ # "no:cacheprovider" of "-p no:cacheprovider".
40
+ selected = [Path(arg) for arg in pytestconfig.args]
41
+ if selected and all(DEFINITION_TEST_DIR in path.parts for path in selected):
37
42
  logger.info("** skip cube setup for definition-only tests")
38
43
  return
39
44
 
@@ -59,14 +64,11 @@ def setup(pytestconfig):
59
64
  capmanager.resume_global_capture()
60
65
  logger.info("%s", yn)
61
66
  test_dir = os.path.dirname(__file__)
62
- cube_file = os.path.join(test_dir, "_cubes.py")
63
67
  make_cube_list = os.path.join(test_dir, "make_cube_list.py")
64
68
  if yn.lower() != "s":
65
69
  logger.info("** GENERATE _cubes.py")
66
- result = os.system(
67
- f"python {shlex.quote(make_cube_list)} {shlex.quote(cube_file)}"
68
- )
69
- if result:
70
+ result = subprocess.run([sys.executable, make_cube_list, CUBE_FILE])
71
+ if result.returncode:
70
72
  logger.info(
71
73
  Fore.RED
72
74
  + "** 2 cubes are not found. _cubes.py is not updated"
@@ -75,10 +77,18 @@ def setup(pytestconfig):
75
77
  else:
76
78
  logger.info(Fore.YELLOW + "** skip to generate _cubes.py" + Style.RESET_ALL)
77
79
  logger.info("** cubes used in this test:")
78
- with open(cube_file, "r") as rf:
80
+ with open(CUBE_FILE, "r") as rf:
79
81
  logger.info("\n" + rf.read())
80
82
 
81
83
 
84
+ @pytest.fixture(scope="session")
85
+ def cubes(setup):
86
+ # Test modules must not import _cubes.py: they are imported during
87
+ # collection, before setup can regenerate the file, so they would keep
88
+ # the cubes of the previous run.
89
+ return runpy.run_path(CUBE_FILE)["CUBES"]
90
+
91
+
82
92
  @pytest.fixture(scope="function")
83
93
  def confirm(pytestconfig):
84
94
  capmanager = pytestconfig.pluginmanager.getplugin("capturemanager")
@@ -28,9 +28,11 @@ async def main(argv):
28
28
  else:
29
29
  if len(argv) >= 2:
30
30
  wfh = open(argv[1], "w")
31
+ output_file = argv[1]
31
32
  else:
32
33
  wfh = sys.stdout
33
- sys.stderr.write("generate cube list: '%s'\n" % argv[1])
34
+ output_file = "stdout"
35
+ sys.stderr.write("generate cube list: '%s'\n" % output_file)
34
36
  wfh.write("from typing import Dict, List\n")
35
37
  wfh.write("\n")
36
38
  wfh.write("CUBES: List[Dict[str, str]] = [\n")
@@ -113,3 +113,24 @@ async def test_connect_7():
113
113
  logger.info("** DISCONNECT")
114
114
  await cube.disconnect()
115
115
  logger.info(warn[0].message)
116
+
117
+
118
+ @pytest.mark.asyncio
119
+ async def test_connect_cube_info():
120
+ device_list = await BLEScanner.scan(2)
121
+ assert len(device_list) == 2
122
+ cubes = [ToioCoreCube(cube_info) for cube_info in device_list]
123
+ assert [cube.name for cube in cubes] == [d.name for d in device_list]
124
+ logger.info("** CONNECTING...")
125
+ for cube in cubes:
126
+ await cube.connect()
127
+ assert cube.is_connect()
128
+ logger.info("** CONNECTED")
129
+ for i, cube in enumerate(cubes):
130
+ pos = await cube.api.id_information.read()
131
+ logger.info("cube[%d]: %s", i, str(pos))
132
+ logger.info("** DISCONNECTING")
133
+ for cube in cubes:
134
+ await cube.disconnect()
135
+ assert not cube.is_connect()
136
+ logger.info("** DISCONNECTED")