hutch-python 1.19.0__tar.gz → 1.20.0__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.
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.gitignore +3 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/PKG-INFO +1 -1
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/releases.rst +17 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/_version.py +2 -2
- hutch_python-1.20.0/hutch_python/cli.py +236 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_cli.py +56 -2
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python.egg-info/PKG-INFO +1 -1
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python.egg-info/SOURCES.txt +0 -1
- hutch_python-1.19.0/docs/source/upcoming_release_notes/379-enh_limit_devices.rst +0 -22
- hutch_python-1.19.0/hutch_python/cli.py +0 -184
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.coveragerc +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.flake8 +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.git_archival.txt +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.gitattributes +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.github/ISSUE_TEMPLATE.md +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.github/PULL_REQUEST_TEMPLATE.md +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.github/workflows/standard.yml +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.landscape.yml +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/.pre-commit-config.yaml +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/AUTHORS.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/CONTRIBUTING.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/LICENSE +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/MANIFEST.in +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/README.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/bin/hutch-python +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/conda-recipe/meta.yaml +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/dev-requirements.txt +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/Makefile +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/pre-release-notes.sh +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/release_notes.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/beamline.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/bug.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/cache.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/cli.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/conf.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/daq.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/database.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/debug.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/environment.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/experiment.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/hutch_setup.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/index.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/ipython_log.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/load_conf.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/load_parts.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/log_setup.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/namespace.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/object_configuration.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/other_modules.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/presets.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/report.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/start.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/startup.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/tips.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/tutorial.ipynb +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/upcoming_release_notes/template-full.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/upcoming_release_notes/template-short.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/user_utils.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/utils.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/yaml_files.rst +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/docs-requirements.txt +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/__init__.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/__main__.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/bug.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cache.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/calc_defaults.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cam_load.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/constants.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/cookiecutter.json +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/.gitignore +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/README.md +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/conf.yml +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/experiments/__init__.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/set-dev +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}/__init__.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}/beamline.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}env +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/cookiecutter/{{ cookiecutter.hutch }}/{{ cookiecutter.hutch }}python +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/debug.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/env_version.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/epics_arch.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/exp_load.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/happi.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/ipython_log.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/lcls.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/load_conf.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/log_setup.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/logging.yml +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/mpl_config.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/namespace.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/obj_config.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/ophyd_settings.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/options.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/plan_defaults.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/plan_wrappers.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/print_hint_banner.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/pt_app_config.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/qs_load.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/sim.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/startup_script.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/templates/issue.template +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/__init__.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/bad_script.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/camviewer.cfg +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/conf.yaml +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/conftest.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/envs/pcds-1.0.0 +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/envs/pcds-2.0.0 +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/envs/z-env +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/experiments/sample_expname.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/experiments/x010.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/experiments/x011.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/happi_db.json +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/sample_module_1.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/sample_module_2.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/script.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_bug.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_cache.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_cam_load.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_epics_arch.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_experiment.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_happi.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_ipython_log.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_load_conf.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_log_setup.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_namespace.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_obj_config.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_plan_wrappers.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_questionnaire.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_tstpython.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_user_load.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/test_utils.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/tst/__init__.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/tst/beamline.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/tstpython +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/user_load.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/utils.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/version.py +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python.egg-info/dependency_links.txt +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python.egg-info/entry_points.txt +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python.egg-info/requires.txt +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python.egg-info/top_level.txt +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/pyproject.toml +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/requirements.txt +0 -0
- {hutch_python-1.19.0 → hutch_python-1.20.0}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: hutch-python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.20.0
|
|
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
|
|
@@ -2,6 +2,23 @@ Release History
|
|
|
2
2
|
###############
|
|
3
3
|
|
|
4
4
|
|
|
5
|
+
v1.20.0 (2024-04-19)
|
|
6
|
+
====================
|
|
7
|
+
|
|
8
|
+
Features
|
|
9
|
+
--------
|
|
10
|
+
- Allow per-session separate ipython histories via ``--hist-file``
|
|
11
|
+
command-line argument. If omitted, default ipython behavior is used.
|
|
12
|
+
When ``--hist-file`` is included with no argument, the history file
|
|
13
|
+
will be written a local operator console hard drive, if available.
|
|
14
|
+
An argument can be provided to use any file as the history.sqlite file.
|
|
15
|
+
|
|
16
|
+
Contributors
|
|
17
|
+
------------
|
|
18
|
+
- zllentz
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
5
22
|
v1.19.0 (2024-04-15)
|
|
6
23
|
====================
|
|
7
24
|
|
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
"""
|
|
2
|
+
This module defines the command-line interface arguments for the
|
|
3
|
+
``hutch-python`` script. It also provides utilities that are only used at
|
|
4
|
+
startup.
|
|
5
|
+
"""
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import argparse
|
|
9
|
+
import dataclasses
|
|
10
|
+
import logging
|
|
11
|
+
import os
|
|
12
|
+
import sys
|
|
13
|
+
from pathlib import Path
|
|
14
|
+
from string import Template
|
|
15
|
+
|
|
16
|
+
import IPython
|
|
17
|
+
import matplotlib
|
|
18
|
+
from cookiecutter.main import cookiecutter
|
|
19
|
+
from IPython import start_ipython
|
|
20
|
+
from traitlets.config import Config
|
|
21
|
+
|
|
22
|
+
from .constants import CONDA_BASE, DIR_MODULE
|
|
23
|
+
from .env_version import log_env
|
|
24
|
+
from .load_conf import load
|
|
25
|
+
from .log_setup import configure_log_directory, debug_mode, setup_logging
|
|
26
|
+
|
|
27
|
+
logger = logging.getLogger(__name__)
|
|
28
|
+
opts_cache = {}
|
|
29
|
+
DEFAULT_HISTFILE = "/u1/${USER}/hutch-python/history.sqlite"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
# Define the parser
|
|
33
|
+
def get_parser() -> argparse.ArgumentParser:
|
|
34
|
+
parser = argparse.ArgumentParser(prog="hutch-python",
|
|
35
|
+
description="Launch LCLS Hutch Python")
|
|
36
|
+
parser.add_argument("--cfg", required=False, default=None,
|
|
37
|
+
help="Configuration yaml file")
|
|
38
|
+
parser.add_argument("--exp", required=False, default=None,
|
|
39
|
+
help="Experiment number override")
|
|
40
|
+
parser.add_argument("--debug", action="store_true", default=False,
|
|
41
|
+
help="Start in debug mode")
|
|
42
|
+
parser.add_argument("--sim", action="store_true", default=False,
|
|
43
|
+
help="Run with simulated DAQ (lcls1 only)")
|
|
44
|
+
parser.add_argument("--create", action="store", default=False,
|
|
45
|
+
help="Create a new hutch deployment")
|
|
46
|
+
parser.add_argument("--hist-file", nargs="?", action="store",
|
|
47
|
+
default=None, const=DEFAULT_HISTFILE,
|
|
48
|
+
help=(
|
|
49
|
+
"File to store the sqlite session history in. "
|
|
50
|
+
"${VARIABLES} will be substituted for "
|
|
51
|
+
"via shell environment variables, "
|
|
52
|
+
"Though in some cases these may be expanded by the shell "
|
|
53
|
+
"prior to reaching the python layer. "
|
|
54
|
+
"If omitted, defaults to the ipython default location. "
|
|
55
|
+
"If included but left blank, defaults to "
|
|
56
|
+
f"{DEFAULT_HISTFILE} "
|
|
57
|
+
"if the folder exists, "
|
|
58
|
+
"otherwise uses the ipython default location. "
|
|
59
|
+
"This folder is a local hard-drive location for lcls "
|
|
60
|
+
"operator consoles."
|
|
61
|
+
))
|
|
62
|
+
parser.add_argument("script", nargs="?",
|
|
63
|
+
help="Run a script instead of running interactively")
|
|
64
|
+
return parser
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
parser = get_parser()
|
|
68
|
+
|
|
69
|
+
# Append to module docs
|
|
70
|
+
__doc__ += "\n::\n\n " + parser.format_help().replace("\n", "\n ")
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@dataclasses.dataclass
|
|
74
|
+
class HutchPythonArgs:
|
|
75
|
+
cfg: str | None = None
|
|
76
|
+
exp: str | None = None
|
|
77
|
+
debug: bool = False
|
|
78
|
+
sim: bool = False
|
|
79
|
+
create: bool = False
|
|
80
|
+
hist_file: str | None = None
|
|
81
|
+
script: str | None = None
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def configure_tab_completion(ipy_config):
|
|
85
|
+
"""
|
|
86
|
+
Disable Jedi and tweak IPython tab completion.
|
|
87
|
+
|
|
88
|
+
Parameters
|
|
89
|
+
----------
|
|
90
|
+
ipy_config : traitlets.config.Config
|
|
91
|
+
IPython configuration.
|
|
92
|
+
"""
|
|
93
|
+
# Old API for disabling Jedi. Keep in just in case API changes back.
|
|
94
|
+
ipy_config.InteractiveShellApp.Completer.use_jedi = False
|
|
95
|
+
# New API for disabling Jedi (two access points documented, use both)
|
|
96
|
+
ipy_config.Completer.use_jedi = False
|
|
97
|
+
ipy_config.IPCompleter.use_jedi = False
|
|
98
|
+
try:
|
|
99
|
+
# Monkeypatch IPython completion - we need it to respect __dir__
|
|
100
|
+
# when Jedi is disabled.
|
|
101
|
+
# Details: https://github.com/pcdshub/pcdsdevices/issues/709
|
|
102
|
+
# First, access it to see that the internals have not changed:
|
|
103
|
+
IPython.core.completer.dir2
|
|
104
|
+
except AttributeError:
|
|
105
|
+
logger.debug("Looks like the IPython API changed!")
|
|
106
|
+
else:
|
|
107
|
+
# Then monkeypatch it in:
|
|
108
|
+
IPython.core.completer.dir2 = dir
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def configure_ipython_session(args: HutchPythonArgs):
|
|
112
|
+
"""
|
|
113
|
+
Configure a new IPython session.
|
|
114
|
+
|
|
115
|
+
Returns
|
|
116
|
+
-------
|
|
117
|
+
ipy_config : traitlets.config.Config
|
|
118
|
+
IPython configuration.
|
|
119
|
+
"""
|
|
120
|
+
ipy_config = Config()
|
|
121
|
+
# Important Utilities
|
|
122
|
+
ipy_config.InteractiveShellApp.extensions = [
|
|
123
|
+
"hutch_python.ipython_log",
|
|
124
|
+
"hutch_python.bug",
|
|
125
|
+
"hutch_python.pt_app_config"
|
|
126
|
+
]
|
|
127
|
+
# Matplotlib setup for ipython (automatically do %matplotlib)
|
|
128
|
+
backend = matplotlib.get_backend().replace("Agg", "").lower()
|
|
129
|
+
ipy_config.InteractiveShellApp.matplotlib = backend
|
|
130
|
+
if backend == "agg":
|
|
131
|
+
logger.warning("No matplotlib rendering available. "
|
|
132
|
+
"Methods that create plots will not "
|
|
133
|
+
"function properly.")
|
|
134
|
+
|
|
135
|
+
# Disable reformatting input with black
|
|
136
|
+
ipy_config.TerminalInteractiveShell.autoformatter = None
|
|
137
|
+
# Set up tab completion modifications
|
|
138
|
+
configure_tab_completion(ipy_config)
|
|
139
|
+
|
|
140
|
+
# disable default banner
|
|
141
|
+
ipy_config.TerminalIPythonApp.display_banner = False
|
|
142
|
+
|
|
143
|
+
# Run startup hook code, print banner after startup hook files
|
|
144
|
+
files = [
|
|
145
|
+
str(DIR_MODULE / "startup_script.py"),
|
|
146
|
+
str(DIR_MODULE / "print_hint_banner.py"),
|
|
147
|
+
]
|
|
148
|
+
ipy_config.InteractiveShellApp.exec_files = files
|
|
149
|
+
|
|
150
|
+
# Custom history file with sensible non-NFS default for opr accounts
|
|
151
|
+
if args.hist_file is not None:
|
|
152
|
+
hist_file = Template(args.hist_file).safe_substitute(os.environ)
|
|
153
|
+
if hist_file == ":memory:" or Path(hist_file).parent.exists():
|
|
154
|
+
ipy_config.HistoryManager.hist_file = hist_file
|
|
155
|
+
else:
|
|
156
|
+
msg = f"No such directory for history file {hist_file}, using ipython default instead."
|
|
157
|
+
if args.hist_file == DEFAULT_HISTFILE:
|
|
158
|
+
# We expect this to be missing for non-opr users
|
|
159
|
+
logger.debug(msg)
|
|
160
|
+
else:
|
|
161
|
+
# You specified a file, so we need to warn about this
|
|
162
|
+
logger.warning(msg)
|
|
163
|
+
|
|
164
|
+
return ipy_config
|
|
165
|
+
|
|
166
|
+
|
|
167
|
+
def main():
|
|
168
|
+
"""
|
|
169
|
+
Do the full hutch-python launch sequence.
|
|
170
|
+
|
|
171
|
+
Parses the user's cli arguments and distributes them as needed to the
|
|
172
|
+
setup functions.
|
|
173
|
+
"""
|
|
174
|
+
# Parse the user's arguments
|
|
175
|
+
args = parser.parse_args(namespace=HutchPythonArgs())
|
|
176
|
+
|
|
177
|
+
# Set up logging first
|
|
178
|
+
if args.cfg is None:
|
|
179
|
+
log_dir = None
|
|
180
|
+
else:
|
|
181
|
+
log_dir = os.path.join(os.path.dirname(args.cfg), "logs")
|
|
182
|
+
|
|
183
|
+
configure_log_directory(log_dir)
|
|
184
|
+
setup_logging()
|
|
185
|
+
|
|
186
|
+
# Debug mode next
|
|
187
|
+
if args.debug:
|
|
188
|
+
debug_mode(True)
|
|
189
|
+
|
|
190
|
+
# Do the first log message, now that logging is ready
|
|
191
|
+
logger.debug("cli starting with args %s", args)
|
|
192
|
+
|
|
193
|
+
# Check and display the environment info as appropriate (very early)
|
|
194
|
+
log_env()
|
|
195
|
+
|
|
196
|
+
# Options that mean skipping the python environment
|
|
197
|
+
if args.create:
|
|
198
|
+
hutch = args.create
|
|
199
|
+
envs_dir = CONDA_BASE / "envs"
|
|
200
|
+
if envs_dir.exists():
|
|
201
|
+
# Pick most recent pcds release in our common env
|
|
202
|
+
base = str(CONDA_BASE)
|
|
203
|
+
path_obj = sorted(envs_dir.glob("pcds-*"))[-1]
|
|
204
|
+
env = path_obj.name
|
|
205
|
+
else:
|
|
206
|
+
# Fallback: pick current env
|
|
207
|
+
try:
|
|
208
|
+
base = str(Path(os.environ["CONDA_EXE"]).parent.parent)
|
|
209
|
+
env = os.environ["CONDA_DEFAULT_ENV"]
|
|
210
|
+
except KeyError:
|
|
211
|
+
# Take a stab at some non-conda defaults; ideally these would
|
|
212
|
+
# be configurable with argparse.
|
|
213
|
+
base = str(Path(sys.executable).parent)
|
|
214
|
+
env = hutch
|
|
215
|
+
logger.info(("Creating hutch-python dir for hutch %s using"
|
|
216
|
+
" base=%s env=%s"), hutch, base, env)
|
|
217
|
+
cookiecutter(str(DIR_MODULE / "cookiecutter"), no_input=True,
|
|
218
|
+
extra_context=dict(base=base, env=env, hutch=hutch))
|
|
219
|
+
return
|
|
220
|
+
|
|
221
|
+
# Save whether we are an interactive session or a script session
|
|
222
|
+
opts_cache["script"] = args.script
|
|
223
|
+
|
|
224
|
+
# Load objects based on the configuration file
|
|
225
|
+
objs = load(cfg=args.cfg, args=args)
|
|
226
|
+
|
|
227
|
+
script = opts_cache.get("script")
|
|
228
|
+
if script is None:
|
|
229
|
+
# Finally start the interactive session
|
|
230
|
+
start_ipython(argv=["--quick"], user_ns=objs,
|
|
231
|
+
config=configure_ipython_session(args))
|
|
232
|
+
else:
|
|
233
|
+
# Instead of setting up ipython, run the script with objs
|
|
234
|
+
with open(script) as fn:
|
|
235
|
+
code = compile(fn.read(), script, "exec")
|
|
236
|
+
exec(code, objs, objs)
|
|
@@ -1,14 +1,18 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
import os
|
|
3
3
|
import shutil
|
|
4
|
+
import subprocess
|
|
5
|
+
import sys
|
|
4
6
|
from pathlib import Path
|
|
7
|
+
from string import Template
|
|
5
8
|
|
|
6
9
|
import IPython.core.completer
|
|
7
10
|
import pytest
|
|
8
11
|
from conftest import cli_args, restore_logging
|
|
9
12
|
|
|
10
13
|
import hutch_python.cli
|
|
11
|
-
from hutch_python.cli import
|
|
14
|
+
from hutch_python.cli import (HutchPythonArgs, configure_ipython_session,
|
|
15
|
+
get_parser, main)
|
|
12
16
|
from hutch_python.load_conf import load
|
|
13
17
|
|
|
14
18
|
from .conftest import skip_if_win32_generic
|
|
@@ -80,6 +84,56 @@ def test_create_arg():
|
|
|
80
84
|
shutil.rmtree(test_dir)
|
|
81
85
|
|
|
82
86
|
|
|
87
|
+
def run_hpy_and_exit(*args: str) -> subprocess.CompletedProcess:
|
|
88
|
+
return subprocess.run(
|
|
89
|
+
[sys.executable, "-m", "hutch_python"] + list(args),
|
|
90
|
+
input="exit\n",
|
|
91
|
+
universal_newlines=True,
|
|
92
|
+
capture_output=True,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
@pytest.mark.timeout(30)
|
|
97
|
+
def test_hist_file_arg(monkeypatch):
|
|
98
|
+
logger.debug("test_hist_file_arg")
|
|
99
|
+
test_hist_file = (CFG_PATH.parent / "history.sqlite").resolve()
|
|
100
|
+
bad_hist_file = (CFG_PATH.parent / "aesefiudh" / "history.sqlite").resolve()
|
|
101
|
+
memory_hist_filename = ":memory:"
|
|
102
|
+
|
|
103
|
+
# Test that the sqlite file gets made
|
|
104
|
+
# First, need to remove the file if it already exists
|
|
105
|
+
if test_hist_file.exists():
|
|
106
|
+
test_hist_file.unlink()
|
|
107
|
+
|
|
108
|
+
# Run with the good arg and exit
|
|
109
|
+
run_hpy_and_exit("--hist-file", str(test_hist_file))
|
|
110
|
+
# Was the history file created?
|
|
111
|
+
assert test_hist_file.exists()
|
|
112
|
+
# Remove the file for future tests
|
|
113
|
+
test_hist_file.unlink()
|
|
114
|
+
# With the bad hist file we should still run ok with just a warning
|
|
115
|
+
run_hpy_and_exit("--hist-file", str(bad_hist_file))
|
|
116
|
+
assert not test_hist_file.exists()
|
|
117
|
+
# Same with the in-memory choice
|
|
118
|
+
run_hpy_and_exit("--hist-file", memory_hist_filename)
|
|
119
|
+
assert not test_hist_file.exists()
|
|
120
|
+
|
|
121
|
+
# Exercise the template + check default usage
|
|
122
|
+
# We can't actually write to the default default in a test context
|
|
123
|
+
# But we can check what the config would be
|
|
124
|
+
new_default = str(test_hist_file.parent / "${USER}-history.sqlite")
|
|
125
|
+
new_default_filled = Template(new_default).substitute({"USER": os.environ["USER"]})
|
|
126
|
+
monkeypatch.setattr(
|
|
127
|
+
hutch_python.cli,
|
|
128
|
+
"DEFAULT_HISTFILE",
|
|
129
|
+
new_default,
|
|
130
|
+
)
|
|
131
|
+
parser = get_parser()
|
|
132
|
+
args = parser.parse_args(["--hist-file"], namespace=HutchPythonArgs())
|
|
133
|
+
ipy_config = configure_ipython_session(args)
|
|
134
|
+
assert ipy_config.HistoryManager.hist_file == new_default_filled
|
|
135
|
+
|
|
136
|
+
|
|
83
137
|
@skip_if_win32_generic
|
|
84
138
|
def test_run_script():
|
|
85
139
|
logger.debug('test_run_script')
|
|
@@ -102,7 +156,7 @@ def test_ipython_tab_completion():
|
|
|
102
156
|
|
|
103
157
|
# Side-effect of the following is monkey-patching `dir2` to "fix" this for
|
|
104
158
|
# us.
|
|
105
|
-
hutch_python.cli.configure_ipython_session()
|
|
159
|
+
hutch_python.cli.configure_ipython_session(HutchPythonArgs())
|
|
106
160
|
|
|
107
161
|
completer = IPython.core.completer.Completer(namespace=ns)
|
|
108
162
|
completer.limit_to__all__ = False
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: hutch-python
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.20.0
|
|
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
|
|
@@ -51,7 +51,6 @@ docs/source/tutorial.ipynb
|
|
|
51
51
|
docs/source/user_utils.rst
|
|
52
52
|
docs/source/utils.rst
|
|
53
53
|
docs/source/yaml_files.rst
|
|
54
|
-
docs/source/upcoming_release_notes/379-enh_limit_devices.rst
|
|
55
54
|
docs/source/upcoming_release_notes/template-full.rst
|
|
56
55
|
docs/source/upcoming_release_notes/template-short.rst
|
|
57
56
|
hutch_python/__init__.py
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
379 enh_limit_devices
|
|
2
|
-
#####################
|
|
3
|
-
|
|
4
|
-
API Changes
|
|
5
|
-
-----------
|
|
6
|
-
- N/A
|
|
7
|
-
|
|
8
|
-
Features
|
|
9
|
-
--------
|
|
10
|
-
- Adds load_level conf.yaml key for choosing the method used to gather happi devices
|
|
11
|
-
|
|
12
|
-
Bugfixes
|
|
13
|
-
--------
|
|
14
|
-
- N/A
|
|
15
|
-
|
|
16
|
-
Maintenance
|
|
17
|
-
-----------
|
|
18
|
-
- N/A
|
|
19
|
-
|
|
20
|
-
Contributors
|
|
21
|
-
------------
|
|
22
|
-
- tangkong
|
|
@@ -1,184 +0,0 @@
|
|
|
1
|
-
"""
|
|
2
|
-
This module defines the command-line interface arguments for the
|
|
3
|
-
``hutch-python`` script. It also provides utilities that are only used at
|
|
4
|
-
startup.
|
|
5
|
-
"""
|
|
6
|
-
import argparse
|
|
7
|
-
import logging
|
|
8
|
-
import os
|
|
9
|
-
import sys
|
|
10
|
-
from pathlib import Path
|
|
11
|
-
|
|
12
|
-
import IPython
|
|
13
|
-
import matplotlib
|
|
14
|
-
from cookiecutter.main import cookiecutter
|
|
15
|
-
from IPython import start_ipython
|
|
16
|
-
from traitlets.config import Config
|
|
17
|
-
|
|
18
|
-
from .constants import CONDA_BASE, DIR_MODULE
|
|
19
|
-
from .env_version import log_env
|
|
20
|
-
from .load_conf import load
|
|
21
|
-
from .log_setup import configure_log_directory, debug_mode, setup_logging
|
|
22
|
-
|
|
23
|
-
logger = logging.getLogger(__name__)
|
|
24
|
-
opts_cache = {}
|
|
25
|
-
|
|
26
|
-
# Define the parser
|
|
27
|
-
parser = argparse.ArgumentParser(prog='hutch-python',
|
|
28
|
-
description='Launch LCLS Hutch Python')
|
|
29
|
-
parser.add_argument('--cfg', required=False, default=None,
|
|
30
|
-
help='Configuration yaml file')
|
|
31
|
-
parser.add_argument('--exp', required=False, default=None,
|
|
32
|
-
help='Experiment number override')
|
|
33
|
-
parser.add_argument('--debug', action='store_true', default=False,
|
|
34
|
-
help='Start in debug mode')
|
|
35
|
-
parser.add_argument('--sim', action='store_true', default=False,
|
|
36
|
-
help='Run with simulated DAQ (lcls1 only)')
|
|
37
|
-
parser.add_argument('--create', action='store', default=False,
|
|
38
|
-
help='Create a new hutch deployment')
|
|
39
|
-
parser.add_argument('script', nargs='?',
|
|
40
|
-
help='Run a script instead of running interactively')
|
|
41
|
-
|
|
42
|
-
# Append to module docs
|
|
43
|
-
__doc__ += '\n::\n\n ' + parser.format_help().replace('\n', '\n ')
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
def configure_tab_completion(ipy_config):
|
|
47
|
-
"""
|
|
48
|
-
Disable Jedi and tweak IPython tab completion.
|
|
49
|
-
|
|
50
|
-
Parameters
|
|
51
|
-
----------
|
|
52
|
-
ipy_config : traitlets.config.Config
|
|
53
|
-
IPython configuration.
|
|
54
|
-
"""
|
|
55
|
-
# Old API for disabling Jedi. Keep in just in case API changes back.
|
|
56
|
-
ipy_config.InteractiveShellApp.Completer.use_jedi = False
|
|
57
|
-
# New API for disabling Jedi (two access points documented, use both)
|
|
58
|
-
ipy_config.Completer.use_jedi = False
|
|
59
|
-
ipy_config.IPCompleter.use_jedi = False
|
|
60
|
-
try:
|
|
61
|
-
# Monkeypatch IPython completion - we need it to respect __dir__
|
|
62
|
-
# when Jedi is disabled.
|
|
63
|
-
# Details: https://github.com/pcdshub/pcdsdevices/issues/709
|
|
64
|
-
# First, access it to see that the internals have not changed:
|
|
65
|
-
IPython.core.completer.dir2
|
|
66
|
-
except AttributeError:
|
|
67
|
-
logger.debug('Looks like the IPython API changed!')
|
|
68
|
-
else:
|
|
69
|
-
# Then monkeypatch it in:
|
|
70
|
-
IPython.core.completer.dir2 = dir
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
def configure_ipython_session():
|
|
74
|
-
"""
|
|
75
|
-
Configure a new IPython session.
|
|
76
|
-
|
|
77
|
-
Returns
|
|
78
|
-
-------
|
|
79
|
-
ipy_config : traitlets.config.Config
|
|
80
|
-
IPython configuration.
|
|
81
|
-
"""
|
|
82
|
-
ipy_config = Config()
|
|
83
|
-
# Important Utilities
|
|
84
|
-
ipy_config.InteractiveShellApp.extensions = [
|
|
85
|
-
'hutch_python.ipython_log',
|
|
86
|
-
'hutch_python.bug',
|
|
87
|
-
'hutch_python.pt_app_config'
|
|
88
|
-
]
|
|
89
|
-
# Matplotlib setup for ipython (automatically do %matplotlib)
|
|
90
|
-
backend = matplotlib.get_backend().replace('Agg', '').lower()
|
|
91
|
-
ipy_config.InteractiveShellApp.matplotlib = backend
|
|
92
|
-
if backend == 'agg':
|
|
93
|
-
logger.warning('No matplotlib rendering available. '
|
|
94
|
-
'Methods that create plots will not '
|
|
95
|
-
'function properly.')
|
|
96
|
-
|
|
97
|
-
# Disable reformatting input with black
|
|
98
|
-
ipy_config.TerminalInteractiveShell.autoformatter = None
|
|
99
|
-
# Set up tab completion modifications
|
|
100
|
-
configure_tab_completion(ipy_config)
|
|
101
|
-
|
|
102
|
-
# disable default banner
|
|
103
|
-
ipy_config.TerminalIPythonApp.display_banner = False
|
|
104
|
-
|
|
105
|
-
# Run startup hook code, print banner after startup hook files
|
|
106
|
-
files = [
|
|
107
|
-
str(DIR_MODULE / "startup_script.py"),
|
|
108
|
-
str(DIR_MODULE / "print_hint_banner.py"),
|
|
109
|
-
]
|
|
110
|
-
ipy_config.InteractiveShellApp.exec_files = files
|
|
111
|
-
|
|
112
|
-
return ipy_config
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
def main():
|
|
116
|
-
"""
|
|
117
|
-
Do the full hutch-python launch sequence.
|
|
118
|
-
|
|
119
|
-
Parses the user's cli arguments and distributes them as needed to the
|
|
120
|
-
setup functions.
|
|
121
|
-
"""
|
|
122
|
-
# Parse the user's arguments
|
|
123
|
-
args = parser.parse_args()
|
|
124
|
-
|
|
125
|
-
# Set up logging first
|
|
126
|
-
if args.cfg is None:
|
|
127
|
-
log_dir = None
|
|
128
|
-
else:
|
|
129
|
-
log_dir = os.path.join(os.path.dirname(args.cfg), 'logs')
|
|
130
|
-
|
|
131
|
-
configure_log_directory(log_dir)
|
|
132
|
-
setup_logging()
|
|
133
|
-
|
|
134
|
-
# Debug mode next
|
|
135
|
-
if args.debug:
|
|
136
|
-
debug_mode(True)
|
|
137
|
-
|
|
138
|
-
# Do the first log message, now that logging is ready
|
|
139
|
-
logger.debug('cli starting with args %s', args)
|
|
140
|
-
|
|
141
|
-
# Check and display the environment info as appropriate (very early)
|
|
142
|
-
log_env()
|
|
143
|
-
|
|
144
|
-
# Options that mean skipping the python environment
|
|
145
|
-
if args.create:
|
|
146
|
-
hutch = args.create
|
|
147
|
-
envs_dir = CONDA_BASE / 'envs'
|
|
148
|
-
if envs_dir.exists():
|
|
149
|
-
# Pick most recent pcds release in our common env
|
|
150
|
-
base = str(CONDA_BASE)
|
|
151
|
-
path_obj = sorted(envs_dir.glob('pcds-*'))[-1]
|
|
152
|
-
env = path_obj.name
|
|
153
|
-
else:
|
|
154
|
-
# Fallback: pick current env
|
|
155
|
-
try:
|
|
156
|
-
base = str(Path(os.environ['CONDA_EXE']).parent.parent)
|
|
157
|
-
env = os.environ['CONDA_DEFAULT_ENV']
|
|
158
|
-
except KeyError:
|
|
159
|
-
# Take a stab at some non-conda defaults; ideally these would
|
|
160
|
-
# be configurable with argparse.
|
|
161
|
-
base = str(Path(sys.executable).parent)
|
|
162
|
-
env = hutch
|
|
163
|
-
logger.info(('Creating hutch-python dir for hutch %s using'
|
|
164
|
-
' base=%s env=%s'), hutch, base, env)
|
|
165
|
-
cookiecutter(str(DIR_MODULE / 'cookiecutter'), no_input=True,
|
|
166
|
-
extra_context=dict(base=base, env=env, hutch=hutch))
|
|
167
|
-
return
|
|
168
|
-
|
|
169
|
-
# Save whether we are an interactive session or a script session
|
|
170
|
-
opts_cache['script'] = args.script
|
|
171
|
-
|
|
172
|
-
# Load objects based on the configuration file
|
|
173
|
-
objs = load(cfg=args.cfg, args=args)
|
|
174
|
-
|
|
175
|
-
script = opts_cache.get('script')
|
|
176
|
-
if script is None:
|
|
177
|
-
# Finally start the interactive session
|
|
178
|
-
start_ipython(argv=['--quick'], user_ns=objs,
|
|
179
|
-
config=configure_ipython_session())
|
|
180
|
-
else:
|
|
181
|
-
# Instead of setting up ipython, run the script with objs
|
|
182
|
-
with open(script) as fn:
|
|
183
|
-
code = compile(fn.read(), script, 'exec')
|
|
184
|
-
exec(code, objs, objs)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/upcoming_release_notes/template-full.rst
RENAMED
|
File without changes
|
{hutch_python-1.19.0 → hutch_python-1.20.0}/docs/source/upcoming_release_notes/template-short.rst
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{hutch_python-1.19.0 → hutch_python-1.20.0}/hutch_python/tests/experiments/sample_expname.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|