pymodaq 5.0.13__tar.gz → 5.0.15__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.

Potentially problematic release.


This version of pymodaq might be problematic. Click here for more details.

Files changed (122) hide show
  1. {pymodaq-5.0.13 → pymodaq-5.0.15}/PKG-INFO +2 -2
  2. {pymodaq-5.0.13 → pymodaq-5.0.15}/pyproject.toml +1 -1
  3. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/dashboard.py +12 -54
  4. pymodaq-5.0.13/src/pymodaq/updater.py +0 -107
  5. {pymodaq-5.0.13 → pymodaq-5.0.15}/.gitignore +0 -0
  6. {pymodaq-5.0.13 → pymodaq-5.0.15}/LICENSE +0 -0
  7. {pymodaq-5.0.13 → pymodaq-5.0.15}/README.rst +0 -0
  8. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/__init__.py +0 -0
  9. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/__init__.py +0 -0
  10. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/daq_move.py +0 -0
  11. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/daq_move_ui.py +0 -0
  12. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/daq_viewer.py +0 -0
  13. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/daq_viewer_ui.py +0 -0
  14. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/mocks.py +0 -0
  15. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/move_utility_classes.py +0 -0
  16. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/utils.py +0 -0
  17. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/control_modules/viewer_utility_classes.py +0 -0
  18. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/daq_utils/__init__.py +0 -0
  19. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/daq_utils/daq_utils.py +0 -0
  20. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.aliases +0 -0
  21. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvlps +0 -0
  22. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.lvproj +0 -0
  23. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Client.vi +0 -0
  24. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_1Dgaussian.vi +0 -0
  25. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_Server_2Dgaussian.vi +0 -0
  26. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_cmd.vi +0 -0
  27. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_float.vi +0 -0
  28. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_read_int.vi +0 -0
  29. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_data.vi +0 -0
  30. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_int.vi +0 -0
  31. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_scalar.vi +0 -0
  32. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/DAQ_TCP_send_string.vi +0 -0
  33. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/client_state.ctl +0 -0
  34. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/Labview_TCP_Client/cmd_types.ctl +0 -0
  35. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/__init__.py +0 -0
  36. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/function_plotter.py +0 -0
  37. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/nonlinearscanner.py +0 -0
  38. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/qt_less_standalone_module.py +0 -0
  39. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/examples/tcp_client.py +0 -0
  40. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/__init__.py +0 -0
  41. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/bayesian/__init__.py +0 -0
  42. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/bayesian/bayesian_optimisation.py +0 -0
  43. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/bayesian/utils.py +0 -0
  44. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/console.py +0 -0
  45. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_logger/__init__.py +0 -0
  46. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_logger/abstract.py +0 -0
  47. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_logger/daq_logger.py +0 -0
  48. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_logger/db/__init__.py +0 -0
  49. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_logger/db/db_logger.py +0 -0
  50. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_logger/db/db_logger_models.py +0 -0
  51. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_logger/h5logging.py +0 -0
  52. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_scan.py +0 -0
  53. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/daq_scan_ui.py +0 -0
  54. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/h5browser.py +0 -0
  55. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/pid/__init__.py +0 -0
  56. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/pid/actuator_controller.py +0 -0
  57. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/pid/daq_move_PID.py +0 -0
  58. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/pid/pid_controller.py +0 -0
  59. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/pid/utils.py +0 -0
  60. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/extensions/utils.py +0 -0
  61. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/icon.ico +0 -0
  62. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/post_treatment/__init__.py +0 -0
  63. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/post_treatment/load_and_plot.py +0 -0
  64. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/resources/__init__.py +0 -0
  65. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/resources/preset_default.xml +0 -0
  66. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/resources/setup_plugin.py +0 -0
  67. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/splash.png +0 -0
  68. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/__init__.py +0 -0
  69. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/array_manipulation.py +0 -0
  70. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/calibration_camera.py +0 -0
  71. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/chrono_timer.py +0 -0
  72. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/config.py +0 -0
  73. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/conftests.py +0 -0
  74. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/daq_utils.py +0 -0
  75. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/data.py +0 -0
  76. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/enums.py +0 -0
  77. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/exceptions.py +0 -0
  78. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/gui_utils/__init__.py +0 -0
  79. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/gui_utils/loader_utils.py +0 -0
  80. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/gui_utils/utils.py +0 -0
  81. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/gui_utils/widgets/lcd.py +0 -0
  82. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/h5modules/__init__.py +0 -0
  83. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/h5modules/module_saving.py +0 -0
  84. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/leco/__init__.py +0 -0
  85. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/leco/daq_move_LECODirector.py +0 -0
  86. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/leco/daq_xDviewer_LECODirector.py +0 -0
  87. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/leco/desktop.ini +0 -0
  88. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/leco/director_utils.py +0 -0
  89. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/leco/leco_director.py +0 -0
  90. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/leco/pymodaq_listener.py +0 -0
  91. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/leco/utils.py +0 -0
  92. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/logger.py +0 -0
  93. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/managers/__init__.py +0 -0
  94. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/managers/batchscan_manager.py +0 -0
  95. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/managers/modules_manager.py +0 -0
  96. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/managers/overshoot_manager.py +0 -0
  97. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/managers/preset_manager.py +0 -0
  98. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/managers/preset_manager_utils.py +0 -0
  99. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/managers/remote_manager.py +0 -0
  100. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/math_utils.py +0 -0
  101. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/messenger.py +0 -0
  102. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/parameter/__init__.py +0 -0
  103. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/parameter/utils.py +0 -0
  104. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/__init__.py +0 -0
  105. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scan_config.py +0 -0
  106. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scan_factory.py +0 -0
  107. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scan_selector.py +0 -0
  108. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scanner.py +0 -0
  109. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scanners/_1d_scanners.py +0 -0
  110. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scanners/_2d_scanners.py +0 -0
  111. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scanners/__init__.py +0 -0
  112. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scanners/sequential.py +0 -0
  113. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/scanners/tabular.py +0 -0
  114. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/scanner/utils.py +0 -0
  115. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/svg/__init__.py +0 -0
  116. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/svg/svg_renderer.py +0 -0
  117. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/svg/svg_view.py +0 -0
  118. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/svg/svg_viewer2D.py +0 -0
  119. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/tcp_ip/__init__.py +0 -0
  120. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/tcp_ip/mysocket.py +0 -0
  121. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/tcp_ip/serializer.py +0 -0
  122. {pymodaq-5.0.13 → pymodaq-5.0.15}/src/pymodaq/utils/tcp_ip/tcp_server_client.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pymodaq
3
- Version: 5.0.13
3
+ Version: 5.0.15
4
4
  Summary: Modular Data Acquisition with Python
5
5
  Project-URL: Homepage, http://pymodaq.cnrs.fr
6
6
  Project-URL: Source, https://github.com/PyMoDAQ/PyMoDAQ
@@ -49,7 +49,7 @@ Requires-Dist: multipledispatch
49
49
  Requires-Dist: numpy<2.0.0
50
50
  Requires-Dist: packaging
51
51
  Requires-Dist: pint
52
- Requires-Dist: pyleco>0.3; python_version >= '3.8'
52
+ Requires-Dist: pyleco<=0.4.2,>0.3; python_version >= '3.8'
53
53
  Requires-Dist: pymodaq-data>=5.0.18
54
54
  Requires-Dist: pymodaq-gui<5.0.23,>=5.0.17
55
55
  Requires-Dist: pymodaq-plugin-manager>=0.0.17
@@ -49,7 +49,7 @@ dependencies = [
49
49
  "simple_pid",
50
50
  "toml",
51
51
  "qtconsole",
52
- "pyleco>0.3; python_version>=\"3.8\"",
52
+ "pyleco>0.3, <=0.4.2; python_version>=\"3.8\"",
53
53
  "bayesian-optimization<2.0.0",
54
54
  ]
55
55
 
@@ -79,44 +79,19 @@ class PymodaqUpdateTableWidget(QTableWidget):
79
79
  '''
80
80
  def __init__(self):
81
81
  super().__init__()
82
-
83
- self._checkboxes = []
84
- self._package_versions = []
82
+ self._row = 0
85
83
 
86
84
  def setHorizontalHeaderLabels(self, labels):
87
85
  super().setHorizontalHeaderLabels(labels)
88
86
  self.setColumnCount(len(labels))
89
87
 
90
- def append_row(self, checkbox, package, current_version, available_version):
91
- row = len(self._checkboxes)
92
-
93
- self._checkboxes.append(checkbox)
94
- self._package_versions.append(f'{package}=={available_version}')
95
-
96
- checkbox_widget = QWidget()
97
-
98
- checkbox.setChecked(True)
99
- checkbox.setToolTip("Check to install update")
100
-
101
- checkbox_layout = QtWidgets.QHBoxLayout()
102
- checkbox_layout.addWidget(checkbox)
103
- checkbox_layout.setAlignment(Qt.AlignCenter)
104
- checkbox_layout.setContentsMargins(0, 0, 0, 0)
105
-
106
- checkbox_widget.setLayout(checkbox_layout)
88
+ def append_row(self, package, current_version, available_version):
89
+ # Add labels
90
+ self.setItem(self._row, 0, QTableWidgetItem(str(package)))
91
+ self.setItem(self._row, 1, QTableWidgetItem(str(current_version)))
92
+ self.setItem(self._row, 2, QTableWidgetItem(str(available_version)))
107
93
 
108
- # Add the checkbox widget to the table
109
- self.setCellWidget(row, 0, checkbox_widget)
110
-
111
- # Add labels in the other columns
112
- self.setItem(row, 1, QTableWidgetItem(str(package)))
113
- self.setItem(row, 2, QTableWidgetItem(str(current_version)))
114
- self.setItem(row, 3, QTableWidgetItem(str(available_version)))
115
-
116
-
117
- def get_checked_data(self):
118
- checked = list(map(lambda c : c.isChecked(), self._checkboxes))
119
- return list(np.array(self._package_versions)[checked])
94
+ self._row += 1
120
95
 
121
96
  def sizeHint(self):
122
97
  self.resizeColumnsToContents()
@@ -1620,11 +1595,10 @@ class DashBoard(CustomApp):
1620
1595
  available_versions = [version_mod.parse(get_pypi_pymodaq(p)['version']) for p in packages]
1621
1596
  new_versions = np.greater(available_versions, current_versions)
1622
1597
  # Combine package and version information and select only the ones with a newer version available
1623
-
1598
+
1624
1599
 
1625
1600
  packages_data = np.array(list(zip(packages, current_versions, available_versions)))[new_versions]
1626
1601
 
1627
- #TODO: Remove `or True`
1628
1602
  if len(packages_data) > 0:
1629
1603
  #Create a QDialog window and different graphical components
1630
1604
  dialog = QtWidgets.QDialog()
@@ -1632,43 +1606,27 @@ class DashBoard(CustomApp):
1632
1606
 
1633
1607
  vlayout = QtWidgets.QVBoxLayout()
1634
1608
 
1635
- message_label = QLabel("New versions of PyMoDAQ packages available!\nPlease select the ones you want to install:")
1609
+ message_label = QLabel("New versions of PyMoDAQ packages available!\nUse your package manager to update.")
1636
1610
  message_label.setAlignment(Qt.AlignCenter)
1637
1611
 
1638
1612
 
1639
1613
  table = PymodaqUpdateTableWidget()
1640
1614
  table.setRowCount(len(packages_data))
1641
- table.setColumnCount(4)
1642
- table.setHorizontalHeaderLabels(["Select", "Package", "Current version", "New version"])
1615
+ table.setColumnCount(3)
1616
+ table.setHorizontalHeaderLabels(["Package", "Current version", "New version"])
1643
1617
 
1644
1618
  for p in packages_data:
1645
- table.append_row(QCheckBox(), p[0], p[1], p[2])
1619
+ table.append_row(p[0], p[1], p[2])
1646
1620
 
1647
- button = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel)
1648
- button.accepted.connect(dialog.accept)
1649
- button.rejected.connect(dialog.reject)
1650
1621
 
1651
1622
  # The vlayout contains the message, the table and the buttons
1652
1623
  # and is connected to the dialog window
1653
1624
  vlayout.addWidget(message_label)
1654
1625
  vlayout.addWidget(table)
1655
- vlayout.addWidget(button)
1656
1626
  dialog.setLayout(vlayout)
1657
1627
 
1658
1628
  ret = dialog.exec()
1659
1629
 
1660
- if ret == QDialog.Accepted:
1661
- # If the update is accepted, the checked packages are extracted from the table
1662
- # and send to the updater
1663
- packages_to_update = table.get_checked_data()
1664
- if len(packages_to_update) > 0:
1665
- packages_to_update_str = ', '.join(packages_to_update)
1666
- logger.info("Trying to update:")
1667
- logger.info(f"\t {packages_to_update_str}")
1668
- subprocess.Popen(['pymodaq_updater', '--wait', '--file', __file__] + packages_to_update, stdin=subprocess.PIPE)
1669
- self.quit_fun()
1670
- return True
1671
- logger.info("Update found but no packages checked for update.")
1672
1630
  else:
1673
1631
  if show:
1674
1632
  msgBox = QtWidgets.QMessageBox()
@@ -1,107 +0,0 @@
1
- import argparse
2
- import subprocess
3
- import sys
4
- import time
5
- import logging
6
-
7
- from pathlib import Path
8
-
9
- from pymodaq_utils.logger import set_logger, get_module_name
10
-
11
- logger = set_logger(get_module_name(__file__))
12
- logger.addHandler(logging.StreamHandler(sys.stdout))
13
-
14
- def wait_for_parent():
15
- '''
16
- A function to wait for its parent to terminate execution.
17
-
18
- In order to achieve that, this process has to be started with
19
- stdin replaced by a piped stream from its parent. When the
20
- parent terminates, stdin will close and either return from read
21
- or throw an exception. De facto creating a way to wait for its
22
- parent's termination.
23
-
24
- It then sleep for 2 seconds, to let the parent process complete
25
- termination.
26
-
27
- CAUTION: If the process was not started by piping stdin AND
28
- the --wait option is set, this function will hang forever.
29
-
30
- We could use `psutil` or a similar lib to check for parent's process
31
- existance with its pid.
32
- '''
33
-
34
- logger.info("Waiting for parent process to stop.")
35
- try:
36
- sys.stdin.read()
37
- except:
38
- pass
39
- logger.debug("Parent process closed stdin")
40
- time.sleep(2)
41
- logger.info("Parent process stopped.")
42
-
43
- def process_args():
44
- '''
45
- Declare arguments for updater.py, parse them and returns them in an object.
46
- The arguments are:
47
- --file <file> to request a python program to (re)start after update if needed (optional)
48
- --wait to wait for the starting process to terminate before updating (optional, defaults to False)
49
- packages the package list to install/update (they should contain the version in a pip accepted format)
50
- '''
51
- parser = argparse.ArgumentParser(description='Update pymodaq using pip.')
52
- parser.add_argument('--file', type=str, help='the pymodaq script to restart after update')
53
- parser.add_argument("--wait", action="store_true", help="enable waiting for pymodaq to finish mode (default is disabled).")
54
- parser.add_argument('packages', type=str, nargs='+', help='package list')
55
- return parser.parse_args()
56
-
57
- def restart_if_command_launch(args):
58
- '''
59
- Try to detect if this process if launched using the declared command (i.e. `pymodaq_updater`)
60
- or using the script file (`updater.py`). If it uses the command, it restart the process to
61
- force it to use the script file, thus preventing a locked file during update on windows systems.
62
- '''
63
- python_file_path = Path(__file__) # Should be the path to `updater.py`
64
- started_path = Path(sys.argv[0]) # Either `updater.py` or `pymodaq_updater`
65
-
66
- # If they're different we'll restart using the script file
67
- if started_path.absolute() != python_file_path.absolute():
68
- logger.info("Started as pymodaq_updater, need to restart using python to prevent lock.")
69
- # We HAVE to wait for this process to stop in the restarted process
70
- new_args = ['--wait'] + sys.argv[1:]
71
- if args.wait:
72
- wait_for_parent()
73
-
74
- subprocess.Popen([sys.executable, str(python_file_path.absolute())] + new_args, stdin=subprocess.PIPE)
75
- sys.exit(0)
76
-
77
- def main():
78
- args = process_args()
79
- logger.info(f"Arguments processed: {args}")
80
-
81
- restart_if_command_launch(args)
82
-
83
- if args.wait:
84
- wait_for_parent()
85
-
86
- packages_str = ', '.join(args.packages)
87
- logger.info(f'Updating packages: {packages_str}')
88
-
89
- with subprocess.Popen([sys.executable, '-m', 'pip', 'install'] + args.packages, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as pip:
90
- for line in pip.stdout:
91
- # Can't decode as some characters are not valid and make the whole process fail
92
- logger.info(line[:-1])
93
- ret_code = pip.wait()
94
-
95
-
96
- if ret_code == 0:
97
- logger.info(f'Succesfully updated {packages_str}')
98
- else:
99
- logger.error(f'Error while updating {packages_str}, pip returned {ret_code}')
100
-
101
- if args.file is not None:
102
- logger.info(f"Restarting {args.file} script after update.")
103
- subprocess.Popen([sys.executable, args.file])
104
-
105
-
106
- if __name__ == "__main__":
107
- main()
File without changes
File without changes
File without changes
File without changes