psychopy 2024.1.3__py3-none-any.whl → 2024.2.0__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 (331) hide show
  1. psychopy/.DS_Store +0 -0
  2. psychopy/CHANGELOG.txt +206 -0
  3. psychopy/GIT_SHA +1 -0
  4. psychopy/VERSION +1 -0
  5. psychopy/__init__.py +77 -15
  6. psychopy/app/Resources/classic/plugin16.png +0 -0
  7. psychopy/app/Resources/classic/plugin16@2x.png +0 -0
  8. psychopy/app/Resources/dark/plugin16.png +0 -0
  9. psychopy/app/Resources/dark/plugin16@2x.png +0 -0
  10. psychopy/app/Resources/light/plugin16.png +0 -0
  11. psychopy/app/Resources/light/plugin16@2x.png +0 -0
  12. psychopy/app/__init__.py +76 -2
  13. psychopy/app/_psychopyApp.py +126 -101
  14. psychopy/app/builder/builder.py +14 -10
  15. psychopy/app/builder/dialogs/__init__.py +8 -8
  16. psychopy/app/builder/dialogs/dlgsConditions.py +12 -13
  17. psychopy/app/builder/dialogs/paramCtrls.py +24 -57
  18. psychopy/app/builder/localizedStrings.py +11 -9
  19. psychopy/app/builder/validators.py +2 -2
  20. psychopy/app/coder/codeEditorBase.py +8 -8
  21. psychopy/app/coder/coder.py +4 -4
  22. psychopy/app/connections/sendusage.py +2 -2
  23. psychopy/app/connections/updates.py +9 -9
  24. psychopy/app/dialogs.py +34 -2
  25. psychopy/app/idle.py +31 -0
  26. psychopy/app/jobs.py +21 -3
  27. psychopy/app/linuxconfig/__init__.py +9 -0
  28. psychopy/app/locale/ar_001/LC_MESSAGE/messages.mo +0 -0
  29. psychopy/app/locale/ar_001/LC_MESSAGE/messages.po +4602 -2540
  30. psychopy/app/locale/es_CO/LC_MESSAGE/messages.mo +0 -0
  31. psychopy/app/locale/es_CO/LC_MESSAGE/messages.po +56 -54
  32. psychopy/app/locale/es_ES/LC_MESSAGE/messages.po +53 -43
  33. psychopy/app/locale/es_US/LC_MESSAGE/messages.mo +0 -0
  34. psychopy/app/locale/es_US/LC_MESSAGE/messages.po +56 -54
  35. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.mo +0 -0
  36. psychopy/app/locale/ja_JP/LC_MESSAGE/messages.po +1258 -1176
  37. psychopy/app/locale/pt_PT/LC_MESSAGE/messages.po +9415 -5
  38. psychopy/app/pavlovia_ui/_base.py +33 -3
  39. psychopy/app/pavlovia_ui/search.py +0 -1
  40. psychopy/app/plugin_manager/dialog.py +104 -51
  41. psychopy/app/plugin_manager/packages.py +5 -0
  42. psychopy/app/plugin_manager/plugins.py +152 -67
  43. psychopy/app/preferencesDlg.py +8 -8
  44. psychopy/app/psychopyApp.py +11 -5
  45. psychopy/app/ribbon.py +124 -14
  46. psychopy/app/runner/runner.py +6 -1
  47. psychopy/app/stdout/stdOutRich.py +27 -11
  48. psychopy/app/themes/icons.py +52 -2
  49. psychopy/assets/__init__.py +0 -0
  50. psychopy/assets/click.png +0 -0
  51. psychopy/assets/clicknext.png +0 -0
  52. psychopy/assets/next.png +0 -0
  53. psychopy/assets/psychopy.ico +0 -0
  54. psychopy/assets/psychopy.png +0 -0
  55. psychopy/assets/templates/__init__.py +0 -0
  56. psychopy/assets/touch.png +0 -0
  57. psychopy/assets/touchnext.png +0 -0
  58. psychopy/assets/window.ico +0 -0
  59. psychopy/changes/2023.1.0.md +9 -0
  60. psychopy/changes/2024.1.0.md +16 -0
  61. psychopy/changes/__init__.py +0 -0
  62. psychopy/clock.py +2 -2
  63. psychopy/colors.py +2 -1
  64. psychopy/compatibility.py +53 -1
  65. psychopy/contrib/.DS_Store +0 -0
  66. psychopy/contrib/configobj/__init__.py +10 -8
  67. psychopy/data/__init__.py +3 -2
  68. psychopy/data/base.py +5 -5
  69. psychopy/data/experiment.py +130 -4
  70. psychopy/data/routine.py +56 -0
  71. psychopy/data/staircase.py +2 -2
  72. psychopy/data/trial.py +559 -97
  73. psychopy/data/utils.py +56 -21
  74. psychopy/demos/.DS_Store +0 -0
  75. psychopy/demos/builder/.DS_Store +0 -0
  76. psychopy/demos/builder/Design Templates/.DS_Store +0 -0
  77. psychopy/demos/builder/Experiments/.DS_Store +0 -0
  78. psychopy/demos/builder/Feature Demos/.DS_Store +0 -0
  79. psychopy/demos/builder/Feature Demos/buttonBox/buttonBoxDemo.psyexp +375 -0
  80. psychopy/demos/builder/Feature Demos/buttonBox/readme.md +5 -0
  81. psychopy/demos/builder/Feature Demos/pilotMode/pilotMode.psyexp +433 -0
  82. psychopy/demos/builder/Feature Demos/pilotMode/readme.md +7 -0
  83. psychopy/demos/builder/Feature Demos/progress/progressBar.psyexp +4 -4
  84. psychopy/demos/builder/Hardware/.DS_Store +0 -0
  85. psychopy/demos/builder/Helper Tools/.DS_Store +0 -0
  86. psychopy/demos/coder/.DS_Store +0 -0
  87. psychopy/demos/coder/hardware/testSoundLatency.py +2 -2
  88. psychopy/demos/coder/iohub/.DS_Store +0 -0
  89. psychopy/demos/coder/misc/hdf5_2_csv +33 -0
  90. psychopy/event.py +30 -29
  91. psychopy/experiment/.DS_Store +0 -0
  92. psychopy/experiment/_experiment.py +6 -6
  93. psychopy/experiment/components/.DS_Store +0 -0
  94. psychopy/experiment/components/__init__.py +6 -3
  95. psychopy/experiment/components/_base.py +286 -131
  96. psychopy/experiment/components/aperture/.DS_Store +0 -0
  97. psychopy/experiment/components/brush/.DS_Store +0 -0
  98. psychopy/experiment/components/button/.DS_Store +0 -0
  99. psychopy/experiment/components/button/__init__.py +5 -1
  100. psychopy/experiment/components/buttonBox/.DS_Store +0 -0
  101. psychopy/experiment/components/buttonBox/__init__.py +21 -12
  102. psychopy/experiment/components/camera/.DS_Store +0 -0
  103. psychopy/experiment/components/code/.DS_Store +0 -0
  104. psychopy/experiment/components/dots/.DS_Store +0 -0
  105. psychopy/experiment/components/eyetracker_record/.DS_Store +0 -0
  106. psychopy/experiment/components/eyetracker_record/__init__.py +92 -30
  107. psychopy/experiment/components/form/.DS_Store +0 -0
  108. psychopy/experiment/components/form/__init__.py +6 -2
  109. psychopy/experiment/components/grating/.DS_Store +0 -0
  110. psychopy/experiment/components/grating/__init__.py +14 -3
  111. psychopy/experiment/components/image/.DS_Store +0 -0
  112. psychopy/experiment/components/image/__init__.py +14 -3
  113. psychopy/experiment/components/joyButtons/.DS_Store +0 -0
  114. psychopy/experiment/components/joystick/.DS_Store +0 -0
  115. psychopy/experiment/components/keyboard/.DS_Store +0 -0
  116. psychopy/experiment/components/keyboard/__init__.py +22 -10
  117. psychopy/experiment/components/microphone/.DS_Store +0 -0
  118. psychopy/experiment/components/microphone/__init__.py +59 -39
  119. psychopy/experiment/components/mouse/.DS_Store +0 -0
  120. psychopy/experiment/components/mouse/__init__.py +44 -29
  121. psychopy/experiment/components/movie/.DS_Store +0 -0
  122. psychopy/experiment/components/movie/__init__.py +1 -1
  123. psychopy/experiment/components/panorama/.DS_Store +0 -0
  124. psychopy/experiment/components/parallelOut/.DS_Store +0 -0
  125. psychopy/experiment/components/patch/.DS_Store +0 -0
  126. psychopy/experiment/components/polygon/.DS_Store +0 -0
  127. psychopy/experiment/components/polygon/__init__.py +26 -6
  128. psychopy/experiment/components/progress/.DS_Store +0 -0
  129. psychopy/experiment/components/progress/__init__.py +1 -1
  130. psychopy/experiment/components/ratingScale/.DS_Store +0 -0
  131. psychopy/experiment/components/resourceManager/.DS_Store +0 -0
  132. psychopy/experiment/components/roi/.DS_Store +0 -0
  133. psychopy/experiment/components/roi/__init__.py +5 -0
  134. psychopy/experiment/components/routineSettings/.DS_Store +0 -0
  135. psychopy/experiment/components/routineSettings/__init__.py +57 -10
  136. psychopy/experiment/components/serialOut/.DS_Store +0 -0
  137. psychopy/experiment/components/settings/.DS_Store +0 -0
  138. psychopy/experiment/components/settings/__init__.py +117 -42
  139. psychopy/experiment/components/slider/.DS_Store +0 -0
  140. psychopy/experiment/components/sound/.DS_Store +0 -0
  141. psychopy/experiment/components/sound/__init__.py +54 -19
  142. psychopy/experiment/components/static/.DS_Store +0 -0
  143. psychopy/experiment/components/static/__init__.py +1 -1
  144. psychopy/experiment/components/text/.DS_Store +0 -0
  145. psychopy/experiment/components/text/__init__.py +28 -3
  146. psychopy/experiment/components/textbox/.DS_Store +0 -0
  147. psychopy/experiment/components/textbox/__init__.py +12 -2
  148. psychopy/experiment/components/unknown/.DS_Store +0 -0
  149. psychopy/experiment/components/unknown/__init__.py +1 -2
  150. psychopy/experiment/components/unknownPlugin/.DS_Store +0 -0
  151. psychopy/experiment/components/unknownPlugin/__init__.py +2 -2
  152. psychopy/experiment/components/variable/.DS_Store +0 -0
  153. psychopy/experiment/flow.py +11 -4
  154. psychopy/experiment/loops.py +85 -37
  155. psychopy/experiment/params.py +74 -32
  156. psychopy/experiment/py2js_transpiler.py +8 -1
  157. psychopy/experiment/routines/.DS_Store +0 -0
  158. psychopy/experiment/routines/_base.py +102 -22
  159. psychopy/experiment/routines/counterbalance/.DS_Store +0 -0
  160. psychopy/experiment/routines/counterbalance/__init__.py +5 -1
  161. psychopy/experiment/routines/eyetracker_calibrate/.DS_Store +0 -0
  162. psychopy/experiment/routines/eyetracker_validate/.DS_Store +0 -0
  163. psychopy/experiment/routines/pavlovia_survey/.DS_Store +0 -0
  164. psychopy/experiment/routines/photodiodeValidator/.DS_Store +0 -0
  165. psychopy/experiment/routines/photodiodeValidator/__init__.py +7 -6
  166. psychopy/experiment/routines/unknown/.DS_Store +0 -0
  167. psychopy/gui/wxgui.py +4 -4
  168. psychopy/hardware/.DS_Store +0 -0
  169. psychopy/hardware/__init__.py +1 -1
  170. psychopy/hardware/base.py +12 -0
  171. psychopy/hardware/camera/__init__.py +1 -15
  172. psychopy/hardware/cedrus.py +10 -11
  173. psychopy/hardware/crs/colorcal.py +13 -22
  174. psychopy/hardware/crs/optical.py +10 -20
  175. psychopy/hardware/emulator.py +17 -14
  176. psychopy/hardware/eyetracker.py +42 -118
  177. psychopy/hardware/gammasci.py +4 -15
  178. psychopy/hardware/keyboard.py +102 -11
  179. psychopy/hardware/listener.py +3 -0
  180. psychopy/hardware/microphone.py +148 -18
  181. psychopy/hardware/minolta.py +8 -15
  182. psychopy/hardware/photodiode.py +191 -16
  183. psychopy/hardware/photometer/__init__.py +11 -19
  184. psychopy/hardware/pr.py +8 -15
  185. psychopy/hardware/speaker.py +39 -4
  186. psychopy/info.py +0 -71
  187. psychopy/iohub/.DS_Store +0 -0
  188. psychopy/iohub/__init__.py +1 -1
  189. psychopy/iohub/client/__init__.py +30 -20
  190. psychopy/iohub/client/keyboard.py +24 -24
  191. psychopy/iohub/datastore/__init__.py +2 -2
  192. psychopy/iohub/datastore/util.py +2 -2
  193. psychopy/iohub/default_config.yaml +1 -1
  194. psychopy/iohub/devices/.DS_Store +0 -0
  195. psychopy/iohub/devices/__init__.py +112 -25
  196. psychopy/iohub/devices/deviceConfigValidation.py +2 -1
  197. psychopy/iohub/devices/experiment/default_experiment.yaml +12 -1
  198. psychopy/iohub/devices/experiment/supported_config_settings.yaml +5 -1
  199. psychopy/iohub/devices/eyetracker/.DS_Store +0 -0
  200. psychopy/iohub/devices/eyetracker/__init__.py +46 -0
  201. psychopy/iohub/devices/eyetracker/calibration/procedure.py +2 -2
  202. psychopy/iohub/devices/eyetracker/hw/gazepoint/__init__.py +14 -2
  203. psychopy/iohub/devices/eyetracker/hw/mouse/eyetracker.py +3 -4
  204. psychopy/iohub/server.py +2 -2
  205. psychopy/iohub/start_iohub_process.py +3 -0
  206. psychopy/iohub/util/__init__.py +62 -70
  207. psychopy/layout.py +5 -5
  208. psychopy/logging.py +8 -1
  209. psychopy/microphone.py +10 -37
  210. psychopy/platform_specific/__init__.py +0 -2
  211. psychopy/platform_specific/darwin.py +1 -3
  212. psychopy/platform_specific/linux.py +31 -33
  213. psychopy/platform_specific/win32.py +38 -13
  214. psychopy/plugins/__init__.py +148 -116
  215. psychopy/plugins/util.py +39 -0
  216. psychopy/preferences/Darwin.spec +4 -2
  217. psychopy/preferences/FreeBSD.spec +4 -2
  218. psychopy/preferences/Linux.spec +4 -2
  219. psychopy/preferences/Windows.spec +4 -2
  220. psychopy/preferences/baseNoArch.spec +4 -2
  221. psychopy/preferences/preferences.py +47 -24
  222. psychopy/projects/pavlovia.py +47 -4
  223. psychopy/scripts/psyexpCompile.py +0 -4
  224. psychopy/session.py +153 -21
  225. psychopy/sound/__init__.py +31 -21
  226. psychopy/sound/_base.py +20 -3
  227. psychopy/sound/audioclip.py +320 -33
  228. psychopy/sound/backend_ptb.py +47 -58
  229. psychopy/sound/backend_pygame.py +1 -1
  230. psychopy/sound/backend_pysound.py +6 -15
  231. psychopy/sound/transcribe.py +53 -0
  232. psychopy/tests/.DS_Store +0 -0
  233. psychopy/tests/data/.DS_Store +0 -0
  234. psychopy/tests/data/TestUnknownPluginComponent_load_resave.psyexp +135 -0
  235. psychopy/tests/data/Test_textbox/test_ori_0_bottom right.png +0 -0
  236. psychopy/tests/data/Test_textbox/test_ori_0_center.png +0 -0
  237. psychopy/tests/data/Test_textbox/test_ori_0_top left.png +0 -0
  238. psychopy/tests/data/Test_textbox/test_ori_120_bottom right.png +0 -0
  239. psychopy/tests/data/Test_textbox/test_ori_120_center.png +0 -0
  240. psychopy/tests/data/Test_textbox/test_ori_120_top left.png +0 -0
  241. psychopy/tests/data/Test_textbox/test_ori_180_bottom right.png +0 -0
  242. psychopy/tests/data/Test_textbox/test_ori_180_center.png +0 -0
  243. psychopy/tests/data/Test_textbox/test_ori_180_top left.png +0 -0
  244. psychopy/tests/data/Test_textbox/test_ori_240_bottom right.png +0 -0
  245. psychopy/tests/data/Test_textbox/test_ori_240_center.png +0 -0
  246. psychopy/tests/data/Test_textbox/test_ori_240_top left.png +0 -0
  247. psychopy/tests/data/correctScript/.DS_Store +0 -0
  248. psychopy/tests/data/test_components/testClearKeyboard/testClearKeyboard.psyexp +200 -0
  249. psychopy/tests/data/test_session/.DS_Store +0 -0
  250. psychopy/tests/data/test_session/root/testFutureTrials/testFutureTrials.psyexp +155 -0
  251. psychopy/tests/data/test_session/root/testTrialNav/trialNav.psyexp +158 -0
  252. psychopy/tests/test_app/.DS_Store +0 -0
  253. psychopy/tests/test_app/conftest.py +2 -2
  254. psychopy/tests/test_app/test_speed.py +4 -1
  255. psychopy/tests/test_data/test_TrialHandler2.py +146 -1
  256. psychopy/tests/test_experiment/.DS_Store +0 -0
  257. psychopy/tests/test_experiment/needs_wx/genComponsTemplate.py +3 -3
  258. psychopy/tests/test_experiment/needs_wx/test_components.py +2 -2
  259. psychopy/tests/test_experiment/test_components/test_KeyboardComponent.py +28 -0
  260. psychopy/tests/test_experiment/test_components/test_UnknownPluginComponent.py +27 -0
  261. psychopy/tests/test_experiment/test_components/test_base_components.py +58 -0
  262. psychopy/tests/test_experiment/test_py2js.py +1 -1
  263. psychopy/tests/test_hardware/test_keyboard.py +184 -16
  264. psychopy/tests/test_hardware/test_ports.py +1 -11
  265. psychopy/tests/test_liaison/test_Liaison.py +47 -0
  266. psychopy/tests/test_misc/test_core.py +5 -0
  267. psychopy/tests/test_session/test_Session.py +5 -1
  268. psychopy/tests/test_tools/test_versionchooser.py +39 -8
  269. psychopy/tests/test_visual/test_all_stimuli.py +0 -97
  270. psychopy/tests/test_visual/test_image.py +6 -5
  271. psychopy/tests/test_visual/test_textbox.py +36 -0
  272. psychopy/tests/utils.py +4 -0
  273. psychopy/tools/filetools.py +1 -1
  274. psychopy/tools/pkgtools.py +160 -137
  275. psychopy/tools/versionchooser.py +10 -10
  276. psychopy/tools/wizard.py +3 -3
  277. psychopy/visual/.DS_Store +0 -0
  278. psychopy/visual/backends/pygletbackend.py +24 -13
  279. psychopy/visual/basevisual.py +5 -11
  280. psychopy/visual/button.py +2 -14
  281. psychopy/visual/helpers.py +5 -5
  282. psychopy/visual/line.py +1 -2
  283. psychopy/visual/movie2.py +7 -816
  284. psychopy/visual/movie3.py +7 -589
  285. psychopy/visual/movies/__init__.py +8 -11
  286. psychopy/visual/movies/frame.py +5 -2
  287. psychopy/visual/movies/players/ffpyplayer_player.py +5 -2
  288. psychopy/visual/noise.py +8 -7
  289. psychopy/visual/patch.py +7 -16
  290. psychopy/visual/progress.py +1 -1
  291. psychopy/visual/radial.py +9 -7
  292. psychopy/visual/ratingscale.py +8 -1415
  293. psychopy/visual/secondorder.py +10 -9
  294. psychopy/visual/shape.py +7 -2
  295. psychopy/visual/text.py +1 -1
  296. psychopy/visual/textbox2/textbox2.py +28 -5
  297. psychopy/web.py +5 -2
  298. {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/METADATA +8 -13
  299. {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/RECORD +313 -219
  300. {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/WHEEL +1 -1
  301. psychopy/app/Resources/click.png +0 -0
  302. psychopy/app/Resources/next.png +0 -0
  303. psychopy/experiment/components/patch/__init__.py +0 -121
  304. psychopy/experiment/components/patch/classic/patch.png +0 -0
  305. psychopy/experiment/components/patch/dark/patch.png +0 -0
  306. psychopy/experiment/components/patch/dark/patch@2x.png +0 -0
  307. psychopy/experiment/components/patch/light/patch.png +0 -0
  308. psychopy/experiment/components/patch/light/patch@2x.png +0 -0
  309. psychopy/experiment/components/ratingScale/__init__.py +0 -337
  310. psychopy/experiment/components/ratingScale/classic/ratingscale.png +0 -0
  311. psychopy/experiment/components/ratingScale/classic/ratingscale@2x.png +0 -0
  312. psychopy/experiment/components/ratingScale/dark/ratingScale@2x.png +0 -0
  313. psychopy/experiment/components/ratingScale/dark/ratingscale.png +0 -0
  314. psychopy/experiment/components/ratingScale/light/ratingScale@2x.png +0 -0
  315. psychopy/experiment/components/ratingScale/light/ratingscale.png +0 -0
  316. psychopy/platform_specific/posix.py +0 -16
  317. psychopy/tests/test_sound/test_microphone.py +0 -217
  318. psychopy/tests/test_visual/test_ratingScale.py +0 -299
  319. /psychopy/{app/Resources → assets}/Psychopy Window Favicon@16w.png +0 -0
  320. /psychopy/{app/Resources → assets}/Psychopy Window Favicon@32w.png +0 -0
  321. /psychopy/{app/Resources → assets}/USB-C.png +0 -0
  322. /psychopy/{app/Resources → assets}/USB.png +0 -0
  323. /psychopy/{app/Resources → assets}/creditCard.png +0 -0
  324. /psychopy/{app/Resources → assets}/default.mp3 +0 -0
  325. /psychopy/{app/Resources → assets}/default.mp4 +0 -0
  326. /psychopy/{app/Resources → assets}/default.png +0 -0
  327. /psychopy/{app/Resources → assets/templates}/instruct1.png +0 -0
  328. /psychopy/{app/Resources → assets/templates}/instruct2.png +0 -0
  329. {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/entry_points.txt +0 -0
  330. {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/licenses/AUTHORS.md +0 -0
  331. {psychopy-2024.1.3.dist-info → psychopy-2024.2.0.dist-info}/licenses/LICENSE +0 -0
@@ -102,6 +102,42 @@ class Test_textbox(_TestColorMixin, _TestUnitsMixin, _TestBoilerplateMixin):
102
102
  #self.win.getMovieFrame(buffer='back').save(Path(utils.TESTS_DATA_PATH) / filename)
103
103
  utils.compareScreenshot(Path(utils.TESTS_DATA_PATH) / filename, self.win, crit=20)
104
104
 
105
+ def test_ori(self):
106
+ # setup textbox
107
+ self.textbox.color = "black"
108
+ self.textbox.fillColor = "white"
109
+ self.textbox.units = "pix"
110
+ self.textbox.size = (100, 50)
111
+ self.textbox.pos = (0, 0)
112
+ self.textbox.letterHeight = 5
113
+ # define params to use
114
+ orientations = [
115
+ 0, 120, 180, 240,
116
+ ]
117
+ anchors = [
118
+ "top left", "center", "bottom right",
119
+ ]
120
+ # try each combination
121
+ for ori in orientations:
122
+ for anchor in anchors:
123
+ # flip
124
+ self.win.flip()
125
+ # set params
126
+ self.textbox.ori = ori
127
+ self.textbox.anchor = anchor
128
+ self.textbox._layout()
129
+ # draw
130
+ self.textbox.draw()
131
+ # construct exemplar filename
132
+ exemplar = f"test_ori_{ori}_{anchor}.png"
133
+ # check/make exemplar
134
+ # self.win.getMovieFrame(buffer='back').save(
135
+ # Path(utils.TESTS_DATA_PATH) / "Test_textbox" / exemplar
136
+ # )
137
+ utils.compareScreenshot(
138
+ Path(utils.TESTS_DATA_PATH) / "Test_textbox" / exemplar, self.win, crit=20
139
+ )
140
+
105
141
  def test_colors(self):
106
142
  # Do base tests
107
143
  _TestColorMixin.test_colors(self)
psychopy/tests/utils.py CHANGED
@@ -6,6 +6,7 @@ import shutil
6
6
  import numpy as np
7
7
  import io
8
8
  from psychopy import logging, colors
9
+ from psychopy.tools import systemtools
9
10
 
10
11
  try:
11
12
  from PIL import Image
@@ -14,6 +15,9 @@ except ImportError:
14
15
 
15
16
  import pytest
16
17
 
18
+ # boolean indicating whether tests are running in a VM
19
+ RUNNING_IN_VM = systemtools.isVM_CI() is not None
20
+
17
21
  # define the path where to find testing data
18
22
  # so tests could be ran from any location
19
23
  TESTS_PATH = abspath(dirname(__file__))
@@ -74,7 +74,7 @@ def _synonymiseExtensions(assets):
74
74
 
75
75
 
76
76
  # Names accepted by stimulus classes & the filename of the default stimulus to use
77
- defaultStimRoot = Path(__file__).parent.parent / "app" / "Resources"
77
+ defaultStimRoot = Path(__file__).parent.parent / "assets"
78
78
  defaultStim = {
79
79
  # Image stimuli
80
80
  "default.png": "default.png",
@@ -26,8 +26,7 @@ import subprocess as sp
26
26
  from psychopy.preferences import prefs
27
27
  from psychopy.localization import _translate
28
28
  import psychopy.logging as logging
29
- import importlib
30
- import pkg_resources
29
+ import importlib, importlib.metadata, importlib.resources
31
30
  import sys
32
31
  import os
33
32
  import os.path
@@ -37,23 +36,69 @@ import site
37
36
 
38
37
  # On import we want to configure the user site-packages dir and add it to the
39
38
  # import path.
40
-
41
39
  # set user site-packages dir
42
- site.USER_BASE = prefs.paths['packages']
43
- site.USER_SITE = None # clear, recompute this value
44
- logging.debug('User site-packages dir set to: %s' % site.getusersitepackages())
40
+ if os.environ.get('PSYCHOPYNOPACKAGES', '0') == '1':
41
+ site.ENABLE_USER_SITE = True
42
+ site.USER_SITE = str(prefs.paths['userPackages'])
43
+ site.USER_BASE = None
44
+ logging.debug(
45
+ 'User site-packages dir set to: %s' % site.getusersitepackages())
46
+
47
+ # add paths from main plugins/packages (installed by plugins manager)
48
+ site.addsitedir(prefs.paths['userPackages']) # user site-packages
49
+ site.addsitedir(prefs.paths['userInclude']) # user include
50
+ site.addsitedir(prefs.paths['packages']) # base package dir
45
51
 
46
52
  if not site.USER_SITE in sys.path:
47
53
  site.addsitedir(site.getusersitepackages())
48
54
 
49
- # add packages dir to import path
50
- if prefs.paths['packages'] not in pkg_resources.working_set.entries:
51
- pkg_resources.working_set.add_entry(prefs.paths['packages'])
52
-
53
55
  # cache list of packages to speed up checks
54
56
  _installedPackageCache = []
55
57
  _installedPackageNamesCache = []
56
58
 
59
+ # reference the user packages path
60
+ USER_PACKAGES_PATH = str(prefs.paths['userPackages'])
61
+
62
+
63
+ class PluginStub:
64
+ """
65
+ Class to handle classes which have moved out to plugins.
66
+
67
+ Example
68
+ -------
69
+ ```
70
+ class NoiseStim(PluginStub, plugin="psychopy-visionscience", doclink="https://psychopy.github.io/psychopy-visionscience/builder/components/NoiseStimComponent/):
71
+ ```
72
+ """
73
+
74
+ def __init_subclass__(cls, plugin, doclink="https://plugins.psychopy.org/directory.html"):
75
+ """
76
+ Subclassing PluginStub will create documentation pointing to the new documentation for the replacement class.
77
+ """
78
+ # store ref to plugin and docs link
79
+ cls.plugin = plugin
80
+ cls.doclink = doclink
81
+ # create doc string point to new location
82
+ cls.__doc__ = (
83
+ "`{mro}` is now located within the `{plugin}` plugin. You can find the documentation for it `here <{doclink}>`_."
84
+ ).format(
85
+ mro=cls.__mro__,
86
+ plugin=plugin,
87
+ doclink=doclink
88
+ )
89
+
90
+ def __call__(self, *args, **kwargs):
91
+ """
92
+ When initialised, rather than creating an object, will log an error.
93
+ """
94
+ raise NameError(
95
+ "Support for `{mro}` is not available this session. Please install "
96
+ "`{plugin}` and restart the session to enable support."
97
+ ).format(
98
+ mro=type(self).__mro__,
99
+ plugin=self.plugin,
100
+ )
101
+
57
102
 
58
103
  def refreshPackages():
59
104
  """Refresh the packaging system.
@@ -61,28 +106,27 @@ def refreshPackages():
61
106
  This needs to be called after adding and removing packages, or making any
62
107
  changes to `sys.path`. Functions `installPackages` and `uninstallPackages`
63
108
  calls this everytime.
64
-
65
- Warnings
66
- --------
67
- Calling this forces a reload of `pkg_resources`. This can cause side-effects
68
- for other modules using it!
69
-
70
109
  """
71
110
  global _installedPackageCache
72
111
  global _installedPackageNamesCache
73
112
 
74
113
  _installedPackageCache.clear()
75
114
  _installedPackageNamesCache.clear()
76
-
77
- importlib.reload(pkg_resources) # reload since package paths might be stale
78
-
79
- # this is like calling `pip freeze` and parsing the output, but faster!
80
- for pkg in pkg_resources.working_set:
81
- thisPkg = pkg_resources.get_distribution(pkg.key)
115
+
116
+ # iterate through installed packages in the user folder
117
+ for dist in importlib.metadata.distributions(path=sys.path + [USER_PACKAGES_PATH]):
118
+ # get name if in 3.8
119
+ if sys.version.startswith("3.8"):
120
+ distName = dist.metadata['name']
121
+ else:
122
+ distName = dist.name
123
+ # mark as installed
82
124
  _installedPackageCache.append(
83
- (thisPkg.project_name, thisPkg.version))
84
- _installedPackageNamesCache.append(pkg_resources.safe_name(
85
- thisPkg.project_name)) # names only
125
+ (distName, dist.version)
126
+ )
127
+ _installedPackageNamesCache.append(
128
+ distName
129
+ )
86
130
 
87
131
 
88
132
  def getUserPackagesPath():
@@ -111,10 +155,12 @@ def getDistributions():
111
155
  plugins can be found.
112
156
 
113
157
  """
114
- toReturn = list()
115
- toReturn.extend(pkg_resources.working_set.entries) # copy
116
-
117
- return toReturn
158
+ logging.error(
159
+ "`pkgtools.getDistributions` is now deprecated as packages are detected via "
160
+ "`importlib.metadata`, which doesn't need a separate working set from the system path. "
161
+ "Please use `sys.path` instead."
162
+ )
163
+ return sys.path
118
164
 
119
165
 
120
166
  def addDistribution(distPath):
@@ -130,8 +176,13 @@ def addDistribution(distPath):
130
176
  file (e.g. ZIP).
131
177
 
132
178
  """
133
- if distPath not in pkg_resources.working_set.entries:
134
- pkg_resources.working_set.add_entry(distPath)
179
+ logging.error(
180
+ "`pkgtools.addDistribution` is now deprecated as packages are detected via "
181
+ "`importlib.metadata`, which doesn't need a separate working set from the system path. "
182
+ "Please use `sys.path.append` instead."
183
+ )
184
+ if distPath not in sys.path:
185
+ sys.path.append(distPath)
135
186
 
136
187
 
137
188
  def installPackage(package, target=None, upgrade=False, forceReinstall=False,
@@ -169,7 +220,7 @@ def installPackage(package, target=None, upgrade=False, forceReinstall=False,
169
220
 
170
221
  """
171
222
  if target is None:
172
- target = prefs.paths['packages']
223
+ target = prefs.paths['userPackages']
173
224
 
174
225
  # check the directory exists before installing
175
226
  if not os.path.exists(target):
@@ -194,17 +245,33 @@ def installPackage(package, target=None, upgrade=False, forceReinstall=False,
194
245
  if noDeps:
195
246
  cmd.append('--no-deps')
196
247
 
248
+ # check if we are in a virtual environment, if so, dont use --user
249
+ if hasattr(sys, 'real_prefix') or (
250
+ hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix):
251
+ # we are in a venv
252
+ logging.warning(
253
+ "You are installing a package inside a virtual environment. "
254
+ "The package will be installed in the user site-packages directory."
255
+ )
256
+ else:
257
+ cmd.append('--user')
258
+
259
+ cmd.append('--prefer-binary') # use binary wheels if available
197
260
  cmd.append('--no-input') # do not prompt, we cannot accept input
198
261
  cmd.append('--no-color') # no color for console, not supported
199
262
  cmd.append('--no-warn-conflicts') # silence non-fatal errors
200
263
 
264
+ # get the environment for the subprocess
265
+ env = os.environ.copy()
266
+
201
267
  # run command in subprocess
202
268
  output = sp.Popen(
203
269
  cmd,
204
270
  stdout=sp.PIPE,
205
271
  stderr=sp.PIPE,
206
272
  shell=False,
207
- universal_newlines=True)
273
+ universal_newlines=True,
274
+ env=env)
208
275
  stdout, stderr = output.communicate() # blocks until process exits
209
276
 
210
277
  sys.stdout.write(stdout)
@@ -272,14 +339,18 @@ def _isUserPackage(package):
272
339
  `True` if the package is present in the user's PsychoPy directory.
273
340
 
274
341
  """
275
- userPackagePath = getUserPackagesPath()
276
- for pkg in pkg_resources.working_set:
277
- if pkg_resources.safe_name(package) == pkg.key:
278
- thisPkg = pkg_resources.get_distribution(pkg.key)
279
- if thisPkg.location == userPackagePath:
280
- return True
281
-
282
- return False
342
+ # get packages in the user path
343
+ userPackages = []
344
+ for dist in importlib.metadata.distributions(path=[USER_PACKAGES_PATH]):
345
+ # substitute name if using 3.8
346
+ if sys.version.startswith("3.8"):
347
+ distName = dist.metadata['name']
348
+ else:
349
+ distName = dist.name
350
+ # get name
351
+ userPackages.append(distName)
352
+
353
+ return package in userPackages
283
354
 
284
355
 
285
356
  def _uninstallUserPackage(package):
@@ -315,95 +386,47 @@ def _uninstallUserPackage(package):
315
386
  logging.info(msg)
316
387
  stdout += msg + "\n"
317
388
 
318
- # figure out he name of the metadata directory
319
- pkgName = pkg_resources.safe_name(package)
320
- thisPkg = pkg_resources.get_distribution(pkgName)
321
-
322
- # build path to metadata based on project name
323
- pathHead = pkg_resources.to_filename(thisPkg.project_name) + '-'
324
- metaDir = pathHead + thisPkg.version
325
- metaDir += '' if thisPkg.py_version is None else '.' + thisPkg.py_version
326
- metaDir += '.dist-info'
327
-
328
- # check if that directory exists
329
- metaPath = os.path.join(userPackagePath, metaDir)
330
- if not os.path.isdir(metaPath):
331
- return False, {
332
- "cmd": cmd,
333
- "stdout": stdout,
334
- "stderr": "No package metadata found at {metaPath}"}
335
-
336
- # Get the top-levels for all packages in the user's PsychoPy directory, this
337
- # is intended to safely remove packages without deleting common directories
338
- # like `bin` which some packages insist on putting in there.
339
- allTopLevelPackages = _getUserPackageTopLevels()
340
-
341
- # get the top-levels associated with the package we want to uninstall
342
- pkgTopLevelDirs = allTopLevelPackages[metaDir].copy()
343
- del allTopLevelPackages[metaDir] # remove from mapping
344
-
345
- # Check which top-level directories are safe to remove if they are not used
346
- # by other packages.
347
- toRemove = []
348
- for pkgTopLevel in pkgTopLevelDirs:
349
- safeToRemove = True
350
- for otherPkg, otherTopLevels in allTopLevelPackages.items():
351
- if pkgTopLevel in otherTopLevels:
352
- # check if another version of this package is sharing the dir
353
- if otherPkg.startswith(pathHead):
354
- msg = (
355
- 'Found metadata for an older version of package `{}` in '
356
- '`{}`. This will also be removed.'
357
- ).format(pkgName, otherPkg)
358
- logging.warning(msg)
359
- stdout += msg + "\n"
360
- toRemove.append(otherPkg)
361
- else:
362
- # unrelated package
363
- msg = (
364
- 'Found matching top-level directory `{}` in metadata '
365
- 'for `{}`. Can not safely remove this directory since '
366
- 'another package appears to use it.'
367
- ).format(pkgTopLevel, otherPkg)
368
- logging.warning(msg)
369
- stdout += msg + "\n"
370
- safeToRemove = False
371
- break
372
-
373
- if safeToRemove:
374
- toRemove.append(pkgTopLevel)
375
-
376
- # delete modules from the paths we found
377
- for rmDir in toRemove:
378
- if os.path.isfile(rmDir):
379
- msg = (
380
- 'Removing file `{}` from user package directory.'
381
- ).format(rmDir)
382
- logging.info(msg)
383
- stdout += msg + "\n"
384
- os.remove(rmDir)
385
- elif os.path.isdir(rmDir):
386
- msg = (
387
- 'Removing directory `{}` from user package '
388
- 'directory.'
389
- ).format(rmDir)
390
- logging.info(msg)
391
- stdout += msg + "\n"
392
- shutil.rmtree(rmDir)
393
-
394
- # cleanup by also deleting the metadata path
395
- shutil.rmtree(metaPath)
396
-
389
+ # get distribution object
390
+ thisPkg = importlib.metadata.distribution(package)
391
+ # iterate through its files
392
+ for file in thisPkg.files:
393
+ # get absolute path (not relative to package dir)
394
+ absPath = thisPkg.locate_file(file)
395
+ # skip pycache
396
+ if absPath.stem == "__pycache__":
397
+ continue
398
+ # delete file
399
+ if absPath.is_file():
400
+ try:
401
+ absPath.unlink()
402
+ except PermissionError as err:
403
+ stdout += _translate(
404
+ "Could not remove {absPath}, reason: {err}".format(absPath=absPath, err=err)
405
+ )
406
+ # skip pycache
407
+ if absPath.parent.stem == "__pycache__":
408
+ continue
409
+ # delete folder if empty
410
+ if absPath.parent.is_dir() and not [f for f in absPath.parent.glob("*")]:
411
+ # delete file
412
+ try:
413
+ absPath.parent.unlink()
414
+ except PermissionError as err:
415
+ stdout += _translate(
416
+ "Could not remove {absPath}, reason: {err}".format(absPath=absPath, err=err)
417
+ )
418
+
419
+ # log success
397
420
  msg = 'Uninstalled package `{}`.'.format(package)
398
421
  logging.info(msg)
399
422
  stdout += msg + "\n"
400
-
401
- # Return the return code and a dict of information from the console
423
+
424
+ # return the return code and a dict of information from the console
402
425
  return True, {
403
426
  "cmd": cmd,
404
427
  "stdout": stdout,
405
- "stderr": ""}
406
-
428
+ "stderr": ""
429
+ }
407
430
 
408
431
  def uninstallPackage(package):
409
432
  """Uninstall a package from the current distribution.
@@ -437,7 +460,6 @@ def uninstallPackage(package):
437
460
 
438
461
  # setup the environment to use the user's site-packages
439
462
  env = os.environ.copy()
440
- env["PYTHONUSERBASE"] = site.USER_BASE
441
463
 
442
464
  # run command in subprocess
443
465
  output = sp.Popen(
@@ -505,10 +527,16 @@ def getInstalledPackages():
505
527
  """
506
528
  # this is like calling `pip freeze` and parsing the output, but faster!
507
529
  installedPackages = []
508
- for pkg in pkg_resources.working_set:
509
- thisPkg = pkg_resources.get_distribution(pkg.key)
530
+ for dist in importlib.metadata.distributions(path=[USER_PACKAGES_PATH]):
531
+ # substitute name if using 3.8
532
+ if sys.version.startswith("3.8"):
533
+ distName = dist.metadata['name']
534
+ else:
535
+ distName = dist.name
536
+ # get name and version
510
537
  installedPackages.append(
511
- (thisPkg.project_name, thisPkg.version))
538
+ (distName, dist.version)
539
+ )
512
540
 
513
541
  return installedPackages
514
542
 
@@ -523,7 +551,7 @@ def isInstalled(packageName):
523
551
 
524
552
  """
525
553
  # installed packages are given as keys in the resulting dicts
526
- return pkg_resources.safe_name(packageName) in _installedPackageNamesCache
554
+ return packageName in _installedPackageNamesCache
527
555
 
528
556
 
529
557
  def getPackageMetadata(packageName):
@@ -544,16 +572,11 @@ def getPackageMetadata(packageName):
544
572
  import email.parser
545
573
 
546
574
  try:
547
- dist = pkg_resources.get_distribution(packageName)
548
- except pkg_resources.DistributionNotFound:
575
+ dist = importlib.metadata.distribution(packageName)
576
+ except importlib.metadata.PackageNotFoundError:
549
577
  return # do nothing
550
578
 
551
- metadata = dist.get_metadata(dist.PKG_INFO)
552
-
553
- # parse the metadata using
554
- metadict = dict()
555
- for key, val in email.message_from_string(metadata).raw_items():
556
- metadict[key] = val
579
+ metadict = dict(dist.metadata)
557
580
 
558
581
  return metadict
559
582
 
@@ -17,7 +17,7 @@ import psychopy # for currently loaded version
17
17
  from psychopy import prefs
18
18
  # the following will all have been imported so import here and reload later
19
19
  from psychopy import logging, tools, web, constants, preferences, __version__
20
- from pkg_resources import parse_version
20
+ from packaging.version import Version
21
21
  from importlib import reload
22
22
  from packaging.version import Version, InvalidVersion, VERSION_PATTERN
23
23
 
@@ -194,7 +194,7 @@ def getPsychoJSVersionStr(currentVersion, preferredVersion=''):
194
194
 
195
195
  # do we shorten minor versions ('3.4.2' to '3.4')?
196
196
  # only from 3.2 onwards
197
- if (parse_version('3.2')) <= parse_version(useVerStr) < parse_version('2021') \
197
+ if (Version('3.2')) <= Version(useVerStr) < Version('2021') \
198
198
  and len(useVerStr.split('.')) > 2:
199
199
  # e.g. 2020.2 not 2021.2.5
200
200
  useVerStr = '.'.join(useVerStr.split('.')[:2])
@@ -385,9 +385,9 @@ def versionOptions(local=True):
385
385
  majorMinor = sorted(
386
386
  list({'.'.join(v.split('.')[:2])
387
387
  for v in availableVersions(local=local)}),
388
- key=parse_version,
388
+ key=Version,
389
389
  reverse=True)
390
- major = sorted(list({v.split('.')[0] for v in majorMinor}), key=parse_version, reverse=True)
390
+ major = sorted(list({v.split('.')[0] for v in majorMinor}), key=Version, reverse=True)
391
391
  special = ['latest']
392
392
  return special + major + majorMinor
393
393
 
@@ -402,7 +402,7 @@ def _localVersions(forceCheck=False):
402
402
  tagInfo = subprocess.check_output(cmd.split(), cwd=VERSIONSDIR,
403
403
  env=constants.ENVIRON).decode('UTF-8')
404
404
  allTags = tagInfo.splitlines()
405
- _localVersionsCache = sorted(allTags, key=parse_version, reverse=True)
405
+ _localVersionsCache = sorted(allTags, key=Version, reverse=True)
406
406
  return _localVersionsCache
407
407
 
408
408
 
@@ -421,7 +421,7 @@ def _remoteVersions(forceCheck=False):
421
421
  for line in tagInfo.decode().splitlines()
422
422
  if '^{}' not in line]
423
423
  # ensure most recent (i.e., highest) first
424
- _remoteVersionsCache = sorted(allTags, key=parse_version, reverse=True)
424
+ _remoteVersionsCache = sorted(allTags, key=Version, reverse=True)
425
425
  return _remoteVersionsCache
426
426
 
427
427
 
@@ -443,19 +443,19 @@ def _versionFilter(versions, wxVersion):
443
443
  # logging.info(msg)
444
444
  versions = [ver for ver in versions
445
445
  if ver == 'latest'
446
- or parse_version(ver) >= parse_version('1.90')
446
+ or Version(ver) >= Version('1.90')
447
447
  and len(ver) > 1]
448
448
 
449
449
  # Get WX Compatibility
450
450
  compatibleWX = '4.0'
451
- if wxVersion is not None and parse_version(wxVersion) >= parse_version(compatibleWX):
451
+ if wxVersion is not None and Version(wxVersion) >= Version(compatibleWX):
452
452
  # msg = _translate("wx version: {}. Filtering versions of "
453
453
  # "PsychoPy only compatible with wx >= version {}".format(wxVersion,
454
454
  # compatibleWX))
455
455
  # logging.info(msg)
456
456
  return [ver for ver in versions
457
457
  if ver == 'latest'
458
- or parse_version(ver) > parse_version('1.85.04')
458
+ or Version(ver) > Version('1.85.04')
459
459
  and len(ver) > 1]
460
460
  return versions
461
461
 
@@ -474,7 +474,7 @@ def availableVersions(local=True, forceCheck=False):
474
474
  return sorted(
475
475
  list(set([psychopy.__version__] + _localVersions(forceCheck) + _remoteVersions(
476
476
  forceCheck))),
477
- key=parse_version,
477
+ key=Version,
478
478
  reverse=True)
479
479
  except subprocess.CalledProcessError:
480
480
  return []
psychopy/tools/wizard.py CHANGED
@@ -17,9 +17,9 @@ import wx
17
17
  import numpy as np
18
18
  import platform
19
19
  import codecs
20
- from pkg_resources import parse_version
20
+ from packaging.version import Version
21
21
 
22
- if parse_version(wx.__version__) < parse_version('2.9'):
22
+ if Version(wx.__version__) < Version('2.9'):
23
23
  tmpApp = wx.PySimpleApp()
24
24
  else:
25
25
  tmpApp = wx.App(False)
@@ -88,7 +88,7 @@ class BaseWizard():
88
88
  'prefs.html#application-settings-app">Preferences -> App</a>')
89
89
  report.append(('locale', items['systemLocale'], msg, False))
90
90
  msg = ''
91
- v = parse_version
91
+ v = Version
92
92
  thisV = v(items['pythonVersion'])
93
93
  if (thisV < v('2.7') or (v('3.0') <= thisV < v('3.6'))
94
94
  ):
Binary file
@@ -179,20 +179,27 @@ class PygletBackend(BaseBackend):
179
179
  'integer greater than two. Disabling.')
180
180
  win.multiSample = False
181
181
 
182
+ skip_screen_warn = False
182
183
  if platform.system() == 'Linux':
183
- display = pyglet.canvas.Display()
184
+ from pyglet.canvas.xlib import NoSuchDisplayException
185
+ try:
186
+ display = pyglet.canvas.Display(x_screen=win.screen)
187
+ # in this case, we'll only get a single x-screen back
188
+ skip_screen_warn = True
189
+ except NoSuchDisplayException:
190
+ # Maybe xinerama? Try again and get the specified screen later
191
+ display = pyglet.canvas.Display(x_screen=0)
192
+
184
193
  allScrs = display.get_screens()
185
194
  else:
186
- if pyglet.version < '1.4':
187
- allScrs = _default_display_.get_screens()
188
- else:
189
- allScrs = _default_display_.get_screens()
195
+ allScrs = _default_display_.get_screens()
190
196
 
191
- # Screen (from Exp Settings) is 1-indexed,
197
+ # Screen (from Exp Settings) is 0-indexed,
192
198
  # so the second screen is Screen 1
193
199
  if len(allScrs) < int(win.screen) + 1:
194
- logging.warn("Requested an unavailable screen number - "
195
- "using first available.")
200
+ if not skip_screen_warn:
201
+ logging.warn("Requested an unavailable screen number - "
202
+ "using first available.")
196
203
  thisScreen = allScrs[0]
197
204
  else:
198
205
  thisScreen = allScrs[win.screen]
@@ -247,7 +254,7 @@ class PygletBackend(BaseBackend):
247
254
  self.winHandle = pyglet.window.Window(
248
255
  width=w, height=h,
249
256
  caption="PsychoPy",
250
- fullscreen=self._isFullScr,
257
+ fullscreen=win._isFullScr,
251
258
  config=config,
252
259
  screen=thisScreen,
253
260
  style=style)
@@ -258,8 +265,12 @@ class PygletBackend(BaseBackend):
258
265
  "graphics card and/or graphics drivers.")
259
266
  try:
260
267
  icns = [
261
- pyglet.image.load(prefs.paths['resources'] + os.sep + "Psychopy Window Favicon@16w.png"),
262
- pyglet.image.load(prefs.paths['resources'] + os.sep + "Psychopy Window Favicon@32w.png"),
268
+ pyglet.image.load(
269
+ prefs.paths['assets'] + os.sep + "Psychopy Window Favicon@16w.png"
270
+ ),
271
+ pyglet.image.load(
272
+ prefs.paths['assets'] + os.sep + "Psychopy Window Favicon@32w.png"
273
+ ),
263
274
  ]
264
275
  self.winHandle.set_icon(*icns)
265
276
  except BaseException:
@@ -347,8 +358,8 @@ class PygletBackend(BaseBackend):
347
358
  int(win.pos[1] + thisScreen.y))
348
359
 
349
360
  try: # to load an icon for the window
350
- iconFile = os.path.join(psychopy.prefs.paths['resources'],
351
- 'psychopy.ico')
361
+ iconFile = os.path.join(psychopy.prefs.paths['assets'],
362
+ 'window.ico')
352
363
  icon = pyglet.image.load(filename=iconFile)
353
364
  self.winHandle.set_icon(icon)
354
365
  except Exception: