hutch-python 1.22.0__tar.gz → 1.23.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (147) hide show
  1. hutch_python-1.23.1/.github/CODEOWNERS +14 -0
  2. {hutch_python-1.22.0 → hutch_python-1.23.1}/.github/workflows/standard.yml +2 -2
  3. {hutch_python-1.22.0 → hutch_python-1.23.1}/.pre-commit-config.yaml +3 -3
  4. {hutch_python-1.22.0 → hutch_python-1.23.1}/PKG-INFO +5 -5
  5. {hutch_python-1.22.0 → hutch_python-1.23.1}/conda-recipe/meta.yaml +2 -2
  6. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/releases.rst +40 -0
  7. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/yaml_files.rst +38 -6
  8. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs-requirements.txt +0 -2
  9. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/_version.py +9 -4
  10. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/constants.py +2 -1
  11. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/epics_arch.py +1 -1
  12. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/happi.py +41 -2
  13. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/ipython_session_timer.py +2 -2
  14. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/load_conf.py +21 -6
  15. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_cli.py +19 -9
  16. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_happi.py +62 -1
  17. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python.egg-info/PKG-INFO +5 -5
  18. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python.egg-info/SOURCES.txt +1 -0
  19. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python.egg-info/requires.txt +2 -3
  20. {hutch_python-1.22.0 → hutch_python-1.23.1}/requirements.txt +2 -2
  21. {hutch_python-1.22.0 → hutch_python-1.23.1}/.coveragerc +0 -0
  22. {hutch_python-1.22.0 → hutch_python-1.23.1}/.flake8 +0 -0
  23. {hutch_python-1.22.0 → hutch_python-1.23.1}/.git_archival.txt +0 -0
  24. {hutch_python-1.22.0 → hutch_python-1.23.1}/.gitattributes +0 -0
  25. {hutch_python-1.22.0 → hutch_python-1.23.1}/.github/ISSUE_TEMPLATE.md +0 -0
  26. {hutch_python-1.22.0 → hutch_python-1.23.1}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
  27. {hutch_python-1.22.0 → hutch_python-1.23.1}/.gitignore +0 -0
  28. {hutch_python-1.22.0 → hutch_python-1.23.1}/.landscape.yml +0 -0
  29. {hutch_python-1.22.0 → hutch_python-1.23.1}/AUTHORS.rst +0 -0
  30. {hutch_python-1.22.0 → hutch_python-1.23.1}/CONTRIBUTING.rst +0 -0
  31. {hutch_python-1.22.0 → hutch_python-1.23.1}/LICENSE +0 -0
  32. {hutch_python-1.22.0 → hutch_python-1.23.1}/MANIFEST.in +0 -0
  33. {hutch_python-1.22.0 → hutch_python-1.23.1}/README.rst +0 -0
  34. {hutch_python-1.22.0 → hutch_python-1.23.1}/bin/hutch-python +0 -0
  35. {hutch_python-1.22.0 → hutch_python-1.23.1}/dev-requirements.txt +0 -0
  36. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/Makefile +0 -0
  37. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/hutch_python.ipynb +0 -0
  38. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/pre-release-notes.sh +0 -0
  39. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/release_notes.py +0 -0
  40. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/beamline.rst +0 -0
  41. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/bug.rst +0 -0
  42. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/cache.rst +0 -0
  43. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/cli.rst +0 -0
  44. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/conf.py +0 -0
  45. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/daq.rst +0 -0
  46. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/database.rst +0 -0
  47. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/debug.rst +0 -0
  48. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/environment.rst +0 -0
  49. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/experiment.rst +0 -0
  50. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/hutch_setup.rst +0 -0
  51. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/index.rst +0 -0
  52. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/ipython_log.rst +0 -0
  53. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/load_conf.rst +0 -0
  54. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/load_parts.rst +0 -0
  55. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/log_setup.rst +0 -0
  56. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/namespace.rst +0 -0
  57. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/object_configuration.rst +0 -0
  58. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/other_modules.rst +0 -0
  59. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/presets.rst +0 -0
  60. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/report.rst +0 -0
  61. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/start.rst +0 -0
  62. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/startup.rst +0 -0
  63. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/tips.rst +0 -0
  64. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/tutorial.ipynb +0 -0
  65. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/upcoming_release_notes/template-full.rst +0 -0
  66. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/upcoming_release_notes/template-short.rst +0 -0
  67. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/user_utils.rst +0 -0
  68. {hutch_python-1.22.0 → hutch_python-1.23.1}/docs/source/utils.rst +0 -0
  69. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/__init__.py +0 -0
  70. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/__main__.py +0 -0
  71. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/bug.py +0 -0
  72. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cache.py +0 -0
  73. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/calc_defaults.py +0 -0
  74. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cam_load.py +0 -0
  75. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cli.py +0 -0
  76. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/cookiecutter.json +0 -0
  77. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/.gitignore +0 -0
  78. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/README.md +0 -0
  79. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/conf.yml +0 -0
  80. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/experiments/__init__.py +0 -0
  81. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/set-dev +0 -0
  82. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}/__init__.py +0 -0
  83. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}/beamline.py +0 -0
  84. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}env +0 -0
  85. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}python +0 -0
  86. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/debug.py +0 -0
  87. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/env_version.py +0 -0
  88. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/exp_load.py +0 -0
  89. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/ipython_log.py +0 -0
  90. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/lcls.py +0 -0
  91. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/log_setup.py +0 -0
  92. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/logging.yml +0 -0
  93. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/mpl_config.py +0 -0
  94. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/namespace.py +0 -0
  95. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/obj_config.py +0 -0
  96. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/ophyd_settings.py +0 -0
  97. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/options.py +0 -0
  98. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/plan_defaults.py +0 -0
  99. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/plan_wrappers.py +0 -0
  100. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/print_hint_banner.py +0 -0
  101. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/pt_app_config.py +0 -0
  102. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/qs_load.py +0 -0
  103. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/sim.py +0 -0
  104. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/startup_script.py +0 -0
  105. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/templates/issue.template +0 -0
  106. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/__init__.py +0 -0
  107. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/bad_script.py +0 -0
  108. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/camviewer.cfg +0 -0
  109. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/conf.yaml +0 -0
  110. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/conftest.py +0 -0
  111. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/envs/pcds-1.0.0 +0 -0
  112. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/envs/pcds-2.0.0 +0 -0
  113. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/envs/z-env +0 -0
  114. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/experiments/sample_expname.py +0 -0
  115. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/experiments/x010.py +0 -0
  116. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/experiments/x011.py +0 -0
  117. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/happi_db.json +0 -0
  118. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/sample_module_1.py +0 -0
  119. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/sample_module_2.py +0 -0
  120. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/script.py +0 -0
  121. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_bug.py +0 -0
  122. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_cache.py +0 -0
  123. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_cam_load.py +0 -0
  124. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_epics_arch.py +0 -0
  125. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_experiment.py +0 -0
  126. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_ipython_log.py +0 -0
  127. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_ipython_session_timer.py +0 -0
  128. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_load_conf.py +0 -0
  129. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_log_setup.py +0 -0
  130. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_namespace.py +0 -0
  131. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_obj_config.py +0 -0
  132. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_plan_wrappers.py +0 -0
  133. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_questionnaire.py +0 -0
  134. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_tstpython.py +0 -0
  135. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_user_load.py +0 -0
  136. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/test_utils.py +0 -0
  137. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/tst/__init__.py +0 -0
  138. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/tst/beamline.py +0 -0
  139. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/tests/tstpython +0 -0
  140. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/user_load.py +0 -0
  141. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/utils.py +0 -0
  142. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python/version.py +0 -0
  143. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python.egg-info/dependency_links.txt +0 -0
  144. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python.egg-info/entry_points.txt +0 -0
  145. {hutch_python-1.22.0 → hutch_python-1.23.1}/hutch_python.egg-info/top_level.txt +0 -0
  146. {hutch_python-1.22.0 → hutch_python-1.23.1}/pyproject.toml +0 -0
  147. {hutch_python-1.22.0 → hutch_python-1.23.1}/setup.cfg +0 -0
@@ -0,0 +1,14 @@
1
+ # default group
2
+ * @pcdshub/python-reviewers
3
+
4
+ # language-specific group(s)
5
+ ## PYTHON files
6
+ *.py @pcdshub/python-reviewers
7
+ *.pyi @pcdshub/python-reviewers
8
+ *.pyc @pcdshub/python-reviewers
9
+ *.pyw @pcdshub/python-reviewers
10
+ *.pyx @pcdshub/python-reviewers
11
+ *.pyd @pcdshub/python-reviewers
12
+
13
+ # github folder holds administrative files
14
+ .github/** @pcdshub/software-admin
@@ -18,10 +18,10 @@ jobs:
18
18
  # Extras that will be installed for both conda/pip:
19
19
  testing-extras: ""
20
20
  # Extras to be installed only for conda-based testing:
21
- conda-testing-extras: "ipython=8.4.0"
21
+ conda-testing-extras: ""
22
22
  # Extras to be installed only for pip-based testing:
23
23
  # Set numpy<2 for now, remove when xraylib updates
24
- pip-testing-extras: "ipython==8.4.0 numpy<2"
24
+ pip-testing-extras: ""
25
25
  # System packages to be installed only for conda-based testing:
26
26
  conda-system-packages: ""
27
27
  # System packages to be installed only for pip-based testing:
@@ -7,7 +7,7 @@ exclude: |
7
7
 
8
8
  repos:
9
9
  - repo: https://github.com/pre-commit/pre-commit-hooks
10
- rev: v4.4.0
10
+ rev: v5.0.0
11
11
  hooks:
12
12
  - id: no-commit-to-branch
13
13
  - id: trailing-whitespace
@@ -27,11 +27,11 @@ repos:
27
27
  - id: debug-statements
28
28
 
29
29
  - repo: https://github.com/pycqa/flake8.git
30
- rev: 6.0.0
30
+ rev: 7.2.0
31
31
  hooks:
32
32
  - id: flake8
33
33
 
34
34
  - repo: https://github.com/timothycrosley/isort
35
- rev: 5.12.0
35
+ rev: 6.0.1
36
36
  hooks:
37
37
  - id: isort
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: hutch-python
3
- Version: 1.22.0
3
+ Version: 1.23.1
4
4
  Summary: Launcher and Config Reader for LCLS Interactive IPython Sessions
5
5
  Author: SLAC National Accelerator Laboratory
6
6
  License: Copyright (c) 2023, The Board of Trustees of the Leland Stanford Junior
@@ -55,14 +55,14 @@ Requires-Dist: bluesky>=1.8.0
55
55
  Requires-Dist: coloredlogs>=15.0.0
56
56
  Requires-Dist: cookiecutter>=1.7.0
57
57
  Requires-Dist: happi>=1.9.0
58
- Requires-Dist: ipython>=7.26.0
58
+ Requires-Dist: ipython<9.0.0
59
59
  Requires-Dist: jinja2>=2.11.0
60
60
  Requires-Dist: lightpath>=1.0.1
61
61
  Requires-Dist: matplotlib>=3.4.0
62
62
  Requires-Dist: nabs>=1.5.0
63
63
  Requires-Dist: pcdscalc>=0.6.0
64
64
  Requires-Dist: pcdsdaq>=2.3.0
65
- Requires-Dist: pcdsdevices>=7.0.0
65
+ Requires-Dist: pcdsdevices>8.7.0
66
66
  Requires-Dist: pcdsutils>=0.5.0
67
67
  Requires-Dist: psdaq-control-minimal
68
68
  Requires-Dist: pyfiglet>=0.8.0
@@ -83,7 +83,7 @@ Requires-Dist: sphinx; extra == "doc"
83
83
  Requires-Dist: sphinx_rtd_theme; extra == "doc"
84
84
  Requires-Dist: sphinxcontrib-jquery; extra == "doc"
85
85
  Requires-Dist: pypandoc; extra == "doc"
86
- Requires-Dist: numpy<2; extra == "doc"
86
+ Dynamic: license-file
87
87
 
88
88
  ============
89
89
  Hutch Python
@@ -27,14 +27,14 @@ requirements:
27
27
  - cookiecutter >=1.7.0
28
28
  - elog >=1.1.0
29
29
  - happi >=1.9.0
30
- - ipython >=7.26.0
30
+ - ipython <9.0.0
31
31
  - jinja2 >=2.11.0
32
32
  - lightpath >=1.0.1
33
33
  - matplotlib-base >=3.4.0
34
34
  - nabs >=1.5.0
35
35
  - pcdscalc >=0.6.0
36
36
  - pcdsdaq >=2.3.0
37
- - pcdsdevices >=7.0.0
37
+ - pcdsdevices >8.7.0
38
38
  - pcdsutils >=0.6.0
39
39
  - psdaq-control-minimal >=3.3.19
40
40
  - psdm_qs_cli >=0.3.1
@@ -2,6 +2,46 @@ Release History
2
2
  ###############
3
3
 
4
4
 
5
+ v1.23.1 (2025-05-14)
6
+ ====================
7
+
8
+ Bugfixes
9
+ --------
10
+ - Fixed pathcheck in hutch_python/epics_arch.py:create_softlink
11
+
12
+ Maintenance
13
+ -----------
14
+ - Separate test_hist_file_arg into three separate test cases to hopefully alleviate test suite timeout issues
15
+
16
+ Contributors
17
+ ------------
18
+ - tangkong
19
+ - vespos
20
+
21
+
22
+
23
+ v1.23.0 (2025-04-07)
24
+ ====================
25
+
26
+ Features
27
+ --------
28
+ - Added ability to load additional devices not on the current beamline or hutch/area using happi search.
29
+
30
+ Bugfixes
31
+ --------
32
+ - update functions anticipating py3.12 and IPython > 8.26
33
+
34
+ Maintenance
35
+ -----------
36
+ - Enable the deferral of preset loading to avoid a pre-mature performance hit
37
+
38
+ Contributors
39
+ ------------
40
+ - janeliu-slac
41
+ - tangkong
42
+
43
+
44
+
5
45
  v1.22.0 (2024-12-19)
6
46
  ====================
7
47
 
@@ -163,21 +163,53 @@ secondary elog.
163
163
 
164
164
  exclude_devices
165
165
  ------------
166
- The ``exclude_devices`` key is optional. ``exclude_devices`` expects a list
167
- of strings containing names of upstream devices that should not be loaded.
168
- It reduces the amount of unnecessary information shown in the console at
169
- load time. The list can be created as a multi-line array of strings or all
170
- on one line using the following formats:
166
+ The ``exclude_devices`` key is optional. ``exclude_devices`` expects a string
167
+ that starts with a "-" symbol on each line. The string is the name of a device
168
+ that should not be loaded.
169
+
170
+ This feature reduces the amount of unnecessary information shown in the console
171
+ at load time. The list uses the following format:
171
172
 
172
173
  .. code-block:: YAML
173
174
 
174
175
  exclude_devices:
175
176
  - crix_cryo_y
176
177
  - at2k2_calc
178
+ - tmo_lamp_sqr1
179
+
180
+
181
+ additional_devices
182
+ ------------
183
+ The ``additional_devices`` key is optional. This key allows hutch-python to
184
+ load additional devices that are on a different beamline or in a different
185
+ hutch/area. The first entry below ``additional_devices`` is a search name,
186
+ such as 'tmo_sqr1_search'. Search names are arbitrarily determined by the user
187
+ but should start with a letter or number. Each search name is followed by a
188
+ happi search key, such as "beamline" and a value. For example, "beamline: TMO".
189
+ This tells hutch-python to gather all devices on the TMO beamline and load
190
+ them. A second search criterion can be added below "beamline: TMO" to constrain
191
+ the search further, so that only those devices that fit both search criteria
192
+ will be loaded. For example, adding "device_class: pcdsdevices.sqr1.SQR1" below
193
+ "beamline: TMO" tells hutch-python to load devices from the TMO beamline whose
194
+ "device_class" key has a value of "pcdsdevices.sqr1.SQR1". More lines can be
195
+ added to obtain even more specific search results.
196
+
197
+ A search value can contain a wildcard symbol (*). For example, "name: tmo_*".
198
+
199
+ In the example below hutch-python will load all devices from "tmo_sqr1_search",
200
+ "las_search", and "crix_search".
177
201
 
178
202
  .. code-block:: YAML
179
203
 
180
- exclude_devices: ['crix_cryo_y', 'at2k2_calc']
204
+ additional_devices:
205
+ tmo_sqr1_search:
206
+ beamline: TMO
207
+ device_class: pcdsdevices.sqr1.SQR1
208
+ z: -1, 1
209
+ las_search:
210
+ name: LAS
211
+ crix_search:
212
+ name: crix_*
181
213
 
182
214
 
183
215
  Full File Example
@@ -4,5 +4,3 @@ sphinx
4
4
  sphinx_rtd_theme
5
5
  sphinxcontrib-jquery
6
6
  pypandoc
7
- # Temporary pin, xraylib 4.1.3 (pcdscalc) incompatible
8
- numpy <2
@@ -1,8 +1,13 @@
1
- # file generated by setuptools_scm
1
+ # file generated by setuptools-scm
2
2
  # don't change, don't track in version control
3
+
4
+ __all__ = ["__version__", "__version_tuple__", "version", "version_tuple"]
5
+
3
6
  TYPE_CHECKING = False
4
7
  if TYPE_CHECKING:
5
- from typing import Tuple, Union
8
+ from typing import Tuple
9
+ from typing import Union
10
+
6
11
  VERSION_TUPLE = Tuple[Union[int, str], ...]
7
12
  else:
8
13
  VERSION_TUPLE = object
@@ -12,5 +17,5 @@ __version__: str
12
17
  __version_tuple__: VERSION_TUPLE
13
18
  version_tuple: VERSION_TUPLE
14
19
 
15
- __version__ = version = '1.22.0'
16
- __version_tuple__ = version_tuple = (1, 22, 0)
20
+ __version__ = version = '1.23.1'
21
+ __version_tuple__ = version_tuple = (1, 23, 1)
@@ -39,7 +39,8 @@ VALID_KEYS = (
39
39
  'daq_host',
40
40
  'obj_config',
41
41
  'session_timer',
42
- 'exclude_devices'
42
+ 'exclude_devices',
43
+ 'additional_devices'
43
44
  )
44
45
  NO_LOG_EXCEPTIONS = (KeyboardInterrupt, SystemExit)
45
46
  LOG_DOMAINS = {".pcdsn", ".slac.stanford.edu"}
@@ -310,7 +310,7 @@ def create_softlink(experiment, link_path):
310
310
  overwrites it with the new active experiment.
311
311
  """
312
312
  # Defaults new softlink in /cds/group/pcds/dist/pds/{}/misc/
313
- if not os.path.exists(link_path):
313
+ if not os.path.exists(link_path.format(experiment[0:3])):
314
314
  raise OSError('Path does not exist path: %s' % link_path)
315
315
 
316
316
  subprocess.run(['ln', '-sf', link_path.format(experiment[0:3]) + 'epicsArch_'
@@ -1,9 +1,11 @@
1
1
  import enum
2
2
  import inspect
3
3
  import logging
4
+ from typing import Dict, List, Optional
4
5
 
5
6
  import happi
6
7
  import ophyd
8
+ from happi.cli import search_parser
7
9
  from happi.loader import load_devices
8
10
 
9
11
  try:
@@ -30,7 +32,8 @@ def get_happi_objs(
30
32
  light_ctrl: LightController,
31
33
  endstation: str,
32
34
  load_level: DeviceLoadLevel = DeviceLoadLevel.STANDARD,
33
- exclude_devices: list[str] = None
35
+ exclude_devices: Optional[List[str]] = None,
36
+ additional_devices: Optional[Dict[str, Dict[str, str]]] = None
34
37
  ) -> dict[str, ophyd.Device]:
35
38
  """
36
39
  Get the relevant items for ``endstation`` from the happi database ``db``.
@@ -53,16 +56,30 @@ def get_happi_objs(
53
56
  endstation: ``str``
54
57
  Name of hutch
55
58
 
59
+ load_level: ``DeviceLoadLevel``
60
+ load all or standard devices
61
+
62
+ exclude_devices: ``Optional[List[str]]``
63
+ an optional list of devices that should be excluded when loading
64
+
65
+ additional_devices: ``Optional[Dict[str, Dict[str, str]]]``
66
+ an optional dictionary of dictionaries with happi search terms
67
+ whose results are loaded
68
+
56
69
  Returns
57
70
  -------
58
71
  objs: ``dict``
59
72
  A mapping from item name to item
60
73
  """
61
74
 
62
- # Explicitly set exclude_devices to empty list to avoid mutable default arguments issue.
75
+ # Explicitly set exclude_devices and additional_devices to empty
76
+ # containers to avoid mutable default arguments issue.
63
77
  if not exclude_devices:
64
78
  exclude_devices = []
65
79
 
80
+ if not additional_devices:
81
+ additional_devices = {}
82
+
66
83
  # Load the happi Client
67
84
  if None not in (light_ctrl, lightpath):
68
85
  client = light_ctrl.client
@@ -113,6 +130,28 @@ def get_happi_objs(
113
130
  logger.warning(f'{len(containers)} active devices found for '
114
131
  'this beampath')
115
132
 
133
+ # Load additional devices
134
+ for search_val in additional_devices.values():
135
+
136
+ search_list = []
137
+ final_results = []
138
+
139
+ for entry_key, entry_val in search_val.items():
140
+ search_string = entry_key + '=' + entry_val
141
+ search_list.append(search_string)
142
+
143
+ search_results = search_parser(
144
+ client=client,
145
+ use_glob=True,
146
+ search_criteria=search_list
147
+ )
148
+ search_results = list(search_results)
149
+ final_results += search_results
150
+ final_results = list(set(final_results))
151
+
152
+ containers.extend(
153
+ res.item for res in final_results if res.item not in containers)
154
+
116
155
  # Do not load excluded devices
117
156
  for device in containers.copy():
118
157
  if device.name in exclude_devices:
@@ -58,11 +58,11 @@ class IPythonSessionTimer:
58
58
  ipython.events.register('pre_run_cell', self._set_user_active)
59
59
  ipython.events.register('post_run_cell', self._set_user_inactive)
60
60
 
61
- def _set_user_active(self):
61
+ def _set_user_active(self, *args, **kwargs):
62
62
  self.user_active = True
63
63
  self.last_active_time = time.monotonic()
64
64
 
65
- def _set_user_inactive(self):
65
+ def _set_user_inactive(self, *args, **kwargs):
66
66
  self.user_active = False
67
67
  self.last_active_time = time.monotonic()
68
68
 
@@ -305,11 +305,24 @@ def load_conf(conf, hutch_dir=None, args=None):
305
305
  'Invalid exclude_devices conf, must be a list.')
306
306
  exclude_devices = []
307
307
  else:
308
- exclude_devices = [device_name.strip() for device_name in exclude_devices]
308
+ exclude_devices = [device_name.strip()
309
+ for device_name in exclude_devices]
309
310
  except KeyError:
310
311
  exclude_devices = []
311
312
  logger.info(
312
- 'Missing exclude_devices in conf. Will load all devices.')
313
+ 'Exclude_devices has not been set in conf. Will load all devices.')
314
+
315
+ try:
316
+ # These are the additional devices to load
317
+ additional_devices = conf['additional_devices']
318
+ for search_val in additional_devices.values():
319
+ if not isinstance(search_val, dict):
320
+ logger.error(
321
+ 'Invalid additional_devices conf, must be a dictionary of dictionaries.')
322
+ except KeyError:
323
+ additional_devices = {}
324
+ logger.info(
325
+ 'Additional_devices has not been set in conf. No additional devices will be loaded.')
313
326
 
314
327
  # Set the session timeout duration
315
328
  try:
@@ -318,7 +331,7 @@ def load_conf(conf, hutch_dir=None, args=None):
318
331
  except KeyError:
319
332
  hutch_python.ipython_session_timer.configure_timeout(172800)
320
333
  logger.info(
321
- 'Missing session_timer value from conf. Set default value to 172800 seconds (48 hours).')
334
+ 'Missing session_timer value from conf. Session will time out in 48 hours.')
322
335
 
323
336
  # Make cache namespace
324
337
  cache = LoadCache((hutch or 'hutch') + '.db', hutch_dir=hutch_dir)
@@ -475,7 +488,7 @@ def load_conf(conf, hutch_dir=None, args=None):
475
488
 
476
489
  # Gather relevant objects given the BeamPath
477
490
  happi_objs = get_happi_objs(
478
- db, lc, hutch, load_level=load_level, exclude_devices=exclude_devices)
491
+ db, lc, hutch, load_level=load_level, exclude_devices=exclude_devices, additional_devices=additional_devices)
479
492
  cache(**happi_objs)
480
493
 
481
494
  # create and store beampath
@@ -583,10 +596,12 @@ def load_conf(conf, hutch_dir=None, args=None):
583
596
  path.mkdir()
584
597
  path.chmod(0o777)
585
598
  if experiment is None:
586
- setup_preset_paths(hutch=beamline_presets)
599
+ setup_preset_paths(hutch=beamline_presets,
600
+ defer_loading=True)
587
601
  else:
588
602
  setup_preset_paths(hutch=beamline_presets,
589
- exp=experiment_presets)
603
+ exp=experiment_presets,
604
+ defer_loading=True)
590
605
 
591
606
  # configure objects
592
607
  if obj_config is not None:
@@ -75,6 +75,7 @@ def test_create_arg():
75
75
  if test_dir.exists():
76
76
  shutil.rmtree(test_dir)
77
77
 
78
+ # Needs manual confirmation if we run with capture output on...
78
79
  with cli_args(['hutch_python', '--create', hutch]):
79
80
  with restore_logging():
80
81
  main()
@@ -96,11 +97,9 @@ def run_hpy_and_exit(*args: str) -> subprocess.CompletedProcess:
96
97
 
97
98
 
98
99
  @pytest.mark.timeout(30)
99
- def test_hist_file_arg(monkeypatch):
100
+ def test_hist_file_arg():
100
101
  logger.debug("test_hist_file_arg")
101
102
  test_hist_file = (CFG_PATH.parent / "history.sqlite").resolve()
102
- bad_hist_file = (CFG_PATH.parent / "aesefiudh" / "history.sqlite").resolve()
103
- memory_hist_filename = ":memory:"
104
103
 
105
104
  # Test that the sqlite file gets made
106
105
  # First, need to remove the file if it already exists
@@ -113,17 +112,27 @@ def test_hist_file_arg(monkeypatch):
113
112
  assert test_hist_file.exists()
114
113
  # Remove the file for future tests
115
114
  test_hist_file.unlink()
116
- # With the bad hist file we should still run ok with just a warning
117
- run_hpy_and_exit("--hist-file", str(bad_hist_file))
118
115
  assert not test_hist_file.exists()
119
- # Same with the in-memory choice
120
- run_hpy_and_exit("--hist-file", memory_hist_filename)
116
+
117
+
118
+ @pytest.mark.timeout(30)
119
+ @pytest.mark.parametrize("filepath,", (
120
+ (CFG_PATH.parent / "aesefiudh" / "history.sqlite").resolve(),
121
+ ":memory:",
122
+ ))
123
+ def test_no_hist_file(filepath):
124
+ # With the bad hist file or memory we should still run ok with just a warning
125
+ test_hist_file = (CFG_PATH.parent / "history.sqlite").resolve()
126
+ run_hpy_and_exit("--hist-file", str(filepath))
121
127
  assert not test_hist_file.exists()
122
128
 
129
+
130
+ @pytest.mark.timeout(30)
131
+ def test_template_file(monkeypatch):
123
132
  # Exercise the template + check default usage
124
133
  # We can't actually write to the default default in a test context
125
134
  # But we can check what the config would be
126
- new_default = str(test_hist_file.parent / "${USER}-history.sqlite")
135
+ new_default = str(CFG_PATH.parent / "${USER}-history.sqlite")
127
136
  new_default_filled = Template(new_default).substitute({"USER": os.environ["USER"]})
128
137
  monkeypatch.setattr(
129
138
  hutch_python.cli,
@@ -160,7 +169,8 @@ def test_ipython_tab_completion():
160
169
  # us.
161
170
  hutch_python.cli.configure_ipython_session(HutchPythonArgs())
162
171
 
163
- completer = IPython.core.completer.Completer(namespace=ns)
172
+ completer = IPython.core.completer.IPCompleter(namespace=ns)
164
173
  completer.limit_to__all__ = False
174
+ completer.line_buffer = "a."
165
175
  assert 'a.THIS_SHOULD_NOT_BE_THERE' not in completer.attr_matches('a.')
166
176
  assert completer.attr_matches('a.') == ['a.foobar']
@@ -78,9 +78,70 @@ def test_happi_objs_with_exclude_devices():
78
78
  assert len(objs) == 4
79
79
 
80
80
  # Call get_happi_objs() with exclude_devices
81
- objs_exclude_devices = get_happi_objs(db, lc, 'tst', DeviceLoadLevel.STANDARD, exclude_devices)
81
+ objs_exclude_devices = get_happi_objs(
82
+ db, lc, 'tst', DeviceLoadLevel.STANDARD, exclude_devices=exclude_devices)
82
83
  assert len(objs_exclude_devices) == 2
83
84
 
84
85
  # Check that none of the loaded devices are in the exclude_devices list
85
86
  for obj in objs_exclude_devices:
86
87
  assert obj not in exclude_devices
88
+
89
+
90
+ # Test ability to add additional devices using multiple happi search criteria
91
+ @conftest.requires_lightpath
92
+ def test_happi_objs_with_additional_devices_using_multiple_search_criteria():
93
+ # Check if the user can load additional devices generated by happi's
94
+ # search_parser() function. This test checks for cases where multiple
95
+ # search criteria are passed to search_parser(). For comparison,
96
+ # get_happi_objs() is first called without the 'additional_devices'
97
+ # variable and then called again with 'additional_devices'.
98
+
99
+ additional_devices = {
100
+ 'beamline_test': {'beamline': 'ZZZ'},
101
+ 'tst_device_3_test': {'name': 'tst_device_3'}
102
+ }
103
+
104
+ logger.debug("test_happi_objs")
105
+ db = os.path.join(os.path.abspath(os.path.dirname(__file__)),
106
+ 'happi_db.json')
107
+ # Only select active objects
108
+ lc = get_lightpath(db, 'tst')
109
+
110
+ # Call get_happi_objs() without additional_devices
111
+ objs = get_happi_objs(db, lc, 'tst', DeviceLoadLevel.STANDARD)
112
+ assert len(objs) == 4
113
+
114
+ # Call get_happi_objs() with additional_devices
115
+ objs_additional_devices = get_happi_objs(
116
+ db, lc, 'tst', DeviceLoadLevel.STANDARD, additional_devices=additional_devices)
117
+
118
+ # Check that the loaded devices include additional_devices
119
+ assert len(objs_additional_devices) == 6
120
+
121
+
122
+ # Test ability to add additional devices using happi search with globs
123
+ @conftest.requires_lightpath
124
+ def test_happi_objs_with_additional_devices_using_globs():
125
+ # This test checks for cases where a search criterion with globs is passed
126
+ # to happi's search_parser(). For comparison, get_happi_objs() is first
127
+ # called without the 'additional_devices' variable and then called again
128
+ # with 'additional_devices'.
129
+
130
+ additional_devices = {'globs_test': {'name': 'tst_device_*'}}
131
+
132
+ logger.debug("test_happi_objs")
133
+ db = os.path.join(os.path.abspath(os.path.dirname(__file__)),
134
+ 'happi_db.json')
135
+ # Only select active objects
136
+ lc = get_lightpath(db, 'tst')
137
+
138
+ # Call get_happi_objs() without additional_devices
139
+ objs = get_happi_objs(db, lc, 'tst', DeviceLoadLevel.STANDARD)
140
+ assert len(objs) == 4
141
+
142
+ # Call get_happi_objs() with additional_devices
143
+ objs_additional_devices = get_happi_objs(
144
+ db, lc, 'tst', DeviceLoadLevel.STANDARD, additional_devices=additional_devices)
145
+
146
+ # Check that the loaded devices include additional_devices
147
+ assert len(objs_additional_devices) == 6
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.4
2
2
  Name: hutch-python
3
- Version: 1.22.0
3
+ Version: 1.23.1
4
4
  Summary: Launcher and Config Reader for LCLS Interactive IPython Sessions
5
5
  Author: SLAC National Accelerator Laboratory
6
6
  License: Copyright (c) 2023, The Board of Trustees of the Leland Stanford Junior
@@ -55,14 +55,14 @@ Requires-Dist: bluesky>=1.8.0
55
55
  Requires-Dist: coloredlogs>=15.0.0
56
56
  Requires-Dist: cookiecutter>=1.7.0
57
57
  Requires-Dist: happi>=1.9.0
58
- Requires-Dist: ipython>=7.26.0
58
+ Requires-Dist: ipython<9.0.0
59
59
  Requires-Dist: jinja2>=2.11.0
60
60
  Requires-Dist: lightpath>=1.0.1
61
61
  Requires-Dist: matplotlib>=3.4.0
62
62
  Requires-Dist: nabs>=1.5.0
63
63
  Requires-Dist: pcdscalc>=0.6.0
64
64
  Requires-Dist: pcdsdaq>=2.3.0
65
- Requires-Dist: pcdsdevices>=7.0.0
65
+ Requires-Dist: pcdsdevices>8.7.0
66
66
  Requires-Dist: pcdsutils>=0.5.0
67
67
  Requires-Dist: psdaq-control-minimal
68
68
  Requires-Dist: pyfiglet>=0.8.0
@@ -83,7 +83,7 @@ Requires-Dist: sphinx; extra == "doc"
83
83
  Requires-Dist: sphinx_rtd_theme; extra == "doc"
84
84
  Requires-Dist: sphinxcontrib-jquery; extra == "doc"
85
85
  Requires-Dist: pypandoc; extra == "doc"
86
- Requires-Dist: numpy<2; extra == "doc"
86
+ Dynamic: license-file
87
87
 
88
88
  ============
89
89
  Hutch Python
@@ -14,6 +14,7 @@ dev-requirements.txt
14
14
  docs-requirements.txt
15
15
  pyproject.toml
16
16
  requirements.txt
17
+ .github/CODEOWNERS
17
18
  .github/ISSUE_TEMPLATE.md
18
19
  .github/PULL_REQUEST_TEMPLATE.md
19
20
  .github/workflows/standard.yml
@@ -3,14 +3,14 @@ bluesky>=1.8.0
3
3
  coloredlogs>=15.0.0
4
4
  cookiecutter>=1.7.0
5
5
  happi>=1.9.0
6
- ipython>=7.26.0
6
+ ipython<9.0.0
7
7
  jinja2>=2.11.0
8
8
  lightpath>=1.0.1
9
9
  matplotlib>=3.4.0
10
10
  nabs>=1.5.0
11
11
  pcdscalc>=0.6.0
12
12
  pcdsdaq>=2.3.0
13
- pcdsdevices>=7.0.0
13
+ pcdsdevices>8.7.0
14
14
  pcdsutils>=0.5.0
15
15
  psdaq-control-minimal
16
16
  pyfiglet>=0.8.0
@@ -27,7 +27,6 @@ sphinx
27
27
  sphinx_rtd_theme
28
28
  sphinxcontrib-jquery
29
29
  pypandoc
30
- numpy<2
31
30
 
32
31
  [test]
33
32
  lightpath
@@ -3,14 +3,14 @@ bluesky>=1.8.0
3
3
  coloredlogs>=15.0.0
4
4
  cookiecutter>=1.7.0
5
5
  happi>=1.9.0
6
- ipython>=7.26.0
6
+ ipython<9.0.0
7
7
  jinja2>=2.11.0
8
8
  lightpath>=1.0.1
9
9
  matplotlib>=3.4.0
10
10
  nabs>=1.5.0
11
11
  pcdscalc>=0.6.0
12
12
  pcdsdaq>=2.3.0
13
- pcdsdevices>=7.0.0
13
+ pcdsdevices>8.7.0
14
14
  pcdsutils>=0.5.0
15
15
  psdaq-control-minimal
16
16
  pyfiglet>=0.8.0
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes