gwpy 3.0.12__tar.gz → 3.0.13__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (377) hide show
  1. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/compatibility.yml +2 -2
  2. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/coverage.yml +1 -1
  3. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/platforms.yml +2 -0
  4. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/python-base.yml +1 -1
  5. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/python-dist.yml +10 -8
  6. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/qa.yml +16 -2
  7. gwpy-3.0.13/.gitlab/ci/rstcheck.py +108 -0
  8. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/rules.yml +15 -11
  9. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/sphinx.yml +1 -1
  10. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/test-job.yml +8 -4
  11. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/test.yml +80 -37
  12. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/twine.yml +2 -2
  13. gwpy-3.0.13/.readthedocs.yaml +28 -0
  14. {gwpy-3.0.12 → gwpy-3.0.13}/PKG-INFO +26 -25
  15. {gwpy-3.0.12 → gwpy-3.0.13}/docs/cli/examples.ini +1 -1
  16. {gwpy-3.0.12 → gwpy-3.0.13}/docs/conf.py +6 -6
  17. gwpy-3.0.13/docs/environment.yaml +10 -0
  18. {gwpy-3.0.12 → gwpy-3.0.13}/docs/overview.rst +2 -2
  19. {gwpy-3.0.12 → gwpy-3.0.13}/docs/segments/index.rst +1 -1
  20. {gwpy-3.0.12 → gwpy-3.0.13}/docs/spectrum/index.rst +1 -1
  21. {gwpy-3.0.12 → gwpy-3.0.13}/docs/timeseries/statevector.rst +2 -2
  22. {gwpy-3.0.12 → gwpy-3.0.13}/examples/frequencyseries/inject.py +1 -1
  23. {gwpy-3.0.12 → gwpy-3.0.13}/examples/frequencyseries/rayleigh.py +1 -1
  24. {gwpy-3.0.12 → gwpy-3.0.13}/examples/frequencyseries/variance.py +2 -2
  25. {gwpy-3.0.12 → gwpy-3.0.13}/examples/spectrogram/rayleigh.py +1 -1
  26. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/blrms.py +1 -1
  27. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/correlate.py +1 -1
  28. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/inject.py +1 -1
  29. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/pycbc-snr.py +1 -2
  30. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/statevector.py +1 -1
  31. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/_version.py +9 -4
  32. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/astro/range.py +22 -9
  33. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/astro/tests/test_range.py +8 -3
  34. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/tests/test_units.py +4 -5
  35. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/units.py +101 -67
  36. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/plot.py +0 -1
  37. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/tests/test_flag.py +36 -6
  38. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/spectral/_scipy.py +14 -0
  39. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/core.py +1 -1
  40. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/losc.py +1 -1
  41. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/statevector.py +2 -2
  42. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/tests/test_timeseries.py +1 -0
  43. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy.egg-info/PKG-INFO +26 -25
  44. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy.egg-info/SOURCES.txt +3 -0
  45. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy.egg-info/requires.txt +5 -5
  46. {gwpy-3.0.12 → gwpy-3.0.13}/pyproject.toml +51 -29
  47. {gwpy-3.0.12 → gwpy-3.0.13}/.gitattributes +0 -0
  48. {gwpy-3.0.12 → gwpy-3.0.13}/.gitignore +0 -0
  49. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab/ci/init-creds.sh +0 -0
  50. {gwpy-3.0.12 → gwpy-3.0.13}/.gitlab-ci.yml +0 -0
  51. {gwpy-3.0.12 → gwpy-3.0.13}/CODE_OF_CONDUCT.rst +0 -0
  52. {gwpy-3.0.12 → gwpy-3.0.13}/CONTRIBUTING.md +0 -0
  53. {gwpy-3.0.12 → gwpy-3.0.13}/LICENSE +0 -0
  54. {gwpy-3.0.12 → gwpy-3.0.13}/MANIFEST.in +0 -0
  55. {gwpy-3.0.12 → gwpy-3.0.13}/README.md +0 -0
  56. {gwpy-3.0.12 → gwpy-3.0.13}/docs/Makefile +0 -0
  57. {gwpy-3.0.12 → gwpy-3.0.13}/docs/_static/css/gwpy-sphinx.css +0 -0
  58. {gwpy-3.0.12 → gwpy-3.0.13}/docs/_static/favicon.png +0 -0
  59. {gwpy-3.0.12 → gwpy-3.0.13}/docs/_static/gwpy_white_24.png +0 -0
  60. {gwpy-3.0.12 → gwpy-3.0.13}/docs/_templates/autoclass/class.rst +0 -0
  61. {gwpy-3.0.12 → gwpy-3.0.13}/docs/_templates/autosummary/base.rst +0 -0
  62. {gwpy-3.0.12 → gwpy-3.0.13}/docs/_templates/autosummary/class.rst +0 -0
  63. {gwpy-3.0.12 → gwpy-3.0.13}/docs/_templates/autosummary/module.rst +0 -0
  64. {gwpy-3.0.12 → gwpy-3.0.13}/docs/astro/index.rst +0 -0
  65. {gwpy-3.0.12 → gwpy-3.0.13}/docs/citing.rst.in +0 -0
  66. {gwpy-3.0.12 → gwpy-3.0.13}/docs/cli/index.rst +0 -0
  67. {gwpy-3.0.12 → gwpy-3.0.13}/docs/detector/channel.rst +0 -0
  68. {gwpy-3.0.12 → gwpy-3.0.13}/docs/dev/release.rst +0 -0
  69. {gwpy-3.0.12 → gwpy-3.0.13}/docs/env.rst +0 -0
  70. {gwpy-3.0.12 → gwpy-3.0.13}/docs/examples/table/H1-LDAS_STRAIN-968654552-10.xml.gz +0 -0
  71. {gwpy-3.0.12 → gwpy-3.0.13}/docs/external/framecpp.rst +0 -0
  72. {gwpy-3.0.12 → gwpy-3.0.13}/docs/external/framel.rst +0 -0
  73. {gwpy-3.0.12 → gwpy-3.0.13}/docs/external/lalsuite.rst +0 -0
  74. {gwpy-3.0.12 → gwpy-3.0.13}/docs/external/nds2.rst +0 -0
  75. {gwpy-3.0.12 → gwpy-3.0.13}/docs/gwpy-docs-logo.png +0 -0
  76. {gwpy-3.0.12 → gwpy-3.0.13}/docs/index.rst +0 -0
  77. {gwpy-3.0.12 → gwpy-3.0.13}/docs/install.rst +0 -0
  78. {gwpy-3.0.12 → gwpy-3.0.13}/docs/plot/colorbars.rst +0 -0
  79. {gwpy-3.0.12 → gwpy-3.0.13}/docs/plot/colors.rst +0 -0
  80. {gwpy-3.0.12 → gwpy-3.0.13}/docs/plot/filter.rst +0 -0
  81. {gwpy-3.0.12 → gwpy-3.0.13}/docs/plot/gps.rst +0 -0
  82. {gwpy-3.0.12 → gwpy-3.0.13}/docs/plot/index.rst +0 -0
  83. {gwpy-3.0.12 → gwpy-3.0.13}/docs/plot/legend.rst +0 -0
  84. {gwpy-3.0.12 → gwpy-3.0.13}/docs/plot/log.rst +0 -0
  85. {gwpy-3.0.12 → gwpy-3.0.13}/docs/references.rst +0 -0
  86. {gwpy-3.0.12 → gwpy-3.0.13}/docs/segments/dqsegdb.rst +0 -0
  87. {gwpy-3.0.12 → gwpy-3.0.13}/docs/segments/io.rst +0 -0
  88. {gwpy-3.0.12 → gwpy-3.0.13}/docs/segments/thresholding.rst +0 -0
  89. {gwpy-3.0.12 → gwpy-3.0.13}/docs/signal/index.rst +0 -0
  90. {gwpy-3.0.12 → gwpy-3.0.13}/docs/spectrogram/index.rst +0 -0
  91. {gwpy-3.0.12 → gwpy-3.0.13}/docs/spectrum/filtering.rst +0 -0
  92. {gwpy-3.0.12 → gwpy-3.0.13}/docs/spectrum/io.rst +0 -0
  93. {gwpy-3.0.12 → gwpy-3.0.13}/docs/table/H1-LDAS_STRAIN-968654552-10.xml.gz +0 -0
  94. {gwpy-3.0.12 → gwpy-3.0.13}/docs/table/filter.rst +0 -0
  95. {gwpy-3.0.12 → gwpy-3.0.13}/docs/table/histogram.rst +0 -0
  96. {gwpy-3.0.12 → gwpy-3.0.13}/docs/table/index.rst +0 -0
  97. {gwpy-3.0.12 → gwpy-3.0.13}/docs/table/io.rst +0 -0
  98. {gwpy-3.0.12 → gwpy-3.0.13}/docs/table/plot.rst +0 -0
  99. {gwpy-3.0.12 → gwpy-3.0.13}/docs/table/rate.rst +0 -0
  100. {gwpy-3.0.12 → gwpy-3.0.13}/docs/time/index.rst +0 -0
  101. {gwpy-3.0.12 → gwpy-3.0.13}/docs/timeseries/datafind.rst +0 -0
  102. {gwpy-3.0.12 → gwpy-3.0.13}/docs/timeseries/index.rst +0 -0
  103. {gwpy-3.0.12 → gwpy-3.0.13}/docs/timeseries/io.rst +0 -0
  104. {gwpy-3.0.12 → gwpy-3.0.13}/docs/timeseries/opendata.rst +0 -0
  105. {gwpy-3.0.12 → gwpy-3.0.13}/docs/timeseries/plot.rst +0 -0
  106. {gwpy-3.0.12 → gwpy-3.0.13}/examples/frequencyseries/coherence.py +0 -0
  107. {gwpy-3.0.12 → gwpy-3.0.13}/examples/frequencyseries/hoff.py +0 -0
  108. {gwpy-3.0.12 → gwpy-3.0.13}/examples/frequencyseries/index.rst +0 -0
  109. {gwpy-3.0.12 → gwpy-3.0.13}/examples/frequencyseries/percentiles.py +0 -0
  110. {gwpy-3.0.12 → gwpy-3.0.13}/examples/frequencyseries/transfer_function.py +0 -0
  111. {gwpy-3.0.12 → gwpy-3.0.13}/examples/miscellaneous/index.rst +0 -0
  112. {gwpy-3.0.12 → gwpy-3.0.13}/examples/miscellaneous/open-data-spectrogram.py +0 -0
  113. {gwpy-3.0.12 → gwpy-3.0.13}/examples/miscellaneous/range-spectrogram.py +0 -0
  114. {gwpy-3.0.12 → gwpy-3.0.13}/examples/miscellaneous/range-timeseries.py +0 -0
  115. {gwpy-3.0.12 → gwpy-3.0.13}/examples/segments/index.rst +0 -0
  116. {gwpy-3.0.12 → gwpy-3.0.13}/examples/segments/open-data.py +0 -0
  117. {gwpy-3.0.12 → gwpy-3.0.13}/examples/signal/gw150914.py +0 -0
  118. {gwpy-3.0.12 → gwpy-3.0.13}/examples/signal/index.rst +0 -0
  119. {gwpy-3.0.12 → gwpy-3.0.13}/examples/signal/qscan.py +0 -0
  120. {gwpy-3.0.12 → gwpy-3.0.13}/examples/spectrogram/coherence.py +0 -0
  121. {gwpy-3.0.12 → gwpy-3.0.13}/examples/spectrogram/index.rst +0 -0
  122. {gwpy-3.0.12 → gwpy-3.0.13}/examples/spectrogram/plot.py +0 -0
  123. {gwpy-3.0.12 → gwpy-3.0.13}/examples/spectrogram/ratio.py +0 -0
  124. {gwpy-3.0.12 → gwpy-3.0.13}/examples/spectrogram/spectrogram2.py +0 -0
  125. {gwpy-3.0.12 → gwpy-3.0.13}/examples/table/H1-LDAS_STRAIN-968654552-10.xml.gz +0 -0
  126. {gwpy-3.0.12 → gwpy-3.0.13}/examples/table/histogram.py +0 -0
  127. {gwpy-3.0.12 → gwpy-3.0.13}/examples/table/index.rst +0 -0
  128. {gwpy-3.0.12 → gwpy-3.0.13}/examples/table/rate.py +0 -0
  129. {gwpy-3.0.12 → gwpy-3.0.13}/examples/table/rate_binned.py +0 -0
  130. {gwpy-3.0.12 → gwpy-3.0.13}/examples/table/scatter.py +0 -0
  131. {gwpy-3.0.12 → gwpy-3.0.13}/examples/table/tiles.py +0 -0
  132. {gwpy-3.0.12 → gwpy-3.0.13}/examples/test_examples.py +0 -0
  133. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/filter.py +0 -0
  134. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/index.rst +0 -0
  135. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/public.py +0 -0
  136. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/qscan.py +0 -0
  137. {gwpy-3.0.12 → gwpy-3.0.13}/examples/timeseries/whiten.py +0 -0
  138. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/__init__.py +0 -0
  139. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/astro/__init__.py +0 -0
  140. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/astro/tests/__init__.py +0 -0
  141. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/__init__.py +0 -0
  142. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/cliproduct.py +0 -0
  143. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/coherence.py +0 -0
  144. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/coherencegram.py +0 -0
  145. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/gwpy_plot.py +0 -0
  146. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/qtransform.py +0 -0
  147. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/spectrogram.py +0 -0
  148. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/spectrum.py +0 -0
  149. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/__init__.py +0 -0
  150. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/base.py +0 -0
  151. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/test_coherence.py +0 -0
  152. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/test_coherencegram.py +0 -0
  153. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/test_gwpy_plot.py +0 -0
  154. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/test_qtransform.py +0 -0
  155. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/test_spectrogram.py +0 -0
  156. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/test_spectrum.py +0 -0
  157. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/test_timeseries.py +0 -0
  158. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/tests/test_transferfunction.py +0 -0
  159. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/timeseries.py +0 -0
  160. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/cli/transferfunction.py +0 -0
  161. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/conftest.py +0 -0
  162. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/__init__.py +0 -0
  163. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/channel.py +0 -0
  164. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/io/__init__.py +0 -0
  165. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/io/cis.py +0 -0
  166. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/io/clf.py +0 -0
  167. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/io/omega.py +0 -0
  168. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/tests/__init__.py +0 -0
  169. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/detector/tests/test_channel.py +0 -0
  170. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/__init__.py +0 -0
  171. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/_fdcommon.py +0 -0
  172. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/frequencyseries.py +0 -0
  173. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/hist.py +0 -0
  174. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/io/__init__.py +0 -0
  175. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/io/ascii.py +0 -0
  176. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/io/hdf5.py +0 -0
  177. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/io/ligolw.py +0 -0
  178. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/tests/__init__.py +0 -0
  179. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/tests/test_frequencyseries.py +0 -0
  180. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/frequencyseries/tests/test_hist.py +0 -0
  181. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/__init__.py +0 -0
  182. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/_framecpp.py +0 -0
  183. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/cache.py +0 -0
  184. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/datafind.py +0 -0
  185. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/ffldatafind.py +0 -0
  186. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/gwf.py +0 -0
  187. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/hdf5.py +0 -0
  188. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/kerberos.py +0 -0
  189. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/ligolw.py +0 -0
  190. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/mp.py +0 -0
  191. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/nds2.py +0 -0
  192. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/registry.py +0 -0
  193. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/__init__.py +0 -0
  194. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_cache.py +0 -0
  195. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_datafind.py +0 -0
  196. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_ffldatafind.py +0 -0
  197. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_gwf.py +0 -0
  198. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_kerberos.py +0 -0
  199. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_ligolw.py +0 -0
  200. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_mp.py +0 -0
  201. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_nds2.py +0 -0
  202. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/tests/test_utils.py +0 -0
  203. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/io/utils.py +0 -0
  204. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/__init__.py +0 -0
  205. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/axes.py +0 -0
  206. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/bode.py +0 -0
  207. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/colorbar.py +0 -0
  208. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/colors.py +0 -0
  209. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/gps.py +0 -0
  210. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/legend.py +0 -0
  211. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/log.py +0 -0
  212. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/rc.py +0 -0
  213. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/segments.py +0 -0
  214. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/__init__.py +0 -0
  215. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_axes.py +0 -0
  216. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_bode.py +0 -0
  217. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_colors.py +0 -0
  218. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_gps.py +0 -0
  219. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_log.py +0 -0
  220. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_plot.py +0 -0
  221. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_rc.py +0 -0
  222. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_segments.py +0 -0
  223. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_tex.py +0 -0
  224. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_text.py +0 -0
  225. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/test_utils.py +0 -0
  226. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tests/utils.py +0 -0
  227. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/tex.py +0 -0
  228. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/text.py +0 -0
  229. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/units.py +0 -0
  230. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/plot/utils.py +0 -0
  231. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/__init__.py +0 -0
  232. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/flag.py +0 -0
  233. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/io/__init__.py +0 -0
  234. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/io/hdf5.py +0 -0
  235. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/io/json.py +0 -0
  236. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/io/ligolw.py +0 -0
  237. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/io/segwizard.py +0 -0
  238. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/segments.py +0 -0
  239. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/tests/__init__.py +0 -0
  240. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/segments/tests/test_segments.py +0 -0
  241. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/__init__.py +0 -0
  242. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/fft.py +0 -0
  243. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/filter_design.py +0 -0
  244. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/qtransform.py +0 -0
  245. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/spectral/__init__.py +0 -0
  246. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/spectral/_lal.py +0 -0
  247. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/spectral/_median_mean.py +0 -0
  248. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/spectral/_pycbc.py +0 -0
  249. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/spectral/_registry.py +0 -0
  250. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/spectral/_ui.py +0 -0
  251. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/spectral/_utils.py +0 -0
  252. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/__init__.py +0 -0
  253. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_coherence.py +0 -0
  254. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_filter_design.py +0 -0
  255. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_qtransform.py +0 -0
  256. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_spectral_lal.py +0 -0
  257. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_spectral_median_mean.py +0 -0
  258. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_spectral_pycbc.py +0 -0
  259. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_spectral_registry.py +0 -0
  260. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_spectral_scipy.py +0 -0
  261. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_spectral_ui.py +0 -0
  262. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_spectral_utils.py +0 -0
  263. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/tests/test_window.py +0 -0
  264. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/signal/window.py +0 -0
  265. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/spectrogram/__init__.py +0 -0
  266. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/spectrogram/coherence.py +0 -0
  267. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/spectrogram/io/__init__.py +0 -0
  268. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/spectrogram/io/hdf5.py +0 -0
  269. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/spectrogram/spectrogram.py +0 -0
  270. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/spectrogram/tests/__init__.py +0 -0
  271. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/spectrogram/tests/test_spectrogram.py +0 -0
  272. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/__init__.py +0 -0
  273. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/filter.py +0 -0
  274. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/filters.py +0 -0
  275. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/gravityspy.py +0 -0
  276. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/__init__.py +0 -0
  277. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/cwb.py +0 -0
  278. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/fetch.py +0 -0
  279. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/gravityspy.py +0 -0
  280. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/gstlal.py +0 -0
  281. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/gwf.py +0 -0
  282. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/hacr.py +0 -0
  283. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/ligolw.py +0 -0
  284. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/losc.py +0 -0
  285. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/omega.py +0 -0
  286. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/omicron.py +0 -0
  287. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/pycbc.py +0 -0
  288. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/root.py +0 -0
  289. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/snax.py +0 -0
  290. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/sql.py +0 -0
  291. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/io/utils.py +0 -0
  292. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/table.py +0 -0
  293. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/tests/__init__.py +0 -0
  294. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/tests/test_gravityspy.py +0 -0
  295. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/tests/test_io_gstlal.py +0 -0
  296. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/tests/test_io_ligolw.py +0 -0
  297. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/tests/test_io_pycbc.py +0 -0
  298. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/table/tests/test_table.py +0 -0
  299. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/__init__.py +0 -0
  300. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/data/H1-LDAS_STRAIN-968654552-10.xml.gz +0 -0
  301. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/data/HLV-HW100916-968654552-1.gwf +0 -0
  302. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/data/HLV-HW100916-968654552-1.hdf +0 -0
  303. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/data/X1-GWPY_TEST_SEGMENTS-0-10.txt +0 -0
  304. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/data/X1-GWPY_TEST_SEGMENTS-0-10.xml.gz +0 -0
  305. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/errors.py +0 -0
  306. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/fixtures.py +0 -0
  307. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/marks.py +0 -0
  308. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/mocks.py +0 -0
  309. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/testing/utils.py +0 -0
  310. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/time/__init__.py +0 -0
  311. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/time/__main__.py +0 -0
  312. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/time/_tconvert.py +0 -0
  313. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/time/tests/__init__.py +0 -0
  314. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/time/tests/test_main.py +0 -0
  315. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/time/tests/test_time.py +0 -0
  316. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/__init__.py +0 -0
  317. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/__init__.py +0 -0
  318. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/ascii.py +0 -0
  319. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/cache.py +0 -0
  320. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/core.py +0 -0
  321. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/gwf/__init__.py +0 -0
  322. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/gwf/framecpp.py +0 -0
  323. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/gwf/framel.py +0 -0
  324. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/gwf/lalframe.py +0 -0
  325. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/hdf5.py +0 -0
  326. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/nds2.py +0 -0
  327. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/io/wav.py +0 -0
  328. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/tests/__init__.py +0 -0
  329. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/tests/test_core.py +0 -0
  330. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/tests/test_io_cache.py +0 -0
  331. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/tests/test_io_gwf_framecpp.py +0 -0
  332. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/tests/test_io_gwf_lalframe.py +0 -0
  333. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/tests/test_io_losc.py +0 -0
  334. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/tests/test_statevector.py +0 -0
  335. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/timeseries/timeseries.py +0 -0
  336. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/__init__.py +0 -0
  337. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/array.py +0 -0
  338. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/array2d.py +0 -0
  339. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/index.py +0 -0
  340. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/io/__init__.py +0 -0
  341. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/io/ascii.py +0 -0
  342. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/io/hdf5.py +0 -0
  343. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/io/ligolw.py +0 -0
  344. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/series.py +0 -0
  345. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/sliceutils.py +0 -0
  346. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/tests/__init__.py +0 -0
  347. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/tests/test_array.py +0 -0
  348. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/tests/test_array2d.py +0 -0
  349. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/tests/test_index.py +0 -0
  350. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/types/tests/test_series.py +0 -0
  351. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/__init__.py +0 -0
  352. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/decorators.py +0 -0
  353. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/enum.py +0 -0
  354. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/env.py +0 -0
  355. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/lal.py +0 -0
  356. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/misc.py +0 -0
  357. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/mp.py +0 -0
  358. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/progress.py +0 -0
  359. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/shell.py +0 -0
  360. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/sphinx/__init__.py +0 -0
  361. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/sphinx/ex2rst.py +0 -0
  362. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/sphinx/zenodo.py +0 -0
  363. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/__init__.py +0 -0
  364. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_decorators.py +0 -0
  365. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_enum.py +0 -0
  366. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_env.py +0 -0
  367. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_lal.py +0 -0
  368. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_misc.py +0 -0
  369. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_mp.py +0 -0
  370. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_shell.py +0 -0
  371. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_sphinx_ex2rst.py +0 -0
  372. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy/utils/tests/test_sphinx_zenodo.py +0 -0
  373. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy.egg-info/dependency_links.txt +0 -0
  374. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy.egg-info/entry_points.txt +0 -0
  375. {gwpy-3.0.12 → gwpy-3.0.13}/gwpy.egg-info/top_level.txt +0 -0
  376. {gwpy-3.0.12 → gwpy-3.0.13}/setup.cfg +0 -0
  377. {gwpy-3.0.12 → gwpy-3.0.13}/setup_utils.py +0 -0
@@ -65,7 +65,7 @@ compat_minimum:
65
65
  extends:
66
66
  - .compat_minimum
67
67
  - .compat_rules
68
- image: python:$[[ inputs.minimum_python_version ]]
68
+ image: "ghcr.io/astral-sh/uv:python$[[ inputs.minimum_python_version ]]-bookworm"
69
69
  before_script:
70
70
  # replace the requirements as follows:
71
71
  # >=X.Y.Z ---> X.Y.Z (exact pin to minimum)
@@ -96,7 +96,7 @@ compat_experimental:
96
96
  extends:
97
97
  - .compat_experimental
98
98
  - .compat_rules
99
- image: python:3.12
99
+ image: "ghcr.io/astral-sh/uv:python3.12-bookworm"
100
100
 
101
101
  # run dependency scanning against minimum specified requirements
102
102
  # (most likely to highlight issues)
@@ -10,7 +10,7 @@ include:
10
10
 
11
11
  coverage:
12
12
  stage: .post
13
- image: python
13
+ image: quay.io/lib/python
14
14
  rules: !reference [.rules_full_test, rules]
15
15
  script:
16
16
  # install coverage (with toml parsing extra)
@@ -26,5 +26,7 @@ spec:
26
26
  # windows gitlab runners don't support symbolic links, so we can't
27
27
  # run the tests that rely upon them
28
28
  PYTEST_ADDOPTS: "-k 'not table\\\\rate and not table\\\\tiles'"
29
+ # pytest-xdist doesn't auto-detect the number of CPUs sometimes
30
+ PYTEST_XDIST_AUTO_NUM_WORKERS: "2"
29
31
  tags:
30
32
  - saas-windows-medium-amd64
@@ -6,7 +6,7 @@ spec:
6
6
  default: ".cache/pip"
7
7
  description: "The path to cache to (relative to CI_PROJECT_DIR)"
8
8
  image:
9
- default: "python"
9
+ default: "quay.io/lib/python"
10
10
  description: "The default image to use for jobs"
11
11
  job_prefix:
12
12
  default: ".python"
@@ -16,22 +16,24 @@ build:
16
16
  rules: !reference [.rules_build, rules]
17
17
  needs: []
18
18
  stage: $[[ inputs.stage ]]
19
- image: python
19
+ image: ghcr.io/astral-sh/uv:alpine
20
20
  variables:
21
21
  # get the full history for setuptools-scm
22
22
  GIT_DEPTH: 0
23
+ # debug setuptools-scm
24
+ SETUPTOOLS_SCM_DEBUG: 1
23
25
  before_script:
24
- - python -m pip install
25
- build
26
+ # need git for setuptools-scm
27
+ - apk add --no-cache git
26
28
  script:
29
+ - uv venv
30
+ - uv pip install build
31
+ - source .venv/bin/activate
27
32
  # if running a default branch push pipeline, strip the +g<HASH> suffix
28
33
  # from the version to give something that test.pypi.org will accept
29
34
  - |
30
- if [ "${CI_COMMIT_TAG}" = "" ] && [ "${CI_PIPELINE_SOURCE}" = "push" ] && [ "${CI_COMMIT_BRANCH}" = "${CI_DEFAULT_BRANCH}" ]; then
31
- python -m pip install -q setuptools setuptools-scm
32
- echo "Real version is '$(python -m setuptools_scm)'";
33
- export SETUPTOOLS_SCM_PRETEND_VERSION=$(python3 -c "from setuptools import setup; setup(use_scm_version={'local_scheme': 'no-local-version'})" --version);
34
- echo "Pretending version is '${SETUPTOOLS_SCM_PRETEND_VERSION}'";
35
+ if [ "${CI_COMMIT_TAG}" = "" ] && [ "${CI_PIPELINE_SOURCE}" = "push" ] && [ "${CI_COMMIT_REF_PROTECTED}" = "true" ]; then
36
+ export SETUPTOOLS_SCM_OVERRIDES_FOR_GWPY="{local_scheme='no-local-version'}";
35
37
  fi
36
38
  # generate the distributions
37
39
  - python -m build . -o .
@@ -39,6 +39,7 @@ include:
39
39
  rules:
40
40
  - if: '$GITLAB_FEATURES !~ /\bsast_advanced\b/'
41
41
  - local: .gitlab/ci/rules.yml
42
+ - local: .gitlab/ci/python-base.yml
42
43
 
43
44
  .qa:
44
45
  extends: .rules_qa_security
@@ -63,7 +64,7 @@ semgrep-sast:
63
64
 
64
65
  ruff:
65
66
  extends: .qa
66
- image: python
67
+ image: quay.io/lib/python
67
68
  script:
68
69
  - python -m pip install
69
70
  ruff
@@ -84,7 +85,7 @@ ruff:
84
85
 
85
86
  mypy:
86
87
  extends: .qa
87
- image: python
88
+ image: quay.io/lib/python
88
89
  script:
89
90
  - python -m pip install
90
91
  mypy
@@ -107,3 +108,16 @@ mypy:
107
108
  artifacts:
108
109
  reports:
109
110
  codequality: gl-mypy-code-quality.json
111
+
112
+ rstcheck:
113
+ extends:
114
+ - .python_base
115
+ - .qa
116
+ image: quay.io/lib/python
117
+ script:
118
+ - python -m pip install rstcheck[sphinx]
119
+ - python .gitlab/ci/rstcheck.py > rstcheck.json
120
+ - python -m json.tool rstcheck.json
121
+ artifacts:
122
+ reports:
123
+ codequality: rstcheck.json
@@ -0,0 +1,108 @@
1
+ """Run rstcheck and report output for codeclimate."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import hashlib
6
+ import json
7
+ import re
8
+ import sys
9
+ import typing
10
+ from pathlib import Path
11
+
12
+ from rstcheck_core.config import RstcheckConfig
13
+ from rstcheck_core.runner import RstcheckMainRunner
14
+
15
+ if typing.TYPE_CHECKING:
16
+ from typing import Literal
17
+
18
+ from rstcheck_core.types import LintError
19
+
20
+ MESSAGE_RE = re.compile(
21
+ r"\((?P<severity>[A-Z]+)/[0-9]+\)(\s+)(?P<message>.*)",
22
+ )
23
+ SEVERITY: dict[str, str] = {
24
+ "ERROR": "major",
25
+ "SEVERE": "major",
26
+ "INFO": "info",
27
+ "WARNING": "minor",
28
+ }
29
+
30
+
31
+ class CodeQualityLocation(typing.TypedDict):
32
+ """Location parameter in a `CodeQualityItem`."""
33
+
34
+ path: str
35
+ lines: dict[str, int]
36
+
37
+
38
+ class CodeQualityItem(typing.TypedDict):
39
+ """Gitlab Code Quality item.
40
+
41
+ See <https://docs.gitlab.com/ci/testing/code_quality/#code-quality-report-format>.
42
+ """
43
+
44
+ description: str
45
+ check_name: str
46
+ fingerprint: str
47
+ severity: Literal["info", "minor", "major", "critical", "blocker"]
48
+ location: CodeQualityLocation
49
+
50
+
51
+ def rstcheck(
52
+ config_path: Path,
53
+ check_paths: list[str | Path],
54
+ *,
55
+ recursive: bool = True,
56
+ ) -> RstcheckMainRunner:
57
+ """Create, execute, and return an `rstcheck_core.runner.RstcheckMainRunner`."""
58
+ config = RstcheckConfig(
59
+ config_path=config_path,
60
+ recursive=recursive,
61
+ )
62
+ runner = RstcheckMainRunner(
63
+ check_paths=list(map(Path, check_paths)),
64
+ rstcheck_config=config,
65
+ )
66
+ runner.check()
67
+ return runner
68
+
69
+
70
+ def codeclimate_item(item: LintError) -> CodeQualityItem:
71
+ """Construct a codeclimate item for this rstcheck lint error."""
72
+ fingerprint = hashlib.sha1(
73
+ "".join(map(str, item.values())).encode("utf-8"),
74
+ usedforsecurity=False,
75
+ ).hexdigest()
76
+ match = MESSAGE_RE.match(item["message"]).groupdict()
77
+ return {
78
+ "check_name": match["message"],
79
+ "description": match["message"],
80
+ "fingerprint": fingerprint,
81
+ "location": {
82
+ "path": str(item["source_origin"]),
83
+ "lines": {
84
+ "begin": (lineno := int(item["line_number"])),
85
+ "end": lineno,
86
+ },
87
+ },
88
+ "severity": SEVERITY.get(match["severity"], "info"),
89
+ }
90
+
91
+
92
+ def codeclimate(items: list[LintError]) -> list[CodeQualityItem]:
93
+ """Parse a list of errors for codeclimate."""
94
+ return [codeclimate_item(item) for item in items]
95
+
96
+
97
+ def main() -> None:
98
+ """Run `rstcheck` and print a codeclimate JSON report."""
99
+ results = rstcheck(
100
+ Path("pyproject.toml"),
101
+ ["docs"],
102
+ )
103
+ issues = codeclimate(results.errors)
104
+ json.dump(issues, sys.stdout)
105
+
106
+
107
+ if __name__ == "__main__":
108
+ main()
@@ -15,18 +15,18 @@ spec:
15
15
  rules:
16
16
  - if: $CI_COMMIT_TAG
17
17
 
18
- # default branch (all pipelines)
19
- .rules_default:
18
+ # protected branch (main or release/xxx, all pipelines)
19
+ .rules_protected:
20
20
  rules:
21
- - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
21
+ - if: '$CI_COMMIT_BRANCH && $CI_COMMIT_REF_PROTECTED == "true"'
22
22
 
23
- # default branch push (not schedules)
24
- .rules_default_push:
23
+ # protected branch push (not schedules)
24
+ .rules_protected_push:
25
25
  rules:
26
- - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
26
+ - if: '$CI_PIPELINE_SOURCE == "push" && $CI_COMMIT_BRANCH && $CI_COMMIT_REF_PROTECTED == "true"'
27
27
 
28
28
  # schedules on default branch
29
- .rules_default_schedule:
29
+ .rules_protected_schedule:
30
30
  rules:
31
31
  - if: '$CI_PIPELINE_SOURCE == "schedule" && $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH'
32
32
 
@@ -41,6 +41,10 @@ spec:
41
41
  # not on branches with an open merge request
42
42
  - if: $CI_COMMIT_BRANCH && $CI_OPEN_MERGE_REQUESTS
43
43
  when: never
44
+ # not on protected branches
45
+ - if: $CI_COMMIT_BRANCH && $CI_COMMIT_REF_PROTECTED == "true"
46
+ when: never
47
+ # all other branches
44
48
  - if: $CI_COMMIT_BRANCH
45
49
 
46
50
  # -- job types
@@ -53,20 +57,20 @@ spec:
53
57
  # nightly builds
54
58
  .rules_nightly:
55
59
  rules:
56
- - !reference [.rules_default_schedule, rules]
60
+ - !reference [.rules_protected_schedule, rules]
57
61
 
58
62
  # build jobs
59
63
  .rules_build:
60
64
  rules:
61
65
  - !reference [.rules_tag, rules]
62
- - !reference [.rules_default_push, rules]
66
+ - !reference [.rules_protected_push, rules]
63
67
  - !reference [.rules_merge_request, rules]
64
68
  - !reference [.rules_branch, rules]
65
69
 
66
70
  # full test suite
67
71
  .rules_full_test:
68
72
  rules:
69
- - !reference [.rules_default, rules]
73
+ - !reference [.rules_protected, rules]
70
74
  - !reference [.rules_merge_request, rules]
71
75
 
72
76
  # basic test suite
@@ -76,6 +80,6 @@ spec:
76
80
 
77
81
  .rules_qa_security:
78
82
  rules:
79
- - !reference [.rules_default, rules]
83
+ - !reference [.rules_protected, rules]
80
84
  - !reference [.rules_nightly, rules]
81
85
  - !reference [.rules_merge_request, rules]
@@ -7,7 +7,7 @@ spec:
7
7
  description: "Pipeline stage in which to add jobs"
8
8
  type: string
9
9
  image:
10
- default: python
10
+ default: quay.io/lib/python
11
11
  description: "Container image to build in"
12
12
  type: string
13
13
  requirements:
@@ -18,6 +18,10 @@ spec:
18
18
  default: "test"
19
19
  description: "Name of the extra feature group(s) to install when installing <install_target>"
20
20
  type: string
21
+ pip_cmd:
22
+ default: "python -m pip"
23
+ description: "Command to use to install packages (default: python -m pip)"
24
+ type: string
21
25
  pip_options:
22
26
  default: ""
23
27
  description: "Extra options to pass to pip install"
@@ -58,10 +62,10 @@ include:
58
62
  (Path(os.getenv('XDG_CACHE_HOME')) / 'astropy').mkdir(parents=True, exist_ok=True)
59
63
  "
60
64
  # install pytest
61
- - python -m pip install pytest pytest-cov $[[ inputs.pip_options ]]
62
- - python -m pip install $[[ inputs.install_target ]][$[[ inputs.install_extra ]]] $[[ inputs.pip_options ]]
65
+ - $[[ inputs.pip_cmd ]] install pytest pytest-cov $[[ inputs.pip_options ]]
66
+ - $[[ inputs.pip_cmd ]] install $[[ inputs.install_target ]][$[[ inputs.install_extra ]]] $[[ inputs.pip_options ]]
63
67
  # list installed packages
64
- - python -m pip list installed
68
+ - $[[ inputs.pip_cmd ]] list
65
69
  # run the tests
66
70
  - python -m pytest --junit-xml=junit.xml $[[ inputs.pytest_options ]]
67
71
  # run any extra tests
@@ -80,7 +84,7 @@ include:
80
84
  - .coverage*
81
85
  coverage: null
82
86
  cache:
83
- # cache pip packages
87
+ # cache Pip downloads
84
88
  - !reference [.python_base, cache]
85
89
  # cache GWpy downloaded files
86
90
  - key: "gwpy-${CI_JOB_NAME_SLUG}"
@@ -8,12 +8,14 @@ include:
8
8
  - local: .gitlab/ci/test-job.yml
9
9
  inputs:
10
10
  job_name: "basic_test"
11
+ pip_cmd: "uv pip"
11
12
  pytest_options: "--color yes --cov gwpy --numprocesses auto gwpy/"
12
13
  install_extra: "test"
13
14
 
14
15
  # full test template
15
16
  - local: .gitlab/ci/test-job.yml
16
17
  inputs:
18
+ pip_cmd: "uv pip"
17
19
  pytest_options: "--color yes --cov gwpy --durations 50 --numprocesses auto gwpy/ examples/"
18
20
  install_extra: "dev,test"
19
21
 
@@ -69,6 +71,51 @@ include:
69
71
  paths:
70
72
  - .cache/choco
71
73
 
74
+ .uv_install: &uv_install
75
+ # install uv
76
+ - wget -qO- https://astral.sh/uv/install.sh | sh -s - -q
77
+ - source ${XDG_BIN_HOME:-$HOME/.local/bin}/env
78
+
79
+ .uv_venv: &uv_venv
80
+ # configure a virtual environment for the right Python version
81
+ - uv venv --python ${PYTHON_VERSION}
82
+ - source .venv/bin/activate
83
+
84
+ .uv_install_windows: &uv_install_windows
85
+ # install uv
86
+ - powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"
87
+ - $env:PATH = $env:USERPROFILE + "\.local\bin;$env:PATH"
88
+ - $env:PATH -split ';'
89
+
90
+ .uv_venv_windows: &uv_venv_windows
91
+ # configure a virtual environment for the right Python version
92
+ - uv venv --python ${PYTHON_VERSION}
93
+ - .venv\Scripts\activate
94
+
95
+ .uv:
96
+ image: "ghcr.io/astral-sh/uv:python$PYTHON_VERSION-bookworm"
97
+ variables:
98
+ # set the cache directory for uv
99
+ UV_CACHE_DIR: "$CI_PROJECT_DIR/.cache/uv"
100
+ before_script:
101
+ - *uv_install
102
+ - *uv_venv
103
+ after_script:
104
+ - uv cache prune --ci
105
+ cache:
106
+ # cache uv packages
107
+ - key: "uv-${CI_JOB_NAME_SLUG}"
108
+ paths:
109
+ - $UV_CACHE_DIR
110
+
111
+ .uv_windows:
112
+ extends:
113
+ - .uv
114
+ - .windows
115
+ before_script:
116
+ - *uv_install_windows
117
+ - *uv_venv_windows
118
+
72
119
  # -- basic tests for new branches without MRs
73
120
  #
74
121
  # This test matrix provides a sanity check for developers working
@@ -83,7 +130,8 @@ basic_test:
83
130
  extends:
84
131
  - .prod_test
85
132
  - .basic_test
86
- image: python:${PYTHON_VERSION}
133
+ - .uv
134
+ image: "ghcr.io/astral-sh/uv:python$PYTHON_VERSION-bookworm"
87
135
  rules:
88
136
  - !reference [.rules_basic_test, rules]
89
137
 
@@ -101,17 +149,21 @@ basic_test:
101
149
  python_test_linux:
102
150
  extends:
103
151
  - .dev_test
152
+ - .uv
104
153
  - .linux
105
- image: python:${PYTHON_VERSION}
106
154
  rules:
107
155
  - !reference [.linux, rules]
108
156
  - !reference [.rules_full_test, rules]
157
+ before_script:
158
+ # don't need to install uv, it comes with the image
159
+ - *uv_venv
109
160
 
110
161
  # macOS
111
162
  python_test_macos:
112
163
  extends:
113
164
  - .prod_test
114
- - .brew
165
+ - .uv
166
+ - .macos
115
167
  rules:
116
168
  - !reference [.macos, rules]
117
169
  - !reference [.rules_full_test, rules]
@@ -121,41 +173,15 @@ python_test_macos:
121
173
  - "3.10"
122
174
  - "3.11"
123
175
  #- "3.12" <-- cannot build ligo-segments on macOS
124
- before_script:
125
- # install Python using Homebrew
126
- - brew install python@${PYTHON_VERSION}
127
- - PYTHON="$(brew --prefix)/opt/python@${PYTHON_VERSION}/libexec/bin/python"
128
- # create a virtual environment to work in
129
- - $PYTHON -m venv --system-site-packages venv
130
- - . ./venv/bin/activate
131
- cache:
132
- # cache pip packages
133
- - !reference [.test, cache]
134
- # and homebrew packages
135
- - !reference [.brew, cache]
136
176
 
137
177
  # Windows
138
178
  python_test_windows:
139
179
  extends:
140
180
  - .prod_test
141
- - .choco
181
+ - .uv_windows
142
182
  rules:
143
183
  - !reference [.windows, rules]
144
184
  - !reference [.rules_full_test, rules]
145
- before_script:
146
- # install Python using Choco
147
- - $PYTHON_VERSION_NODOTS = ${PYTHON_VERSION}.Replace('.', '')
148
- - choco install
149
- --cache $CHOCO_CACHE_DIR
150
- --yes
151
- python${PYTHON_VERSION_NODOTS}
152
- - $env:PATH += ";C:\Python" + ${PYTHON_VERSION_NODOTS} + ";C:\Python" + ${PYTHON_VERSION_NODOTS} + "\Scripts"
153
- - echo $PYTEST_ADDOPTS
154
- cache:
155
- # cache pip packages
156
- - !reference [.test, cache]
157
- # and choco packages
158
- - !reference [.choco, cache]
159
185
 
160
186
  # -- conda tests
161
187
  #
@@ -169,12 +195,21 @@ python_test_windows:
169
195
  .conda_create_test_env:
170
196
  before_script:
171
197
  - conda info --all
172
- - conda create --quiet --yes --name pip2conda pip2conda
173
- - conda run -n pip2conda pip2conda
198
+ # create an (almost) empty environment
199
+ - conda create -n pip2conda
200
+ --yes
201
+ --quiet
202
+ python
203
+ - conda activate pip2conda
204
+ # and use uv to install pip2conda into it
205
+ - uv pip install pip2conda
206
+ # then use pip2conda to solve (sort of) the test environment
207
+ - python -m pip2conda
174
208
  --all
175
209
  --output environment.txt
176
210
  --python-version ${PYTHON_VERSION}
177
211
  - cat environment.txt
212
+ # create the test environment
178
213
  - conda create --quiet --yes --name test --file environment.txt
179
214
  - conda list --name test
180
215
  - conda activate test
@@ -182,11 +217,12 @@ python_test_windows:
182
217
  .conda_test:
183
218
  extends:
184
219
  - .prod_test
220
+ - .uv
185
221
  stage: conda
186
222
  variables:
187
223
  CONDA_PKGS_DIRS: "${CI_PROJECT_DIR}/.cache/conda/pkgs"
188
224
  cache:
189
- - !reference [.test, cache]
225
+ - !reference [.uv, cache]
190
226
  - key: "conda-${CI_JOB_NAME_SLUG}"
191
227
  paths:
192
228
  - .cache/conda/pkgs/*.conda
@@ -199,11 +235,13 @@ conda_test_linux:
199
235
  rules:
200
236
  - !reference [.linux, rules]
201
237
  - !reference [.rules_full_test, rules]
202
- image: condaforge/miniforge3
238
+ image: quay.io/condaforge/miniforge3
203
239
  before_script:
240
+ # install uv
241
+ - *uv_install
204
242
  # init conda
205
243
  - . $(conda info --base)/etc/profile.d/conda.sh
206
- # create test environment using pip2conda
244
+ # create the test environment using conda, uv, and pip2conda
207
245
  - !reference [.conda_create_test_env, before_script]
208
246
  # initialise credentials
209
247
  - bash -ex .gitlab/ci/init-creds.sh
@@ -222,20 +260,25 @@ conda_test_macos:
222
260
  # then do the same init as Linux
223
261
  - !reference [conda_test_linux, before_script]
224
262
  cache:
225
- # cache conda packages
263
+ # cache uv/conda packages
226
264
  - !reference [.conda_test, cache]
227
265
  # and homebrew packages
228
266
  - !reference [.brew, cache]
229
267
 
230
268
  # Windows
231
269
  conda_test_windows:
270
+ # allow windows a bit more time for provisioning
271
+ timeout: 90m
232
272
  extends:
233
273
  - .conda_test
234
274
  - .choco
275
+ - .uv_windows
235
276
  rules:
236
277
  - !reference [.windows, rules]
237
278
  - !reference [.rules_full_test, rules]
238
279
  before_script:
280
+ # install uv
281
+ - *uv_install_windows
239
282
  # install miniforge using choco
240
283
  - choco install
241
284
  --cache $CHOCO_CACHE_DIR
@@ -244,7 +287,7 @@ conda_test_windows:
244
287
  - $env:PATH += ";C:\tools\miniforge3\Scripts;C:\tools\miniforge3"
245
288
  - conda init powershell
246
289
  - . C:\tools\miniforge3\shell\condabin\conda-hook.ps1
247
- # create the test environment using conda
290
+ # create the test environment using conda, uv, and pip2conda
248
291
  - !reference [.conda_create_test_env, before_script]
249
292
  cache:
250
293
  # cache conda packages
@@ -19,7 +19,7 @@ twine:
19
19
  when: never
20
20
  - !reference [.rules_deploy, rules]
21
21
  stage: $[[ inputs.stage ]]
22
- image: python
22
+ image: quay.io/lib/python
23
23
  environment:
24
24
  name: $PYPI_REPOSITORY
25
25
  url: https://$PYPI_HOSTNAME/project/$CI_PROJECT_NAME
@@ -59,7 +59,7 @@ twine_test:
59
59
  rules:
60
60
  - if: '$CI_COMMIT_MESSAGE =~ /\[skip deploy\]/'
61
61
  when: never
62
- - !reference [.rules_default_push, rules]
62
+ - !reference [.rules_protected_push, rules]
63
63
  variables:
64
64
  PYPI_REPOSITORY: "testpypi"
65
65
  PYPI_HOSTNAME: "test.pypi.org"
@@ -0,0 +1,28 @@
1
+ # Read the Docs configuration file
2
+ # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3
+
4
+ version: 2
5
+
6
+ build:
7
+ os: "ubuntu-lts-latest"
8
+ tools:
9
+ python: "mambaforge-latest"
10
+ jobs:
11
+ post_install:
12
+ # show what is installed in the build environment
13
+ - conda list
14
+
15
+ conda:
16
+ environment: docs/environment.yaml
17
+
18
+ python:
19
+ install:
20
+ - method: pip
21
+ path: .
22
+ extra_requirements:
23
+ - dev
24
+ - docs
25
+
26
+ sphinx:
27
+ builder: dirhtml
28
+ configuration: docs/conf.py