psychopy 2024.2.5__py3-none-any.whl → 2025.1.1__py3-none-any.whl

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 psychopy might be problematic. Click here for more details.

Files changed (863) hide show
  1. psychopy/CHANGELOG.txt +4 -4
  2. psychopy/GIT_SHA +1 -1
  3. psychopy/LICENSE.txt +1 -1
  4. psychopy/VERSION +1 -1
  5. psychopy/__init__.py +10 -7
  6. psychopy/alerts/__init__.py +1 -1
  7. psychopy/alerts/_alerts.py +53 -17
  8. psychopy/alerts/_errorHandler.py +3 -4
  9. psychopy/alerts/alertsCatalogue/3210.yaml +27 -0
  10. psychopy/alerts/alertsCatalogue/3610.yaml +19 -0
  11. psychopy/alerts/alertsCatalogue/4130.yaml +19 -0
  12. psychopy/alerts/alertsCatalogue/alertCategories.yaml +8 -1
  13. psychopy/alerts/alertsCatalogue/alertmsg.py +1 -1
  14. psychopy/alerts/alerttools.py +0 -16
  15. psychopy/app/Resources/betasplash.png +0 -0
  16. psychopy/app/Resources/betasplash@2x.png +0 -0
  17. psychopy/app/Resources/classic/case.png +0 -0
  18. psychopy/app/Resources/classic/case@2x.png +0 -0
  19. psychopy/app/Resources/classic/fileaudio.png +0 -0
  20. psychopy/app/Resources/classic/fileaudio@2x.png +0 -0
  21. psychopy/app/Resources/classic/filecss.png +0 -0
  22. psychopy/app/Resources/classic/filecss@2x.png +0 -0
  23. psychopy/app/Resources/classic/filecsv.png +0 -0
  24. psychopy/app/Resources/classic/filecsv@2x.png +0 -0
  25. psychopy/app/Resources/classic/filedesign.png +0 -0
  26. psychopy/app/Resources/classic/filedesign@2x.png +0 -0
  27. psychopy/app/Resources/classic/filefont.png +0 -0
  28. psychopy/app/Resources/classic/filefont@2x.png +0 -0
  29. psychopy/app/Resources/classic/filegit.png +0 -0
  30. psychopy/app/Resources/classic/filegit@2x.png +0 -0
  31. psychopy/app/Resources/classic/filehtml.png +0 -0
  32. psychopy/app/Resources/classic/filehtml@2x.png +0 -0
  33. psychopy/app/Resources/classic/fileimage.png +0 -0
  34. psychopy/app/Resources/classic/fileimage@2x.png +0 -0
  35. psychopy/app/Resources/classic/fileinfo.png +0 -0
  36. psychopy/app/Resources/classic/fileinfo@2x.png +0 -0
  37. psychopy/app/Resources/classic/filejs.png +0 -0
  38. psychopy/app/Resources/classic/filejs@2x.png +0 -0
  39. psychopy/app/Resources/classic/filejson.png +0 -0
  40. psychopy/app/Resources/classic/filejson@2x.png +0 -0
  41. psychopy/app/Resources/classic/filepkg.png +0 -0
  42. psychopy/app/Resources/classic/filepkg@2x.png +0 -0
  43. psychopy/app/Resources/classic/filepsyexp.png +0 -0
  44. psychopy/app/Resources/classic/filepsyexp@2x.png +0 -0
  45. psychopy/app/Resources/classic/filepy.png +0 -0
  46. psychopy/app/Resources/classic/filepy@2x.png +0 -0
  47. psychopy/app/Resources/classic/filetxt.png +0 -0
  48. psychopy/app/Resources/classic/filetxt@2x.png +0 -0
  49. psychopy/app/Resources/classic/fileunknown.png +0 -0
  50. psychopy/app/Resources/classic/fileunknown@2x.png +0 -0
  51. psychopy/app/Resources/classic/filevideo.png +0 -0
  52. psychopy/app/Resources/classic/filevideo@2x.png +0 -0
  53. psychopy/app/Resources/classic/find.png +0 -0
  54. psychopy/app/Resources/classic/find@2x.png +0 -0
  55. psychopy/app/Resources/classic/loop.png +0 -0
  56. psychopy/app/Resources/classic/loop@2x.png +0 -0
  57. psychopy/app/Resources/classic/regex.png +0 -0
  58. psychopy/app/Resources/classic/regex@2x.png +0 -0
  59. psychopy/app/Resources/dark/case.png +0 -0
  60. psychopy/app/Resources/dark/case@2x.png +0 -0
  61. psychopy/app/Resources/dark/fileaudio.png +0 -0
  62. psychopy/app/Resources/dark/fileaudio@2x.png +0 -0
  63. psychopy/app/Resources/dark/filecss.png +0 -0
  64. psychopy/app/Resources/dark/filecss@2x.png +0 -0
  65. psychopy/app/Resources/dark/filecsv.png +0 -0
  66. psychopy/app/Resources/dark/filecsv@2x.png +0 -0
  67. psychopy/app/Resources/dark/filedesign.png +0 -0
  68. psychopy/app/Resources/dark/filedesign@2x.png +0 -0
  69. psychopy/app/Resources/dark/filefont.png +0 -0
  70. psychopy/app/Resources/dark/filefont@2x.png +0 -0
  71. psychopy/app/Resources/dark/filegit.png +0 -0
  72. psychopy/app/Resources/dark/filegit@2x.png +0 -0
  73. psychopy/app/Resources/dark/filehtml.png +0 -0
  74. psychopy/app/Resources/dark/filehtml@2x.png +0 -0
  75. psychopy/app/Resources/dark/fileimage.png +0 -0
  76. psychopy/app/Resources/dark/fileimage@2x.png +0 -0
  77. psychopy/app/Resources/dark/fileinfo.png +0 -0
  78. psychopy/app/Resources/dark/fileinfo@2x.png +0 -0
  79. psychopy/app/Resources/dark/filejs.png +0 -0
  80. psychopy/app/Resources/dark/filejs@2x.png +0 -0
  81. psychopy/app/Resources/dark/filejson.png +0 -0
  82. psychopy/app/Resources/dark/filejson@2x.png +0 -0
  83. psychopy/app/Resources/dark/filepkg.png +0 -0
  84. psychopy/app/Resources/dark/filepkg@2x.png +0 -0
  85. psychopy/app/Resources/dark/filepsyexp.png +0 -0
  86. psychopy/app/Resources/dark/filepsyexp@2x.png +0 -0
  87. psychopy/app/Resources/dark/filepy.png +0 -0
  88. psychopy/app/Resources/dark/filepy@2x.png +0 -0
  89. psychopy/app/Resources/dark/filetxt.png +0 -0
  90. psychopy/app/Resources/dark/filetxt@2x.png +0 -0
  91. psychopy/app/Resources/dark/fileunknown.png +0 -0
  92. psychopy/app/Resources/dark/fileunknown@2x.png +0 -0
  93. psychopy/app/Resources/dark/filevideo.png +0 -0
  94. psychopy/app/Resources/dark/filevideo@2x.png +0 -0
  95. psychopy/app/Resources/dark/find.png +0 -0
  96. psychopy/app/Resources/dark/find@2x.png +0 -0
  97. psychopy/app/Resources/dark/loop.png +0 -0
  98. psychopy/app/Resources/dark/loop@2x.png +0 -0
  99. psychopy/app/Resources/dark/regex.png +0 -0
  100. psychopy/app/Resources/dark/regex@2x.png +0 -0
  101. psychopy/app/Resources/light/case.png +0 -0
  102. psychopy/app/Resources/light/case@2x.png +0 -0
  103. psychopy/app/Resources/light/fileaudio.png +0 -0
  104. psychopy/app/Resources/light/fileaudio@2x.png +0 -0
  105. psychopy/app/Resources/light/filecss.png +0 -0
  106. psychopy/app/Resources/light/filecss@2x.png +0 -0
  107. psychopy/app/Resources/light/filecsv.png +0 -0
  108. psychopy/app/Resources/light/filecsv@2x.png +0 -0
  109. psychopy/app/Resources/light/filedesign.png +0 -0
  110. psychopy/app/Resources/light/filedesign@2x.png +0 -0
  111. psychopy/app/Resources/light/filefont.png +0 -0
  112. psychopy/app/Resources/light/filefont@2x.png +0 -0
  113. psychopy/app/Resources/light/filegit.png +0 -0
  114. psychopy/app/Resources/light/filegit@2x.png +0 -0
  115. psychopy/app/Resources/light/filehtml.png +0 -0
  116. psychopy/app/Resources/light/filehtml@2x.png +0 -0
  117. psychopy/app/Resources/light/fileimage.png +0 -0
  118. psychopy/app/Resources/light/fileimage@2x.png +0 -0
  119. psychopy/app/Resources/light/fileinfo.png +0 -0
  120. psychopy/app/Resources/light/fileinfo@2x.png +0 -0
  121. psychopy/app/Resources/light/filejs.png +0 -0
  122. psychopy/app/Resources/light/filejs@2x.png +0 -0
  123. psychopy/app/Resources/light/filejson.png +0 -0
  124. psychopy/app/Resources/light/filejson@2x.png +0 -0
  125. psychopy/app/Resources/light/filepkg.png +0 -0
  126. psychopy/app/Resources/light/filepkg@2x.png +0 -0
  127. psychopy/app/Resources/light/filepsyexp.png +0 -0
  128. psychopy/app/Resources/light/filepsyexp@2x.png +0 -0
  129. psychopy/app/Resources/light/filepy.png +0 -0
  130. psychopy/app/Resources/light/filepy@2x.png +0 -0
  131. psychopy/app/Resources/light/filetxt.png +0 -0
  132. psychopy/app/Resources/light/filetxt@2x.png +0 -0
  133. psychopy/app/Resources/light/fileunknown.png +0 -0
  134. psychopy/app/Resources/light/fileunknown@2x.png +0 -0
  135. psychopy/app/Resources/light/filevideo.png +0 -0
  136. psychopy/app/Resources/light/filevideo@2x.png +0 -0
  137. psychopy/app/Resources/light/find.png +0 -0
  138. psychopy/app/Resources/light/find@2x.png +0 -0
  139. psychopy/app/Resources/light/loop.png +0 -0
  140. psychopy/app/Resources/light/loop@2x.png +0 -0
  141. psychopy/app/Resources/light/regex.png +0 -0
  142. psychopy/app/Resources/light/regex@2x.png +0 -0
  143. psychopy/app/Resources/routine_templates/Basic.psyexp +0 -1
  144. psychopy/app/Resources/routine_templates/Misc.psyexp +0 -1
  145. psychopy/app/Resources/routine_templates/Online.psyexp +0 -2
  146. psychopy/app/Resources/routine_templates/Trials.psyexp +0 -1
  147. psychopy/app/Resources/splash.png +0 -0
  148. psychopy/app/Resources/splash@2x.png +0 -0
  149. psychopy/app/__init__.py +49 -8
  150. psychopy/app/__main__.py +3 -0
  151. psychopy/app/_psychopyApp.py +134 -125
  152. psychopy/app/builder/builder.py +42 -22
  153. psychopy/app/builder/dialogs/__init__.py +44 -11
  154. psychopy/app/builder/dialogs/dlgsCode.py +1 -1
  155. psychopy/app/builder/dialogs/dlgsConditions.py +1 -1
  156. psychopy/app/builder/dialogs/findDlg.py +106 -20
  157. psychopy/app/builder/dialogs/paramCtrls.py +42 -1
  158. psychopy/app/builder/validators.py +1 -1
  159. psychopy/app/coder/codeEditorBase.py +8 -8
  160. psychopy/app/coder/coder.py +32 -29
  161. psychopy/app/coder/fileBrowser.py +68 -22
  162. psychopy/app/coder/folding.py +1 -1
  163. psychopy/app/coder/psychoParser.py +1 -1
  164. psychopy/app/coder/repl.py +1 -1
  165. psychopy/app/coder/sourceTree.py +1 -1
  166. psychopy/app/connections/__init__.py +1 -1
  167. psychopy/app/connections/news.py +1 -1
  168. psychopy/app/connections/sendusage.py +1 -1
  169. psychopy/app/connections/updates.py +1 -1
  170. psychopy/app/console.py +1 -1
  171. psychopy/app/errorDlg.py +1 -1
  172. psychopy/app/frametracker.py +1 -1
  173. psychopy/app/idle.py +1 -1
  174. psychopy/app/jobs.py +5 -2
  175. psychopy/app/linuxconfig/__init__.py +1 -1
  176. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  177. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4 -4
  178. psychopy/app/locale/cs_CZ/LC_MESSAGE/messages.mo +0 -0
  179. psychopy/app/locale/da_DK/LC_MESSAGE/messages.mo +0 -0
  180. psychopy/app/locale/de_DE/LC_MESSAGE/messages.mo +0 -0
  181. psychopy/app/locale/de_DE/LC_MESSAGE/messages.po +3 -3
  182. psychopy/app/locale/el_GR/LC_MESSAGE/messages.mo +0 -0
  183. psychopy/app/locale/en_NZ/LC_MESSAGE/messages.mo +0 -0
  184. psychopy/app/locale/en_US/LC_MESSAGE/messages.mo +0 -0
  185. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  186. psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +4 -4
  187. psychopy/app/locale/es_ES/LC_MESSAGE/messages.mo +0 -0
  188. psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +4 -4
  189. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  190. psychopy/app/locale/es_US/LC_MESSAGE/messages.po +4 -4
  191. psychopy/app/locale/et_EE/LC_MESSAGE/messages.mo +0 -0
  192. psychopy/app/locale/et_EE/LC_MESSAGE/messages.po +2 -2
  193. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.mo +0 -0
  194. psychopy/app/locale/fa_IR/LC_MESSAGE/messages.po +1 -1
  195. psychopy/app/locale/fi_FI/LC_MESSAGE/messages.mo +0 -0
  196. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.mo +0 -0
  197. psychopy/app/locale/fr_FR/LC_MESSAGE/messages.po +2 -2
  198. psychopy/app/locale/he_IL/LC_MESSAGE/messages.mo +0 -0
  199. psychopy/app/locale/he_IL/LC_MESSAGE/messages.po +2 -2
  200. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.mo +0 -0
  201. psychopy/app/locale/hi_IN/LC_MESSAGE/messages.po +2 -2
  202. psychopy/app/locale/hu_HU/LC_MESSAGE/messages.mo +0 -0
  203. psychopy/app/locale/it_IT/LC_MESSAGE/messages.mo +0 -0
  204. psychopy/app/locale/it_IT/LC_MESSAGE/messages.po +2 -2
  205. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  206. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +3421 -2396
  207. psychopy/app/locale/ko_KR/LC_MESSAGE/messages.mo +0 -0
  208. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.mo +0 -0
  209. psychopy/app/locale/ms_MY/LC_MESSAGE/messages.po +2 -2
  210. psychopy/app/locale/nl_NL/LC_MESSAGE/messages.mo +0 -0
  211. psychopy/app/locale/nn_NO/LC_MESSAGE/messages.mo +0 -0
  212. psychopy/app/locale/pl_PL/LC_MESSAGE/messages.mo +0 -0
  213. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.mo +0 -0
  214. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +4 -4
  215. psychopy/app/locale/ro_RO/LC_MESSAGE/messages.mo +0 -0
  216. psychopy/app/locale/ru_RU/LC_MESSAGE/messages.mo +0 -0
  217. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.mo +0 -0
  218. psychopy/app/locale/sv_SE/LC_MESSAGE/messages.po +2 -2
  219. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.mo +0 -0
  220. psychopy/app/locale/tr_TR/LC_MESSAGE/messages.po +2 -2
  221. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.mo +0 -0
  222. psychopy/app/locale/zh_CN/LC_MESSAGE/messages.po +3 -3
  223. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.mo +0 -0
  224. psychopy/app/locale/zh_TW/LC_MESSAGE/messages.po +2 -2
  225. psychopy/app/{builder/localizedStrings.py → localizedStrings.py} +173 -26
  226. psychopy/app/pavlovia_ui/__init__.py +1 -1
  227. psychopy/app/pavlovia_ui/_base.py +1 -1
  228. psychopy/app/pavlovia_ui/functions.py +1 -1
  229. psychopy/app/pavlovia_ui/menu.py +1 -1
  230. psychopy/app/pavlovia_ui/project.py +1 -1
  231. psychopy/app/pavlovia_ui/search.py +1 -1
  232. psychopy/app/pavlovia_ui/sync.py +1 -1
  233. psychopy/app/pavlovia_ui/user.py +1 -1
  234. psychopy/app/plugin_manager/dialog.py +34 -96
  235. psychopy/app/plugin_manager/packages.py +10 -14
  236. psychopy/app/plugin_manager/plugins.py +64 -4
  237. psychopy/app/preferencesDlg.py +12 -37
  238. psychopy/app/psychopyApp.py +130 -44
  239. psychopy/app/ribbon.py +1 -0
  240. psychopy/app/runner/runner.py +19 -7
  241. psychopy/app/runner/scriptProcess.py +11 -6
  242. psychopy/app/stdout/stdOutRich.py +9 -2
  243. psychopy/app/themes/fonts.py +1 -1
  244. psychopy/app/themes/icons.py +2 -38
  245. psychopy/app/ui/__init__.py +1 -1
  246. psychopy/app/utils.py +3 -3
  247. psychopy/assets/default.mp3 +0 -0
  248. psychopy/assets/fonts/NotoSans-Bold.ttf +0 -0
  249. psychopy/assets/fonts/NotoSans-BoldItalic.ttf +0 -0
  250. psychopy/assets/fonts/NotoSans-Italic.ttf +0 -0
  251. psychopy/assets/fonts/NotoSans-Regular.ttf +0 -0
  252. psychopy/assets/voicekeyThresholdStim.wav +0 -0
  253. psychopy/clock.py +4 -1
  254. psychopy/colors.py +12 -5
  255. psychopy/core.py +1 -1
  256. psychopy/data/base.py +1 -1
  257. psychopy/data/experiment.py +151 -46
  258. psychopy/data/routine.py +27 -1
  259. psychopy/data/staircase.py +2 -1
  260. psychopy/data/trial.py +62 -14
  261. psychopy/data/utils.py +2 -2
  262. psychopy/demos/builder/Design Templates/branchedExperiment/branchedExperiment.psyexp +333 -218
  263. psychopy/demos/builder/Design Templates/psychophysicsStaircase/psychophysicsStaircase.psyexp +261 -239
  264. psychopy/demos/builder/Design Templates/psychophysicsStairsInterleaved/psychophysicsStaircaseInterleaved.psyexp +319 -180
  265. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks.psyexp +204 -116
  266. psychopy/demos/builder/Experiments/BART/assets/background.jpg +0 -0
  267. psychopy/demos/builder/Experiments/BART/assets/blueBalloon.png +0 -0
  268. psychopy/demos/builder/Experiments/BART/assets/greenBalloon.png +0 -0
  269. psychopy/demos/builder/Experiments/BART/assets/redBalloon.png +0 -0
  270. psychopy/demos/builder/Experiments/BART/bart.psyexp +779 -866
  271. psychopy/demos/builder/Experiments/BigFiveInventory/BFI.psyexp +242 -180
  272. psychopy/demos/builder/Experiments/GoNoGo/gng.psyexp +419 -406
  273. psychopy/demos/builder/Experiments/dragAndDrop/README.md +2 -37
  274. psychopy/demos/builder/Experiments/dragAndDrop/drag_and_drop.psyexp +460 -1204
  275. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/blank_grid.png +0 -0
  276. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/make_shapes.psyexp +221 -0
  277. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/readme.md +4 -0
  278. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_1.png +0 -0
  279. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_10.png +0 -0
  280. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_2.png +0 -0
  281. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_3.png +0 -0
  282. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_4.png +0 -0
  283. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_5.png +0 -0
  284. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_6.png +0 -0
  285. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_7.png +0 -0
  286. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_8.png +0 -0
  287. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solution_9.png +0 -0
  288. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/solutions.xlsx +0 -0
  289. psychopy/demos/builder/Experiments/mentalRotation/MentalRotation.psyexp +583 -542
  290. psychopy/demos/builder/Experiments/navon/NavonTask.psyexp +458 -427
  291. psychopy/demos/builder/Experiments/sternberg/sternberg.psyexp +588 -550
  292. psychopy/demos/builder/Experiments/stroop/stroop.psyexp +303 -207
  293. psychopy/demos/builder/Experiments/stroopExtended/stroop.psyexp +390 -215
  294. psychopy/demos/builder/Experiments/stroopExtended/stroopReverse.psyexp +390 -215
  295. psychopy/demos/builder/Experiments/stroopVoice/stroopVoice.psyexp +357 -331
  296. psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +3 -2
  297. psychopy/demos/builder/Feature Demos/counterbalance/counterbalance.psyexp +287 -277
  298. psychopy/demos/builder/Feature Demos/gratings/gratings.psyexp +370 -320
  299. psychopy/demos/builder/Feature Demos/noise/noise.psyexp +452 -399
  300. psychopy/demos/builder/Feature Demos/panorama/panorama.psyexp +168 -133
  301. psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +4 -3
  302. psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +420 -392
  303. psychopy/demos/builder/Feature Demos/sliders/sliders.psyexp +917 -871
  304. psychopy/demos/builder/Feature Demos/visualValidator/readme.md +7 -0
  305. psychopy/demos/builder/Feature Demos/visualValidator/visualValidator.psyexp +200 -0
  306. psychopy/demos/builder/Hardware/EEG_parallel_component/EEG_triggers_parallel_comp.psyexp +25 -9
  307. psychopy/demos/builder/Hardware/EEG_serial_code/EEG_triggers_serial_code.psyexp +372 -361
  308. psychopy/demos/builder/Hardware/EEG_serial_component/EEG_triggers_serial_comp.psyexp +25 -9
  309. psychopy/demos/builder/Hardware/EGI_netstation/stroop.psyexp +320 -235
  310. psychopy/demos/builder/Hardware/Eyetracking_visual_search/visualSearch.psyexp +790 -651
  311. psychopy/demos/builder/Hardware/camera/camera.psyexp +326 -246
  312. psychopy/demos/builder/Hardware/eyetracking/eyetracking.psyexp +432 -327
  313. psychopy/demos/builder/Hardware/eyetracking_custom_cal/eyetracking_custom_cal.psyexp +440 -321
  314. psychopy/demos/builder/Hardware/fMRI/fMRI_demo.psyexp +190 -181
  315. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo.psyexp +323 -312
  316. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy.psyexp +360 -0
  317. psychopy/demos/builder/Hardware/lab_streaming_layer/lsl_triggers_demo_legacy_legacy.psyexp +312 -0
  318. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy.psyexp +329 -273
  319. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy.psyexp +360 -0
  320. psychopy/demos/builder/Hardware/lab_streaming_layer_legacy/lsl_triggers_demo_legacy_legacy_legacy.psyexp +312 -0
  321. psychopy/demos/builder/Hardware/microphone/microphone.psyexp +450 -404
  322. psychopy/demos/builder/Hardware/pump/pump.psyexp +593 -329
  323. psychopy/demos/builder/Helper Tools/achorVSalignment/FlowCircular-Regular.ttf +0 -0
  324. psychopy/demos/builder/Helper Tools/achorVSalignment/anchorAlignment.psyexp +336 -274
  325. psychopy/demos/builder/Helper Tools/clockFace/clockFace.psyexp +200 -149
  326. psychopy/demos/builder/Helper Tools/colors/colors.psyexp +300 -279
  327. psychopy/demos/builder/Helper Tools/drawPolygon/drawPolygon.psyexp +677 -564
  328. psychopy/demos/builder/Helper Tools/keyNameFinder/keyNameFinder.psyexp +214 -158
  329. psychopy/demos/builder/Helper Tools/spatialUnits/unitDemo.psyexp +195 -146
  330. psychopy/demos/coder/experiment control/runtimeInfo.py +1 -1
  331. psychopy/devices/__init__.py +1 -1
  332. psychopy/event.py +1 -1
  333. psychopy/exceptions.py +1 -1
  334. psychopy/experiment/__init__.py +1 -1
  335. psychopy/experiment/_experiment.py +30 -9
  336. psychopy/experiment/components/__init__.py +1 -6
  337. psychopy/experiment/components/_base.py +44 -19
  338. psychopy/experiment/components/aperture/__init__.py +1 -1
  339. psychopy/experiment/components/brush/__init__.py +2 -2
  340. psychopy/experiment/components/button/__init__.py +24 -28
  341. psychopy/experiment/components/camera/__init__.py +38 -39
  342. psychopy/experiment/components/code/__init__.py +1 -1
  343. psychopy/experiment/components/dots/__init__.py +1 -1
  344. psychopy/experiment/components/eyetracker_record/__init__.py +7 -3
  345. psychopy/experiment/components/form/__init__.py +3 -3
  346. psychopy/experiment/components/grating/__init__.py +1 -1
  347. psychopy/experiment/components/image/__init__.py +1 -1
  348. psychopy/experiment/components/joyButtons/__init__.py +2 -2
  349. psychopy/experiment/components/joyButtons/virtualJoyButtons.py +1 -1
  350. psychopy/experiment/components/joystick/__init__.py +3 -3
  351. psychopy/experiment/components/joystick/virtualJoystick.py +1 -1
  352. psychopy/experiment/components/keyboard/__init__.py +98 -122
  353. psychopy/experiment/components/microphone/__init__.py +54 -98
  354. psychopy/experiment/components/mouse/__init__.py +92 -93
  355. psychopy/experiment/components/movie/__init__.py +28 -50
  356. psychopy/experiment/components/parallelOut/__init__.py +3 -3
  357. psychopy/experiment/components/polygon/__init__.py +2 -3
  358. psychopy/experiment/components/roi/__init__.py +2 -2
  359. psychopy/experiment/components/routineSettings/__init__.py +2 -0
  360. psychopy/experiment/components/serialOut/__init__.py +7 -7
  361. psychopy/experiment/components/settings/__init__.py +317 -313
  362. psychopy/experiment/components/settings/eyetracking.py +108 -0
  363. psychopy/experiment/components/slider/__init__.py +5 -5
  364. psychopy/experiment/components/sound/__init__.py +168 -78
  365. psychopy/experiment/components/soundsensor/__init__.py +361 -0
  366. psychopy/experiment/components/soundsensor/classic/soundsensor.png +0 -0
  367. psychopy/experiment/components/soundsensor/classic/soundsensor@2x.png +0 -0
  368. psychopy/experiment/components/soundsensor/dark/soundsensor.png +0 -0
  369. psychopy/experiment/components/soundsensor/dark/soundsensor@2x.png +0 -0
  370. psychopy/experiment/components/soundsensor/light/soundsensor.png +0 -0
  371. psychopy/experiment/components/soundsensor/light/soundsensor@2x.png +0 -0
  372. psychopy/experiment/components/static/__init__.py +59 -33
  373. psychopy/experiment/components/text/__init__.py +2 -6
  374. psychopy/experiment/components/textbox/__init__.py +3 -7
  375. psychopy/experiment/components/unknown/__init__.py +2 -0
  376. psychopy/experiment/components/unknownPlugin/__init__.py +2 -0
  377. psychopy/experiment/exports.py +1 -1
  378. psychopy/experiment/flow.py +2 -2
  379. psychopy/experiment/localization.py +1 -1
  380. psychopy/experiment/loops.py +43 -10
  381. psychopy/experiment/params.py +6 -4
  382. psychopy/experiment/plugins.py +8 -1
  383. psychopy/experiment/py2js.py +1 -1
  384. psychopy/experiment/py2js_transpiler.py +1 -1
  385. psychopy/experiment/routines/__init__.py +1 -1
  386. psychopy/experiment/routines/_base.py +23 -24
  387. psychopy/experiment/routines/audioValidator/__init__.py +343 -0
  388. psychopy/experiment/routines/audioValidator/classic/audio_validator.png +0 -0
  389. psychopy/experiment/routines/audioValidator/classic/audio_validator@2x.png +0 -0
  390. psychopy/experiment/routines/audioValidator/dark/audio_validator.png +0 -0
  391. psychopy/experiment/routines/audioValidator/dark/audio_validator@2x.png +0 -0
  392. psychopy/experiment/routines/audioValidator/light/audio_validator.png +0 -0
  393. psychopy/experiment/routines/audioValidator/light/audio_validator@2x.png +0 -0
  394. psychopy/experiment/routines/eyetracker_calibrate/__init__.py +76 -17
  395. psychopy/experiment/routines/eyetracker_validate/__init__.py +1 -1
  396. psychopy/experiment/routines/unknown/__init__.py +2 -0
  397. psychopy/experiment/routines/{photodiodeValidator → visualValidator}/__init__.py +89 -120
  398. psychopy/experiment/routines/visualValidator/classic/visual_validator.png +0 -0
  399. psychopy/experiment/routines/visualValidator/classic/visual_validator@2x.png +0 -0
  400. psychopy/experiment/routines/visualValidator/dark/visual_validator.png +0 -0
  401. psychopy/experiment/routines/visualValidator/dark/visual_validator@2x.png +0 -0
  402. psychopy/experiment/routines/visualValidator/light/visual_validator.png +0 -0
  403. psychopy/experiment/routines/visualValidator/light/visual_validator@2x.png +0 -0
  404. psychopy/experiment/utils.py +1 -1
  405. psychopy/gui/__init__.py +1 -1
  406. psychopy/gui/qtgui.py +15 -6
  407. psychopy/gui/wxgui.py +1 -1
  408. psychopy/hardware/__init__.py +0 -1
  409. psychopy/hardware/base.py +147 -16
  410. psychopy/hardware/bbtk/__init__.py +10 -16
  411. psychopy/hardware/brainproducts.py +7 -13
  412. psychopy/hardware/button.py +21 -2
  413. psychopy/hardware/buttonbox/__init__.py +1 -1
  414. psychopy/hardware/camera/__init__.py +18 -5
  415. psychopy/hardware/cedrus.py +5 -16
  416. psychopy/hardware/crs/__init__.py +1 -1
  417. psychopy/hardware/crs/bits.py +36 -33
  418. psychopy/hardware/crs/colorcal.py +8 -11
  419. psychopy/hardware/crs/optical.py +7 -10
  420. psychopy/hardware/crs/shaders.py +18 -5
  421. psychopy/hardware/emotiv.py +1 -1
  422. psychopy/hardware/emulator.py +11 -5
  423. psychopy/hardware/exceptions.py +86 -0
  424. psychopy/hardware/forp.py +18 -23
  425. psychopy/hardware/gammasci.py +8 -3
  426. psychopy/hardware/iolab.py +8 -19
  427. psychopy/hardware/joystick/__init__.py +865 -266
  428. psychopy/hardware/joystick/_base.py +251 -0
  429. psychopy/hardware/joystick/backend_glfw.py +306 -0
  430. psychopy/hardware/joystick/backend_pyglet.py +309 -0
  431. psychopy/hardware/joystick/mappings.py +287 -0
  432. psychopy/hardware/keyboard.py +4 -2
  433. psychopy/hardware/labhackers.py +1 -1
  434. psychopy/hardware/labjacks.py +9 -13
  435. psychopy/hardware/{photodiode.py → lightsensor.py} +146 -203
  436. psychopy/hardware/listener.py +9 -8
  437. psychopy/hardware/manager.py +24 -35
  438. psychopy/hardware/microphone.py +535 -155
  439. psychopy/hardware/minolta.py +14 -4
  440. psychopy/hardware/mouse/__init__.py +1 -1
  441. psychopy/hardware/photometer/__init__.py +2 -2
  442. psychopy/hardware/pr.py +14 -4
  443. psychopy/hardware/qmix.py +18 -27
  444. psychopy/hardware/serialdevice.py +43 -12
  445. psychopy/hardware/soundsensor.py +473 -0
  446. psychopy/hardware/spatial/__init__.py +231 -0
  447. psychopy/hardware/speaker.py +298 -36
  448. psychopy/hardware/triggerbox/__init__.py +1 -1
  449. psychopy/hardware/triggerbox/base.py +1 -1
  450. psychopy/hardware/triggerbox/parallel.py +1 -1
  451. psychopy/info.py +1 -1
  452. psychopy/iohub/devices/eyetracker/__init__.py +10 -18
  453. psychopy/iohub/devices/eyetracker/calibration/procedure.py +15 -33
  454. psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +2 -2
  455. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/__init__.py +1 -0
  456. psychopy/iohub/devices/eyetracker/hw/gazepoint/gp3/eyetracker.py +10 -0
  457. psychopy/iohub/devices/eyetracker/hw/pupil_labs/neon/__init__.py +1 -0
  458. psychopy/iohub/devices/mouse/linux2.py +2 -1
  459. psychopy/layout.py +1 -1
  460. psychopy/liaison.py +91 -39
  461. psychopy/locale_setup.py +11 -1
  462. psychopy/localization/__init__.py +1 -1
  463. psychopy/localization/_localization.py +1 -1
  464. psychopy/localization/messages.pot +2 -2
  465. psychopy/logging.py +14 -12
  466. psychopy/microphone.py +4 -3
  467. psychopy/misc.py +1 -1
  468. psychopy/monitors/MonitorCenter.py +3 -3
  469. psychopy/monitors/__init__.py +1 -1
  470. psychopy/monitors/calibData.py +1 -1
  471. psychopy/monitors/calibTools.py +3 -2
  472. psychopy/platform_specific/__init__.py +1 -1
  473. psychopy/platform_specific/darwin.py +1 -1
  474. psychopy/platform_specific/linux.py +1 -1
  475. psychopy/platform_specific/win32.py +1 -1
  476. psychopy/plugins/__init__.py +26 -17
  477. psychopy/plugins/util.py +65 -0
  478. psychopy/preferences/Darwin.spec +11 -3
  479. psychopy/preferences/FreeBSD.spec +11 -3
  480. psychopy/preferences/Linux.spec +11 -3
  481. psychopy/preferences/Windows.spec +11 -3
  482. psychopy/preferences/__init__.py +1 -1
  483. psychopy/preferences/baseNoArch.spec +11 -3
  484. psychopy/preferences/hints.py +78 -61
  485. psychopy/preferences/preferences.py +82 -13
  486. psychopy/projects/__init__.py +1 -1
  487. psychopy/projects/pavlovia.py +29 -13
  488. psychopy/scripts/psyexpCompile.py +1 -1
  489. psychopy/session.py +81 -8
  490. psychopy/sound/__init__.py +25 -10
  491. psychopy/sound/_base.py +134 -34
  492. psychopy/sound/audioclip.py +38 -15
  493. psychopy/sound/audiodevice.py +1 -1
  494. psychopy/sound/backend_ptb.py +53 -321
  495. psychopy/sound/backend_pygame.py +7 -3
  496. psychopy/sound/backend_pyo.py +53 -22
  497. psychopy/sound/backend_pysound.py +10 -27
  498. psychopy/sound/backend_sounddevice.py +33 -21
  499. psychopy/sound/exceptions.py +1 -1
  500. psychopy/sound/microphone.py +83 -5
  501. psychopy/sound/transcribe.py +3 -3
  502. psychopy/tests/data/test_basic_run.py +1 -0
  503. psychopy/tests/data/test_sounds/default_16000.wav +0 -0
  504. psychopy/tests/data/test_sounds/default_192000.wav +0 -0
  505. psychopy/tests/data/test_sounds/default_22050.wav +0 -0
  506. psychopy/tests/data/test_sounds/default_32000.wav +0 -0
  507. psychopy/tests/data/test_sounds/default_44100.wav +0 -0
  508. psychopy/tests/data/test_sounds/default_48000.wav +0 -0
  509. psychopy/tests/data/test_sounds/default_8000.wav +0 -0
  510. psychopy/tests/data/test_sounds/default_96000.wav +0 -0
  511. psychopy/tests/test_alerts/test_alerttools.py +2 -1
  512. psychopy/tests/test_app/test_command_line.py +65 -0
  513. psychopy/tests/test_data/test_TrialHandler2.py +18 -7
  514. psychopy/tests/test_demos/test_builder_demos.py +1 -1
  515. psychopy/tests/test_experiment/needs_wx/componsTemplate.txt +5238 -4188
  516. psychopy/tests/test_experiment/needs_wx/test_components.py +1 -1
  517. psychopy/tests/test_experiment/test_components/test_RoutineSettingsComponent.py +16 -0
  518. psychopy/tests/test_experiment/test_components/test_all_components.py +1 -1
  519. psychopy/tests/test_experiment/test_components/test_base_components.py +26 -17
  520. psychopy/tests/test_experiment/test_loops.py +12 -4
  521. psychopy/tests/test_experiment/test_params.py +17 -4
  522. psychopy/tests/test_experiment/test_routines/test_PhotodiodeValidationRoutine.py +2 -2
  523. psychopy/tests/test_hardware/test_photodiode.py +66 -0
  524. psychopy/tests/test_liaison/test_Liaison.py +4 -4
  525. psychopy/tests/test_misc/test_clock.py +2 -0
  526. psychopy/tests/test_misc/test_color.py +2 -0
  527. psychopy/tests/test_misc/test_event.py +1 -0
  528. psychopy/tests/test_plugins/__init__.py +0 -0
  529. psychopy/tests/test_plugins/test_plugin_stubs.py +125 -0
  530. psychopy/tests/test_sound/test_sound.py +111 -40
  531. psychopy/tests/test_tools/test_colorspacetools.py +24 -23
  532. psychopy/tests/test_tools/test_mathtools.py +9 -9
  533. psychopy/tests/test_tools/test_viewtools.py +101 -0
  534. psychopy/tests/test_validators/__init__.py +0 -0
  535. psychopy/tests/test_validators/test_voicekeyValidator.py +95 -0
  536. psychopy/tests/test_visual/test_all_stimuli.py +2 -2
  537. psychopy/tests/test_visual/test_basevisual.py +37 -7
  538. psychopy/tests/test_visual/test_button.py +2 -2
  539. psychopy/tests/test_visual/test_circle.py +10 -2
  540. psychopy/tests/test_visual/test_dots.py +1 -1
  541. psychopy/tests/test_visual/test_form.py +13 -13
  542. psychopy/tests/test_visual/test_gamma.py +3 -3
  543. psychopy/tests/test_visual/test_image.py +2 -2
  544. psychopy/tests/test_visual/test_progress.py +2 -2
  545. psychopy/tests/test_visual/test_roi.py +8 -2
  546. psychopy/tests/test_visual/test_shape.py +2 -2
  547. psychopy/tests/test_visual/test_slider.py +2 -2
  548. psychopy/tests/test_visual/test_target.py +2 -2
  549. psychopy/tests/test_visual/test_textbox.py +6 -8
  550. psychopy/tests/test_visual/test_winScalePos.py +6 -5
  551. psychopy/tests/test_visual/test_window.py +17 -0
  552. psychopy/tests/utils.py +51 -1
  553. psychopy/tools/__init__.py +1 -1
  554. psychopy/tools/arraytools.py +2 -2
  555. psychopy/tools/attributetools.py +52 -1
  556. psychopy/tools/audiotools.py +4 -1
  557. psychopy/tools/colorspacetools.py +6 -4
  558. psychopy/tools/coordinatetools.py +1 -1
  559. psychopy/tools/fileerrortools.py +21 -9
  560. psychopy/tools/filetools.py +2 -2
  561. psychopy/tools/fontmanager.py +47 -28
  562. psychopy/tools/gltools.py +2967 -559
  563. psychopy/tools/imagetools.py +1 -1
  564. psychopy/tools/mathtools.py +997 -127
  565. psychopy/tools/monitorunittools.py +7 -1
  566. psychopy/tools/movietools.py +1 -2
  567. psychopy/tools/pkgtools.py +157 -127
  568. psychopy/tools/plottools.py +1 -1
  569. psychopy/tools/rifttools.py +1 -1
  570. psychopy/tools/stereotools.py +1 -1
  571. psychopy/tools/stimulustools.py +172 -2
  572. psychopy/tools/stringtools.py +22 -2
  573. psychopy/tools/systemtools.py +1 -1
  574. psychopy/tools/typetools.py +1 -1
  575. psychopy/tools/unittools.py +1 -1
  576. psychopy/tools/versionchooser.py +3 -1
  577. psychopy/tools/viewtools.py +54 -70
  578. psychopy/tools/wizard.py +2 -2
  579. psychopy/validation/__init__.py +6 -0
  580. psychopy/validation/audio.py +74 -0
  581. psychopy/validation/visual.py +115 -0
  582. psychopy/visual/__init__.py +1 -4
  583. psychopy/visual/aperture.py +9 -6
  584. psychopy/visual/backends/__init__.py +1 -1
  585. psychopy/visual/backends/_base.py +1 -1
  586. psychopy/visual/backends/gamma.py +1 -1
  587. psychopy/visual/backends/glfwbackend.py +8 -12
  588. psychopy/visual/backends/pygamebackend.py +1 -1
  589. psychopy/visual/backends/pygletbackend.py +32 -11
  590. psychopy/visual/basevisual.py +93 -13
  591. psychopy/visual/brush.py +1 -1
  592. psychopy/visual/bufferimage.py +90 -10
  593. psychopy/visual/button.py +1 -1
  594. psychopy/visual/circle.py +12 -20
  595. psychopy/visual/custommouse.py +1 -1
  596. psychopy/visual/dot.py +80 -14
  597. psychopy/visual/elementarray.py +84 -10
  598. psychopy/visual/filters.py +1 -1
  599. psychopy/visual/form.py +43 -28
  600. psychopy/visual/grating.py +105 -25
  601. psychopy/visual/helpers.py +4 -2
  602. psychopy/visual/image.py +98 -20
  603. psychopy/visual/line.py +15 -25
  604. psychopy/visual/movie.py +1 -1
  605. psychopy/visual/movie2.py +4 -3
  606. psychopy/visual/movie3.py +4 -3
  607. psychopy/visual/movies/__init__.py +1 -1
  608. psychopy/visual/movies/frame.py +1 -1
  609. psychopy/visual/movies/metadata.py +1 -1
  610. psychopy/visual/movies/players/__init__.py +1 -1
  611. psychopy/visual/movies/players/_base.py +1 -1
  612. psychopy/visual/movies/players/ffpyplayer_player.py +2 -3
  613. psychopy/visual/nnlvs.py +9 -6
  614. psychopy/visual/noise.py +4 -16
  615. psychopy/visual/patch.py +4 -3
  616. psychopy/visual/pie.py +3 -14
  617. psychopy/visual/polygon.py +21 -28
  618. psychopy/visual/radial.py +4 -18
  619. psychopy/visual/ratingscale.py +4 -3
  620. psychopy/visual/rect.py +16 -25
  621. psychopy/visual/rift.py +8 -2
  622. psychopy/visual/secondorder.py +4 -16
  623. psychopy/visual/shaders.py +620 -286
  624. psychopy/visual/shape.py +281 -90
  625. psychopy/visual/simpleimage.py +1 -1
  626. psychopy/visual/slider.py +78 -25
  627. psychopy/visual/stim3d.py +5 -608
  628. psychopy/visual/text.py +13 -3
  629. psychopy/visual/textbox2/textbox2.py +188 -56
  630. psychopy/visual/vlcmoviestim.py +1 -1
  631. psychopy/visual/window.py +374 -201
  632. psychopy/web.py +1 -1
  633. {psychopy-2024.2.5.dist-info → psychopy-2025.1.1.dist-info}/METADATA +13 -12
  634. {psychopy-2024.2.5.dist-info → psychopy-2025.1.1.dist-info}/RECORD +647 -624
  635. {psychopy-2024.2.5.dist-info → psychopy-2025.1.1.dist-info}/WHEEL +1 -1
  636. psychopy/.DS_Store +0 -0
  637. psychopy/__init__.py.orig +0 -65
  638. psychopy/app/.DS_Store +0 -0
  639. psychopy/app/Resources/.DS_Store +0 -0
  640. psychopy/app/Resources/classic/filecsv16.png +0 -0
  641. psychopy/app/Resources/classic/fileimage16.png +0 -0
  642. psychopy/app/Resources/classic/fileunknown16.png +0 -0
  643. psychopy/app/Resources/dark/filecsv16.png +0 -0
  644. psychopy/app/Resources/dark/filecsv16@2x.png +0 -0
  645. psychopy/app/Resources/dark/fileimage16.png +0 -0
  646. psychopy/app/Resources/dark/fileimage16@2x.png +0 -0
  647. psychopy/app/Resources/dark/fileunknown16.png +0 -0
  648. psychopy/app/Resources/dark/fileunknown16@2x.png +0 -0
  649. psychopy/app/Resources/fonts/OpenSans-Bold.ttf +0 -0
  650. psychopy/app/Resources/fonts/OpenSans-BoldItalic.ttf +0 -0
  651. psychopy/app/Resources/fonts/OpenSans-ExtraBold.ttf +0 -0
  652. psychopy/app/Resources/fonts/OpenSans-ExtraBoldItalic.ttf +0 -0
  653. psychopy/app/Resources/fonts/OpenSans-Italic.ttf +0 -0
  654. psychopy/app/Resources/fonts/OpenSans-Light.ttf +0 -0
  655. psychopy/app/Resources/fonts/OpenSans-LightItalic.ttf +0 -0
  656. psychopy/app/Resources/fonts/OpenSans-Regular.ttf +0 -0
  657. psychopy/app/Resources/fonts/OpenSans-SemiBold.ttf +0 -0
  658. psychopy/app/Resources/fonts/OpenSans-SemiBoldItalic.ttf +0 -0
  659. psychopy/app/Resources/light/filecsv16.png +0 -0
  660. psychopy/app/Resources/light/filecsv16@2x.png +0 -0
  661. psychopy/app/Resources/light/fileimage16.png +0 -0
  662. psychopy/app/Resources/light/fileimage16@2x.png +0 -0
  663. psychopy/app/Resources/light/fileunknown16.png +0 -0
  664. psychopy/app/Resources/light/fileunknown16@2x.png +0 -0
  665. psychopy/app/Resources/psychopySplash.png +0 -0
  666. psychopy/app/Resources/psychopySplash@2x.png +0 -0
  667. psychopy/app/builder/builder.py.orig +0 -3932
  668. psychopy/app/builder/dialogs/__init__.py.orig +0 -1679
  669. psychopy/app/builder/dialogs/paramCtrls.py.orig +0 -713
  670. psychopy/app/colorpicker/__init__.py.orig +0 -411
  671. psychopy/app/locale/ar_001/.DS_Store +0 -0
  672. psychopy/app/locale/ar_001/LC_MESSAGE/.DS_Store +0 -0
  673. psychopy/core.py.orig +0 -169
  674. psychopy/demos/builder/.DS_Store +0 -0
  675. psychopy/demos/builder/Design Templates/randomisedBlocks/randomisedBlocks_lastrun.py +0 -330
  676. psychopy/demos/builder/Experiments/.DS_Store +0 -0
  677. psychopy/demos/builder/Experiments/dragAndDrop/archived_conditions.xlsx +0 -0
  678. psychopy/demos/builder/Experiments/dragAndDrop/draw grid stim.py +0 -61
  679. psychopy/demos/builder/Experiments/dragAndDrop/shapeMaker.psyexp +0 -91
  680. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_1.png +0 -0
  681. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_10.png +0 -0
  682. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_2.png +0 -0
  683. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_3.png +0 -0
  684. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_4.png +0 -0
  685. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_5.png +0 -0
  686. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_6.png +0 -0
  687. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_7.png +0 -0
  688. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_8.png +0 -0
  689. psychopy/demos/builder/Experiments/dragAndDrop/stimuli/grid_image_9.png +0 -0
  690. psychopy/demos/builder/Experiments/dragAndDrop/updated_conditions.xlsx +0 -0
  691. psychopy/demos/builder/Tools/.DS_Store +0 -0
  692. psychopy/demos/builder/Tools/gammaCalibration/.DS_Store +0 -0
  693. psychopy/demos/builder/Tools/gammaCalibration/data/.DS_Store +0 -0
  694. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.csv +0 -38
  695. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.log +0 -3418
  696. psychopy/demos/builder/Tools/gammaCalibration/data/_gamma_correction_visual_2022-05-18_14h18.29.439.psydat +0 -0
  697. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.csv +0 -2
  698. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.log +0 -15
  699. psychopy/demos/builder/Tools/gammaCalibration/data/x1_gamma_correction_visual_2022-05-17_13h59.42.928.psydat +0 -0
  700. psychopy/demos/builder/Tools/gammaCalibration/gamma_correction_visual_lastrun.py +0 -562
  701. psychopy/demos/coder/.DS_Store +0 -0
  702. psychopy/demos/coder/experiment control/info_gamma.pickle +0 -0
  703. psychopy/demos/coder/iohub/.iohpid +0 -1
  704. psychopy/demos/coder/iohub/eyetracking/.iohpid +0 -1
  705. psychopy/demos/coder/iohub/wintab/.DS_Store +0 -0
  706. psychopy/demos/coder/stimuli/.DS_Store +0 -0
  707. psychopy/experiment/_experiment.py.orig +0 -1032
  708. psychopy/experiment/components/.DS_Store +0 -0
  709. psychopy/experiment/components/_base.py.orig +0 -823
  710. psychopy/experiment/components/form/.DS_Store +0 -0
  711. psychopy/experiment/components/microphone/__init__.py.orig +0 -490
  712. psychopy/experiment/components/settings/__init__.py.orig +0 -1337
  713. psychopy/experiment/components/textbox/__init__.py.orig +0 -310
  714. psychopy/experiment/components/webcam/.DS_Store +0 -0
  715. psychopy/experiment/components/webcam/light/.DS_Store +0 -0
  716. psychopy/experiment/loops.py.orig +0 -829
  717. psychopy/experiment/params.py.orig +0 -408
  718. psychopy/experiment/routine.py.orig +0 -503
  719. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator.png +0 -0
  720. psychopy/experiment/routines/photodiodeValidator/classic/photodiode_validator@2x.png +0 -0
  721. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator.png +0 -0
  722. psychopy/experiment/routines/photodiodeValidator/dark/photodiode_validator@2x.png +0 -0
  723. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator.png +0 -0
  724. psychopy/experiment/routines/photodiodeValidator/light/photodiode_validator@2x.png +0 -0
  725. psychopy/hardware/.DS_Store +0 -0
  726. psychopy/hardware/brainproducts.py.orig +0 -680
  727. psychopy/hardware/iolab.py.orig +0 -238
  728. psychopy/iohub/datastore/__init__.py.orig +0 -443
  729. psychopy/iohub/datastore/util.py.orig +0 -692
  730. psychopy/iohub/devices/mouse/darwin.py.orig +0 -427
  731. psychopy/iohub/devices/mouse/linux2.py.orig +0 -198
  732. psychopy/preferences/.DS_Store +0 -0
  733. psychopy/projects/pavlovia.py.orig +0 -1295
  734. psychopy/tests/.DS_Store +0 -0
  735. psychopy/tests/data/.DS_Store +0 -0
  736. psychopy/tests/data/TestCircle_fill_local.png +0 -0
  737. psychopy/tests/data/aperture1_normHexbackground_local.png +0 -0
  738. psychopy/tests/data/aperture1_norm_local.png +0 -0
  739. psychopy/tests/data/aperture2_normHexbackground_local.png +0 -0
  740. psychopy/tests/data/beatandrcos_height_local.png +0 -0
  741. psychopy/tests/data/beatandrcos_normAddBlend_local.png +0 -0
  742. psychopy/tests/data/beatandrcos_normHexbackground_local.png +0 -0
  743. psychopy/tests/data/beatandrcos_norm_local.png +0 -0
  744. psychopy/tests/data/beatandrcos_stencil_local.png +0 -0
  745. psychopy/tests/data/blend_add_height_local.png +0 -0
  746. psychopy/tests/data/blend_add_normAddBlend_local.png +0 -0
  747. psychopy/tests/data/blend_add_normHexbackground_local.png +0 -0
  748. psychopy/tests/data/blend_add_normNoShade_local.png +0 -0
  749. psychopy/tests/data/blend_add_norm_local.png +0 -0
  750. psychopy/tests/data/blend_add_stencil_local.png +0 -0
  751. psychopy/tests/data/bufferimg_gabor_height_local.png +0 -0
  752. psychopy/tests/data/bufferimg_gabor_normAddBlend_local.png +0 -0
  753. psychopy/tests/data/bufferimg_gabor_normHexbackground_local.png +0 -0
  754. psychopy/tests/data/bufferimg_gabor_normNoShade_local.png +0 -0
  755. psychopy/tests/data/bufferimg_gabor_norm_local.png +0 -0
  756. psychopy/tests/data/bufferimg_gabor_stencil_local.png +0 -0
  757. psychopy/tests/data/circleHex_height_local.png +0 -0
  758. psychopy/tests/data/circleHex_normAddBlend_local.png +0 -0
  759. psychopy/tests/data/circleHex_normHexbackground_local.png +0 -0
  760. psychopy/tests/data/circleHex_normNoShade_local.png +0 -0
  761. psychopy/tests/data/circleHex_norm_local.png +0 -0
  762. psychopy/tests/data/circleHex_stencil_local.png +0 -0
  763. psychopy/tests/data/color_comparison_local.png +0 -0
  764. psychopy/tests/data/correctScript/.DS_Store +0 -0
  765. psychopy/tests/data/dots_height_local.png +0 -0
  766. psychopy/tests/data/dots_normAddBlend_local.png +0 -0
  767. psychopy/tests/data/dots_normHexbackground_local.png +0 -0
  768. psychopy/tests/data/dots_normNoShade_local.png +0 -0
  769. psychopy/tests/data/dots_norm_local.png +0 -0
  770. psychopy/tests/data/dots_stencil_local.png +0 -0
  771. psychopy/tests/data/elarray1_height_local.png +0 -0
  772. psychopy/tests/data/elarray1_normAddBlend_local.png +0 -0
  773. psychopy/tests/data/elarray1_normHexbackground_local.png +0 -0
  774. psychopy/tests/data/elarray1_norm_local.png +0 -0
  775. psychopy/tests/data/elarray1_stencil_local.png +0 -0
  776. psychopy/tests/data/envelopeandrcos_height_local.png +0 -0
  777. psychopy/tests/data/envelopeandrcos_normAddBlend_local.png +0 -0
  778. psychopy/tests/data/envelopeandrcos_normHexbackground_local.png +0 -0
  779. psychopy/tests/data/envelopeandrcos_norm_local.png +0 -0
  780. psychopy/tests/data/envelopeandrcos_stencil_local.png +0 -0
  781. psychopy/tests/data/envelopepowerandrcos_height_local.png +0 -0
  782. psychopy/tests/data/envelopepowerandrcos_normAddBlend_local.png +0 -0
  783. psychopy/tests/data/envelopepowerandrcos_normHexbackground_local.png +0 -0
  784. psychopy/tests/data/envelopepowerandrcos_norm_local.png +0 -0
  785. psychopy/tests/data/envelopepowerandrcos_stencil_local.png +0 -0
  786. psychopy/tests/data/gabor1_height_local.png +0 -0
  787. psychopy/tests/data/gabor1_normAddBlend_local.png +0 -0
  788. psychopy/tests/data/gabor1_normHexbackground_local.png +0 -0
  789. psychopy/tests/data/gabor1_normNoShade_local.png +0 -0
  790. psychopy/tests/data/gabor1_norm_local.png +0 -0
  791. psychopy/tests/data/gabor1_stencil_local.png +0 -0
  792. psychopy/tests/data/greyscale_normHexbackground_local.png +0 -0
  793. psychopy/tests/data/imageAndGauss_height_local.png +0 -0
  794. psychopy/tests/data/imageAndGauss_normAddBlend_local.png +0 -0
  795. psychopy/tests/data/imageAndGauss_normHexbackground_local.png +0 -0
  796. psychopy/tests/data/imageAndGauss_normNoShade_local.png +0 -0
  797. psychopy/tests/data/imageAndGauss_norm_local.png +0 -0
  798. psychopy/tests/data/imageAndGauss_stencil_local.png +0 -0
  799. psychopy/tests/data/movFrame1_stencil_local.png +0 -0
  800. psychopy/tests/data/noiseAndRcos_height_local.png +0 -0
  801. psychopy/tests/data/noiseAndRcos_normAddBlend_local.png +0 -0
  802. psychopy/tests/data/noiseAndRcos_normHexbackground_local.png +0 -0
  803. psychopy/tests/data/noiseAndRcos_normNoShade_local.png +0 -0
  804. psychopy/tests/data/noiseAndRcos_norm_local.png +0 -0
  805. psychopy/tests/data/noiseAndRcos_stencil_local.png +0 -0
  806. psychopy/tests/data/noiseFiltersAndRcos_height_local.png +0 -0
  807. psychopy/tests/data/noiseFiltersAndRcos_normAddBlend_local.png +0 -0
  808. psychopy/tests/data/noiseFiltersAndRcos_normHexbackground_local.png +0 -0
  809. psychopy/tests/data/noiseFiltersAndRcos_normNoShade_local.png +0 -0
  810. psychopy/tests/data/noiseFiltersAndRcos_norm_local.png +0 -0
  811. psychopy/tests/data/noiseFiltersAndRcos_stencil_local.png +0 -0
  812. psychopy/tests/data/numpyImage_height_local.png +0 -0
  813. psychopy/tests/data/numpyImage_normAddBlend_local.png +0 -0
  814. psychopy/tests/data/numpyImage_normHexbackground_local.png +0 -0
  815. psychopy/tests/data/numpyImage_normNoShade_local.png +0 -0
  816. psychopy/tests/data/numpyImage_norm_local.png +0 -0
  817. psychopy/tests/data/numpyImage_stencil_local.png +0 -0
  818. psychopy/tests/data/shape2_1_normAddBlend_local.png +0 -0
  819. psychopy/tests/data/shape2_1_normHexbackground_local.png +0 -0
  820. psychopy/tests/data/shape2_1_normNoShade_local.png +0 -0
  821. psychopy/tests/data/shape2_1_norm_local.png +0 -0
  822. psychopy/tests/data/shape2_1_stencil_local.png +0 -0
  823. psychopy/tests/data/text1_height_local.png +0 -0
  824. psychopy/tests/data/text1_normAddBlend_local.png +0 -0
  825. psychopy/tests/data/text1_normHexbackground_local.png +0 -0
  826. psychopy/tests/data/text1_norm_local.png +0 -0
  827. psychopy/tests/data/text1_stencil_local.png +0 -0
  828. psychopy/tests/data/wedge1_height_local.png +0 -0
  829. psychopy/tests/data/wedge1_normAddBlend_local.png +0 -0
  830. psychopy/tests/data/wedge1_normHexbackground_local.png +0 -0
  831. psychopy/tests/data/wedge1_normNoShade_local.png +0 -0
  832. psychopy/tests/data/wedge1_norm_local.png +0 -0
  833. psychopy/tests/data/wedge1_stencil_local.png +0 -0
  834. psychopy/tests/test_app/.DS_Store +0 -0
  835. psychopy/tests/test_app/test_builder/.DS_Store +0 -0
  836. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.log +0 -177
  837. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.psydat +0 -0
  838. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1206.xlsx +0 -0
  839. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.log +0 -168
  840. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.psydat +0 -0
  841. psychopy/tests/test_app/test_builder/data/_2021_ 5_03_1324.xlsx +0 -0
  842. psychopy/tests/test_data/.DS_Store +0 -0
  843. psychopy/tests/test_hardware/test_CRS_BitsSharp.py +0 -67
  844. psychopy/tests/test_hardware/test_CRS_BitsSharp.py.orig +0 -68
  845. psychopy/tests/test_hardware/test_CRS_bitsShaders.py +0 -110
  846. psychopy/tests/test_visual/test_image.py.orig +0 -219
  847. psychopy/visual/basevisual.py.orig +0 -1723
  848. psychopy/visual/form.py.orig +0 -1181
  849. psychopy/visual/text.py.orig +0 -752
  850. psychopy/visual/textbox2/textbox2.py.orig +0 -1315
  851. psychopy/visual/windowwarp.py.orig +0 -463
  852. /psychopy/{app/cortex.log → alerts/alertsCatalogue/3600.yaml} +0 -0
  853. /psychopy/{app/Resources → assets}/fonts/Arvo-Bold.ttf +0 -0
  854. /psychopy/{app/Resources → assets}/fonts/Arvo-BoldItalic.ttf +0 -0
  855. /psychopy/{app/Resources → assets}/fonts/Arvo-Italic.ttf +0 -0
  856. /psychopy/{app/Resources → assets}/fonts/Arvo-Regular.ttf +0 -0
  857. /psychopy/{app/Resources → assets}/fonts/DejaVuSerif.ttf +0 -0
  858. /psychopy/{app/Resources → assets}/fonts/IndieFlower-Regular.ttf +0 -0
  859. /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-Italic-VariableFont_wght.ttf +0 -0
  860. /psychopy/{app/Resources → assets}/fonts/JetBrainsMono-VariableFont_wght.ttf +0 -0
  861. /psychopy/demos/builder/Experiments/{GoNoGo → goNoGo}/readme.md +0 -0
  862. {psychopy-2024.2.5.dist-info → psychopy-2025.1.1.dist-info}/entry_points.txt +0 -0
  863. {psychopy-2024.2.5.dist-info → psychopy-2025.1.1.dist-info}/licenses/LICENSE +0 -0
psychopy/liaison.py CHANGED
@@ -13,13 +13,13 @@ zeroRPC
13
13
 
14
14
 
15
15
  import inspect
16
- import logging
17
16
  import asyncio
18
17
  import signal
19
18
  import json
20
19
  import sys
21
20
  import traceback
22
-
21
+ import logging as _logging
22
+ from psychopy import logging
23
23
  from psychopy.localization import _translate
24
24
 
25
25
  try:
@@ -37,9 +37,13 @@ class LiaisonJSONEncoder(json.JSONEncoder):
37
37
  string before JSONifying.
38
38
  """
39
39
  def default(self, o):
40
- # if object has a getJSON method, use it
41
- if hasattr(o, "getJSON"):
42
- return o.getJSON(asString=False)
40
+ try:
41
+ # if object has a getJSON method, use it
42
+ if hasattr(o, "getJSON"):
43
+ return o.getJSON(asString=False)
44
+ except:
45
+ # if there's an error in the getJSON method, continue so we can try regular encoding
46
+ pass
43
47
  # if object is an error, transform in standardised form
44
48
  if isinstance(o, BaseException):
45
49
  tb = traceback.format_exception(type(o), o, o.__traceback__)
@@ -56,6 +60,36 @@ class LiaisonJSONEncoder(json.JSONEncoder):
56
60
  return str(o)
57
61
 
58
62
 
63
+ class LiaisonLogger(logging._Logger):
64
+ """
65
+ Special logger for Liaison which logs any messages sent, and the direction they
66
+ were sent in (Python to JS or JS to Python). Logs both at level INFO.
67
+ """
68
+ def sent(self, message):
69
+ """
70
+ Log a message sent by Liaison
71
+ """
72
+ self.log(
73
+ message=message,
74
+ level=logging.INFO,
75
+ levelname="LIAISON PY->JS",
76
+ )
77
+ # immediately flush - we're not in a frame loop
78
+ self.flush()
79
+
80
+ def received(self, message):
81
+ """
82
+ Log a message received by Liaison
83
+ """
84
+ self.log(
85
+ message=message,
86
+ level=logging.INFO,
87
+ levelname="LIAISON JS->PY",
88
+ )
89
+ # immediately flush - we're not in a frame loop
90
+ self.flush()
91
+
92
+
59
93
  class WebSocketServer:
60
94
  """
61
95
  A simple Liaison server, using WebSockets as communication protocol.
@@ -67,19 +101,32 @@ class WebSocketServer:
67
101
  """
68
102
  # the set of currently established connections:
69
103
  self._connections = set()
104
+ self.loop = None
70
105
 
71
- # setup a logger:
72
- self._logger = logging.getLogger('liaison.WebSocketServer')
106
+ # setup a dedicated logger for messages
107
+ self.logger = LiaisonLogger()
108
+ # setup a base Python logger
109
+ self._logger = _logging.getLogger('liaison.WebSocketServer')
73
110
  self._logger.setLevel(logging.DEBUG)
74
- consoleHandler = logging.StreamHandler()
75
- consoleHandler.setLevel(logging.DEBUG)
76
- consoleHandler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
111
+ consoleHandler = _logging.StreamHandler()
112
+ consoleHandler.setLevel(_logging.DEBUG)
113
+ consoleHandler.setFormatter(_logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
77
114
  self._logger.addHandler(consoleHandler)
78
115
 
79
116
  # register the Liaison methods available to clients:
80
117
  self._methods = {
81
- 'liaison': (self, ['listRegisteredMethods', 'pingPong'])
118
+ 'liaison': (self, ['listRegisteredMethods', 'addLogFile', 'pingPong'])
82
119
  }
120
+
121
+ def addLogFile(self, file, loggingLevel=logging.INFO):
122
+ # actualize logging level
123
+ if isinstance(loggingLevel, str):
124
+ loggingLevel = getattr(logging, loggingLevel.upper())
125
+ # if given a log file, add it
126
+ logFile = logging.LogFile(
127
+ file, level=logging.DEBUG
128
+ )
129
+ self._logger.addTarget(logFile)
83
130
 
84
131
  def registerObject(self, targetObject, referenceName):
85
132
  """
@@ -205,7 +252,12 @@ class WebSocketServer:
205
252
  port : int
206
253
  the port number, e.g. 8001
207
254
  """
208
- asyncio.run(self.run(host, port))
255
+ # create a loop
256
+ self.loop = asyncio.new_event_loop()
257
+ # run loop until complete
258
+ self.loop.run_until_complete(
259
+ self.run(host, port)
260
+ )
209
261
 
210
262
  def pingPong(self):
211
263
  """
@@ -221,20 +273,20 @@ class WebSocketServer:
221
273
  Parameters
222
274
  ----------
223
275
  host : string
224
- the hostname, e.g. 'localhost'
276
+ The hostname, e.g. 'localhost'
225
277
  port : int
226
- the port number, e.g. 8001
278
+ The port number, e.g. 8001
227
279
  """
280
+ # create future for the current loop
281
+ loopFuture = self.loop.create_future()
228
282
  # set the loop future on SIGTERM or SIGINT for clean interruptions:
229
- loop = asyncio.get_running_loop()
230
- loopFuture = loop.create_future()
231
283
  if sys.platform in ("linux", "linux2"):
232
- loop.add_signal_handler(signal.SIGINT, loopFuture.set_result, None)
233
-
234
- async with websockets.serve(self._connectionHandler, host, port):
284
+ self.loop.add_signal_handler(signal.SIGINT, loopFuture.set_result, None)
285
+ # await loop's future to continuously serve
286
+ async with websockets.serve(self._connectionHandler, host, port, compression=None):
235
287
  self._logger.info(f"Liaison Server started on: {host}:{port}")
288
+ # run forever
236
289
  await loopFuture
237
- # await asyncio.Future() # run forever
238
290
 
239
291
  self._logger.info('Liaison Server terminated.')
240
292
 
@@ -250,6 +302,7 @@ class WebSocketServer:
250
302
  if not isinstance(message, str):
251
303
  message = json.dumps(message, cls=LiaisonJSONEncoder)
252
304
  for websocket in self._connections:
305
+ self.logger.sent(message)
253
306
  await websocket.send(message)
254
307
 
255
308
  def broadcastSync(self, message):
@@ -261,13 +314,11 @@ class WebSocketServer:
261
314
  message : string
262
315
  the message to be sent to all clients
263
316
  """
264
- try:
265
- # try to run in new loop
266
- asyncio.run(self.broadcast(message))
267
- except RuntimeError:
268
- # use existing if there's already a loop
269
- loop = asyncio.get_event_loop()
270
- loop.create_task(self.broadcast(message))
317
+ # run task
318
+ asyncio.run_coroutine_threadsafe(
319
+ self.broadcast(message),
320
+ loop=self.loop
321
+ )
271
322
 
272
323
  async def _connectionHandler(self, websocket):
273
324
  """
@@ -329,6 +380,8 @@ class WebSocketServer:
329
380
  message : string
330
381
  the message sent by the client to the server, as a JSON string
331
382
  """
383
+ # log message
384
+ self.logger.received(message)
332
385
  # decode the message:
333
386
  try:
334
387
  decodedMessage = json.loads(message)
@@ -356,7 +409,7 @@ class WebSocketServer:
356
409
  # try to parse json string
357
410
  try:
358
411
  arg = json.loads(arg)
359
- except json.decoder.JSONDecodeError:
412
+ except (json.decoder.JSONDecodeError, TypeError):
360
413
  pass
361
414
  # if arg is a known property, get its value
362
415
  arg = self.actualizeAttributes(arg)
@@ -396,24 +449,23 @@ class WebSocketServer:
396
449
  rawResult = await method(*args)
397
450
  else:
398
451
  rawResult = method(*args)
399
-
400
- # convert result to a string
401
- result = json.dumps(rawResult, cls=LiaisonJSONEncoder)
402
-
403
- # send a response back to the client:
404
- response = {
405
- "result": result
452
+ # prepare a response to send back to the client
453
+ rawResponse = {
454
+ "result": rawResult
406
455
  }
407
-
408
456
  # if there is a messageId in the message, add it to the response:
409
457
  if 'messageId' in decodedMessage:
410
- response['messageId'] = decodedMessage['messageId']
411
-
412
- await websocket.send(json.dumps(response))
458
+ rawResponse['messageId'] = decodedMessage['messageId']
459
+ # convert to a string before sending
460
+ response = json.dumps(rawResponse, cls=LiaisonJSONEncoder)
461
+ # send
462
+ self.logger.sent(response)
463
+ await websocket.send(response)
413
464
 
414
465
  except BaseException as err:
415
466
  # JSONify any errors
416
467
  err = json.dumps(err, cls=LiaisonJSONEncoder)
417
468
  # send to server
469
+ self.logger.sent(err)
418
470
  await websocket.send(err)
419
471
 
psychopy/locale_setup.py CHANGED
@@ -28,4 +28,14 @@ if macVer:
28
28
  from psychopy import prefs
29
29
  if not prefs.app['locale']:
30
30
  prefs.app['locale'] = u'en_US'
31
- locale.setlocale(locale.LC_ALL, str(prefs.app['locale']) + '.UTF-8')
31
+
32
+ # set the requested locale
33
+ reqLocale = str(prefs.app['locale'])
34
+ reqLocale += '.UTF-8'
35
+ try:
36
+ locale.setlocale(locale.LC_ALL, reqLocale)
37
+ except locale.Error:
38
+ # locale not found, use en_US.UTF-8
39
+ locale.setlocale(locale.LC_ALL, 'en_US.UTF-8')
40
+ print('Warning: locale {} not found, using en_US.UTF-8'.format(
41
+ reqLocale))
@@ -9,7 +9,7 @@ translation _translate():
9
9
  """
10
10
 
11
11
  # Part of the PsychoPy library
12
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
12
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
13
13
  # Distributed under the terms of the GNU General Public License (GPL).
14
14
 
15
15
  try:
@@ -9,7 +9,7 @@ translation _translate():
9
9
  """
10
10
 
11
11
  # Part of the PsychoPy library
12
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
12
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
13
13
  # Distributed under the terms of the GNU General Public License (GPL).
14
14
 
15
15
  # Author: Jeremy Gray, July 2014
@@ -329,7 +329,7 @@ msgid "Copyright (C) {year} OpenScienceTools.org"
329
329
  msgstr ""
330
330
 
331
331
  #: ../app/_psychopyApp.py:518
332
- msgid " Creating frames..."
332
+ msgid "Creating frames..."
333
333
  msgstr ""
334
334
 
335
335
  #: ../app/_psychopyApp.py:559
@@ -365,7 +365,7 @@ msgid "tips.txt"
365
365
  msgstr ""
366
366
 
367
367
  #: ../app/_psychopyApp.py:662
368
- msgid " Loading plugins..."
368
+ msgid "Loading plugins..."
369
369
  msgstr ""
370
370
 
371
371
  #: ../app/_psychopyApp.py:746
psychopy/logging.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Provides functions for logging error and other messages to one or more
@@ -127,12 +127,14 @@ def setDefaultClock(clock):
127
127
 
128
128
  class _LogEntry():
129
129
 
130
- def __init__(self, level, message, t=None, obj=None):
130
+ def __init__(self, level, message, t=None, obj=None, levelname=None):
131
131
  super(_LogEntry, self).__init__()
132
132
  self.t = t
133
133
  self.t_ms = t * 1000
134
134
  self.level = level
135
- self.levelname = getLevel(level)
135
+ if levelname is None:
136
+ levelname = getLevel(level)
137
+ self.levelname = levelname
136
138
  self.message = message
137
139
  self.obj = obj
138
140
 
@@ -275,7 +277,7 @@ class _Logger():
275
277
  for target in self.targets:
276
278
  self.lowestTarget = min(self.lowestTarget, target.level)
277
279
 
278
- def log(self, message, level, t=None, obj=None):
280
+ def log(self, message, level, t=None, obj=None, levelname=None):
279
281
  """Add the `message` to the log stack at the appropriate `level`
280
282
 
281
283
  If no relevant targets (files or console) exist then the message is
@@ -290,7 +292,7 @@ class _Logger():
290
292
  t = defaultClock.getTime()
291
293
  # add message to list
292
294
  self.toFlush.append(
293
- _LogEntry(t=t, level=level, message=message, obj=obj))
295
+ _LogEntry(t=t, level=level, levelname=levelname, message=message, obj=obj))
294
296
 
295
297
  def flush(self):
296
298
  """Process all current messages to each target
@@ -329,7 +331,7 @@ def critical(msg, t=None, obj=None):
329
331
  Send the message to any receiver of logging info (e.g. a LogFile)
330
332
  of level `log.CRITICAL` or higher
331
333
  """
332
- root.log(msg, level=CRITICAL, t=t, obj=obj)
334
+ root.log(msg, level=CRITICAL, t=t, obj=obj, levelname="CRITICAL")
333
335
  fatal = critical
334
336
 
335
337
 
@@ -339,7 +341,7 @@ def error(msg, t=None, obj=None):
339
341
  Send the message to any receiver of logging info (e.g. a LogFile)
340
342
  of level `log.ERROR` or higher
341
343
  """
342
- root.log(msg, level=ERROR, t=t, obj=obj)
344
+ root.log(msg, level=ERROR, t=t, obj=obj, levelname="ERROR")
343
345
 
344
346
 
345
347
  def warning(msg, t=None, obj=None):
@@ -348,7 +350,7 @@ def warning(msg, t=None, obj=None):
348
350
  Sends the message to any receiver of logging info (e.g. a LogFile)
349
351
  of level `log.WARNING` or higher
350
352
  """
351
- root.log(msg, level=WARNING, t=t, obj=obj)
353
+ root.log(msg, level=WARNING, t=t, obj=obj, levelname="WARNING")
352
354
  warn = warning
353
355
 
354
356
 
@@ -361,7 +363,7 @@ def data(msg, t=None, obj=None):
361
363
  Sends the message to any receiver of logging info (e.g. a LogFile)
362
364
  of level `log.DATA` or higher
363
365
  """
364
- root.log(msg, level=DATA, t=t, obj=obj)
366
+ root.log(msg, level=DATA, t=t, obj=obj, levelname="DATA")
365
367
 
366
368
 
367
369
  def exp(msg, t=None, obj=None):
@@ -374,7 +376,7 @@ def exp(msg, t=None, obj=None):
374
376
  Sends the message to any receiver of logging info (e.g. a LogFile)
375
377
  of level `log.EXP` or higher
376
378
  """
377
- root.log(msg, level=EXP, t=t, obj=obj)
379
+ root.log(msg, level=EXP, t=t, obj=obj, levelname="EXP")
378
380
 
379
381
 
380
382
  def info(msg, t=None, obj=None):
@@ -386,7 +388,7 @@ def info(msg, t=None, obj=None):
386
388
  Sends the message to any receiver of logging info (e.g. a LogFile)
387
389
  of level `log.INFO` or higher
388
390
  """
389
- root.log(msg, level=INFO, t=t, obj=obj)
391
+ root.log(msg, level=INFO, t=t, obj=obj, levelname="INFO")
390
392
 
391
393
 
392
394
  def debug(msg, t=None, obj=None):
@@ -399,7 +401,7 @@ def debug(msg, t=None, obj=None):
399
401
  Sends the message to any receiver of logging info (e.g. a LogFile)
400
402
  of level `log.DEBUG` or higher
401
403
  """
402
- root.log(msg, level=DEBUG, t=t, obj=obj)
404
+ root.log(msg, level=DEBUG, t=t, obj=obj, levelname="DEBUG")
403
405
 
404
406
 
405
407
  def log(msg, level, t=None, obj=None):
psychopy/microphone.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Audio capture and analysis using pyo.
@@ -13,12 +13,13 @@ These are optional components that can be obtained by installing the
13
13
  """
14
14
 
15
15
 
16
- from psychopy.tools.pkgtools import PluginStub
16
+ from psychopy.plugins import PluginStub
17
17
 
18
18
 
19
19
  class AudioCapture(
20
20
  PluginStub,
21
- plugin="psychopy-legacy-mic"
21
+ plugin="psychopy-legacy-mic",
22
+ docsHome="https://github.com/psychopy/psychopy-legacy-mic",
22
23
  ):
23
24
  pass
24
25
 
psychopy/misc.py CHANGED
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Wrapper for all miscellaneous functions and classes from psychopy.tools
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  import time
@@ -42,7 +42,7 @@ if not hasattr(wx.grid, 'EVT_GRID_CELL_CHANGED'):
42
42
 
43
43
  # wx IDs for menu items
44
44
  def newIds(n):
45
- return [wx.NewId() for i in range(n)]
45
+ return [wx.NewIdRef(count=1) for i in range(n)]
46
46
 
47
47
  [idMenuSave] = newIds(1)
48
48
  # wx IDs for controllers (admin panel)
@@ -228,7 +228,7 @@ class MainFrame(wx.Frame):
228
228
 
229
229
  # Edit
230
230
  editMenu = wx.Menu()
231
- id = wx.NewId()
231
+ id = wx.NewIdRef(count=1)
232
232
  _hint = _translate("Copy the current monitor's name to clipboard")
233
233
  editMenu.Append(id, _translate('Copy\tCtrl+C'), _hint)
234
234
  self.Bind(wx.EVT_MENU, self.onCopyMon, id=id)
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  from .calibTools import *
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Data useful for calibrations (Smith-Pokorny cone fundamentals etc...)
@@ -5,11 +5,11 @@
5
5
  """
6
6
 
7
7
  # Part of the PsychoPy library
8
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
8
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
9
9
  # Distributed under the terms of the GNU General Public License (GPL).
10
10
 
11
11
  from .calibData import wavelength_5nm, juddVosXYZ1976_5nm, cones_SmithPokorny
12
- from psychopy import __version__, logging, hardware
12
+ from psychopy import __version__, logging
13
13
 
14
14
  try:
15
15
  import serial
@@ -1116,6 +1116,7 @@ def getRGBspectra(stimSize=0.3, winSize=(800, 600), photometer='COM1'):
1116
1116
  photom = photometer
1117
1117
  else:
1118
1118
  # setup photom
1119
+ from psychopy import hardware
1119
1120
  photom = hardware.Photometer(photometer)
1120
1121
  if photom != None:
1121
1122
  havephotom = 1
@@ -4,7 +4,7 @@
4
4
  """Platform specific extensions (using ctypes)"""
5
5
 
6
6
  # Part of the PsychoPy library
7
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
7
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
8
8
  # Distributed under the terms of the GNU General Public License (GPL).
9
9
 
10
10
  import sys
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  from psychopy import logging
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  """Placeholder for adding c (or ctypes) extensions to PsychoPy on linux.
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
 
8
8
  # These are correct for win32, not sure about 64bit versions
@@ -2,11 +2,13 @@
2
2
  # -*- coding: utf-8 -*-
3
3
 
4
4
  # Part of the PsychoPy library
5
- # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2024 Open Science Tools Ltd.
5
+ # Copyright (C) 2002-2018 Jonathan Peirce (C) 2019-2025 Open Science Tools Ltd.
6
6
  # Distributed under the terms of the GNU General Public License (GPL).
7
7
  """Utilities for extending PsychoPy with plugins."""
8
8
 
9
9
  __all__ = [
10
+ 'PluginStub',
11
+ 'PluginRequiredError',
10
12
  'loadPlugin',
11
13
  'listPlugins',
12
14
  'installPlugin',
@@ -25,6 +27,7 @@ __all__ = [
25
27
  ]
26
28
 
27
29
  import os
30
+ from pathlib import Path
28
31
  import sys
29
32
  import inspect
30
33
  import collections
@@ -32,6 +35,7 @@ import hashlib
32
35
  import importlib, importlib.metadata
33
36
  from psychopy import logging
34
37
  from psychopy.preferences import prefs
38
+ from .util import PluginStub, PluginRequiredError
35
39
 
36
40
  # Configure the environment to use our custom site-packages location for
37
41
  # user-installed packages (i.e. plugins).
@@ -780,6 +784,10 @@ def loadPlugin(plugin):
780
784
  # _failed_plugins_.append(plugin)
781
785
  #
782
786
  # return False
787
+ # log that we're loading the entry point
788
+ logging.debug(
789
+ f"Registering entry point {ep.value} (from {plugin}) to {ep.group}:{ep.name}"
790
+ )
783
791
  try:
784
792
  ep = ep.load() # load the entry point
785
793
 
@@ -788,26 +796,21 @@ def loadPlugin(plugin):
788
796
  logging.warning(
789
797
  "Plugin `{}` is being loaded from a zip file. This may "
790
798
  "cause issues with the plugin's functionality.".format(plugin))
791
-
792
- except ImportError as e:
793
- logging.error(
794
- "Failed to load entry point `{}` of plugin `{}`. "
795
- "(`{}: {}`) "
796
- "Skipping.".format(str(ep), plugin, e.name, e.msg))
797
-
798
- if plugin not in _failed_plugins_:
799
- _failed_plugins_.append(plugin)
800
-
801
- return False
802
- except Exception: # catch everything else
803
- logging.error(
804
- "Failed to load entry point `{}` of plugin `{}` for unknown"
805
- " reasons. Skipping.".format(str(ep), plugin))
799
+ except Exception as err:
800
+ # generic start of message
801
+ msg = f"Skipping entry point {ep.value} (from {plugin}) to {ep.group}:{ep.name}"
802
+ # append reason
803
+ if isinstance(err, ImportError):
804
+ msg += f" as {ep.value} cannot be imported."
805
+ else:
806
+ msg += f", reason: {err}"
807
+ # log message
808
+ logging.error(msg)
806
809
 
807
810
  if plugin not in _failed_plugins_:
808
811
  _failed_plugins_.append(plugin)
809
812
 
810
- return False
813
+ continue
811
814
 
812
815
  # If we get here, the entry point is valid and we can safely add it
813
816
  # to PsychoPy's namespace.
@@ -839,6 +842,12 @@ def loadPlugin(plugin):
839
842
  _registerBuilderStandaloneRoutine(ep)
840
843
  elif fqn == 'psychopy.hardware.photometer': # photometer
841
844
  _registerPhotometer(ep)
845
+ elif fqn == "psychopy.app.themes.icons":
846
+ # get module folder
847
+ folder = Path(ep.__file__).parent
848
+ # add all matching .png files from that folder
849
+ for file in folder.glob(f"**/*.png"):
850
+ targObj.pluginIconFiles.append(file)
842
851
 
843
852
  # Retain information about the plugin's entry points, we will use this for
844
853
  # conflict resolution.