Skip to content

Commit 28f8fb4

Browse files
committed
First pass at importable package
1 parent e4c9967 commit 28f8fb4

File tree

12 files changed

+240
-225
lines changed

12 files changed

+240
-225
lines changed

LICENSE

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
BSD 3-Clause License
2+
3+
Copyright (c) 2024, ISIS Experiment Controls Computing
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice,
12+
this list of conditions and the following disclaimer in the documentation
13+
and/or other materials provided with the distribution.
14+
15+
3. Neither the name of the copyright holder nor the names of its
16+
contributors may be used to endorse or promote products derived from
17+
this software without specific prior written permission.
18+
19+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
20+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
23+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
25+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
26+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
27+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

pyproject.toml

Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
[build-system]
2+
requires = ["setuptools", "setuptools_scm>=8"]
3+
build-backend = "setuptools.build_meta"
4+
5+
6+
[project]
7+
name = "genie_python"
8+
dynamic = ["version"]
9+
description = "Instrument control & scripting for the ISIS Neutron & Muon source"
10+
readme = "README.md"
11+
requires-python = ">=3.11"
12+
license = {file = "LICENSE"}
13+
14+
authors = [
15+
{name = "ISIS Experiment Controls", email = "ISISExperimentControls@stfc.ac.uk" }
16+
]
17+
maintainers = [
18+
{name = "ISIS Experiment Controls", email = "ISISExperimentControls@stfc.ac.uk" }
19+
]
20+
21+
classifiers = [
22+
"Development Status :: 5 - Production/Stable",
23+
"Intended Audience :: Developers",
24+
"License :: OSI Approved :: BSD License",
25+
"Programming Language :: Python :: 3.11",
26+
]
27+
28+
dependencies = [
29+
# EPICS Channel access lib
30+
"CaChannel",
31+
# Caffi provides some EPICS CA definitions if CaChannel is falling back to using caffi backend
32+
# (not used if CaChannel._ca is available)
33+
"caffi",
34+
# Send log messages to graylog
35+
"graypy",
36+
# genie_python will install ipython completers
37+
"ipython",
38+
# Getting user details from database
39+
"mysql-connector-python",
40+
# Array support for CA calls
41+
"numpy",
42+
# EPICS PV access lib
43+
"p4p",
44+
# Used to find process by name to kill it
45+
"psutil",
46+
# For checking user scripts on g.load_script()
47+
"pylint",
48+
# For setting windows job-object flags
49+
"pywin32;platform_system=='Windows'",
50+
]
51+
52+
[project.optional-dependencies]
53+
54+
# Make plotting an optional dependency as:
55+
# - It fixes a *specific* matplotlib version
56+
# - It depends on a couple of heavyweight libs (py4j and tornado) that aren't necessary otherwise
57+
plot = [
58+
# When updating, check plotting works in GUI. Must keep pinned to a specific, tested version.
59+
"matplotlib==3.9.2",
60+
# Python <-> Java communication, to spawn matplotlib plots in GUI
61+
"py4j",
62+
# Tornado webserver used by custom backend
63+
"tornado",
64+
]
65+
66+
doc = [
67+
"sphinx",
68+
"sphinx_rtd_theme",
69+
"myst_parser",
70+
"sphinx-autobuild",
71+
]
72+
73+
dev = [
74+
"genie_python[plot,doc]",
75+
"mock",
76+
"parameterized",
77+
"pyhamcrest",
78+
"pyright",
79+
"ruff>=0.6",
80+
]
81+
82+
[project.urls]
83+
"Homepage" = "https://github.com/isiscomputinggroup/genie"
84+
"Bug Reports" = "https://github.com/isiscomputinggroup/genie/issues"
85+
"Source" = "https://github.com/isiscomputinggroup/genie"
86+
87+
[tool.pyright]
88+
include = ["src", "tests"]
89+
reportConstantRedefinition = true
90+
reportDeprecated = true
91+
reportInconsistentConstructor = true
92+
reportMissingParameterType = true
93+
reportMissingTypeArgument = true
94+
reportUnnecessaryCast = true
95+
reportUnnecessaryComparison = true
96+
reportUnnecessaryContains = true
97+
reportUnnecessaryIsInstance = true
98+
reportUntypedBaseClass = true
99+
reportUntypedClassDecorator = true
100+
reportUntypedFunctionDecorator = true
101+
102+
[tool.setuptools_scm]
103+
104+
[tool.build_sphinx]

ruff.toml

Lines changed: 3 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,8 @@
11
# Exclude a variety of commonly ignored directories.
22
exclude = [
3-
".bzr",
4-
".direnv",
5-
".eggs",
6-
".git",
7-
".git-rewrite",
8-
".hg",
9-
".ipynb_checkpoints",
10-
".mypy_cache",
11-
".nox",
12-
".pants.d",
13-
".pyenv",
14-
".pytest_cache",
15-
".pytype",
16-
".ruff_cache",
17-
".svn",
18-
".tox",
19-
".venv",
20-
".vscode",
21-
"__pypackages__",
22-
"_build",
23-
"buck-out",
24-
"build",
25-
"dist",
26-
"node_modules",
27-
"venv",
28-
"uk.ac.stfc.isis.ibex.opis",
3+
".pyi",
294
"snmp-mibs",
5+
"tests/test_scripts",
306
]
317

328
# Set the maximum line length to 100.
@@ -52,7 +28,7 @@ ignore = [
5228
"ANN401", # explicit ANY type is allowed
5329
]
5430
[lint.per-file-ignores]
55-
"{**/tests/**,/tests/**,**/*tests.py,tests/**,*tests.py,*test.py,**/*test.py,common_tests/**,**/test_modules**}" = [
31+
"tests/*" = [
5632
"N802",
5733
"D100",
5834
"D101",
@@ -64,9 +40,3 @@ ignore = [
6440
[lint.pydocstyle]
6541
# Use Google-style docstrings.
6642
convention = "google"
67-
68-
[format]
69-
quote-style = "double"
70-
indent-style = "space"
71-
docstring-code-format = true
72-
line-ending = "auto"

src/genie_python/genie_cachannel_wrapper.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,16 @@
1111
from typing import TYPE_CHECKING, Optional, Tuple, TypeVar
1212

1313
from CaChannel import CaChannel, CaChannelException, ca
14-
from CaChannel._ca import AlarmCondition, AlarmSeverity, dbf_type_to_DBR_STS, dbf_type_to_DBR_TIME
14+
15+
try:
16+
from CaChannel._ca import (
17+
AlarmCondition,
18+
AlarmSeverity,
19+
dbf_type_to_DBR_STS,
20+
dbf_type_to_DBR_TIME,
21+
)
22+
except ImportError:
23+
from caffi.ca import AlarmCondition, AlarmSeverity, dbf_type_to_DBR_STS, dbf_type_to_DBR_TIME
1524

1625
if TYPE_CHECKING:
1726
from genie_python.genie import PVValue
@@ -112,7 +121,13 @@ def installHandlers(chan: CaChannel) -> None: # noqa N802
112121
# callbacks CaChannel itself delays creation of the context, so if we just installed the
113122
# handlers now we would get a default non-preemptive CA context created.
114123
chan.poll()
115-
chan.replace_printf_handler(CaChannelWrapper.printfHandler)
124+
try:
125+
chan.replace_printf_handler(CaChannelWrapper.printfHandler)
126+
except AttributeError:
127+
# If we can't replace the printf handler, ignore that error - it is not crucial.
128+
# It probably means we are using default CaChannel, as opposed to ISIS' special build.
129+
# Cope with both cases.
130+
pass
116131
chan.add_exception_event(CaChannelWrapper.CAExceptionHandler)
117132

118133
# noinspection PyPep8Naming

src/genie_python/genie_dae.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
import numpy as np
1919
import numpy.typing as npt
2020
import psutil
21-
from CaChannel._ca import AlarmCondition, AlarmSeverity
21+
22+
try:
23+
from CaChannel._ca import AlarmCondition, AlarmSeverity
24+
except ImportError:
25+
from caffi.ca import AlarmCondition, AlarmSeverity
2226

2327
from genie_python.genie_cachannel_wrapper import CaChannelWrapper
2428
from genie_python.genie_change_cache import ChangeCache

src/genie_python/genie_plot.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,6 @@
33
from builtins import object, str
44
from functools import wraps
55

6-
import matplotlib.pyplot as pyplt
7-
86

97
def _plotting_func(func):
108
"""
@@ -16,6 +14,8 @@ def _plotting_func(func):
1614

1715
@wraps(func)
1816
def wrapper(*args, **kwargs):
17+
import matplotlib.pyplot as pyplt
18+
1919
was_interactive = pyplt.isinteractive()
2020
pyplt.ioff()
2121
result = func(*args, **kwargs)
@@ -29,6 +29,8 @@ def wrapper(*args, **kwargs):
2929
class SpectraPlot(object):
3030
@_plotting_func
3131
def __init__(self, api, spectrum, period, dist):
32+
import matplotlib.pyplot as pyplt
33+
3234
self.api = api
3335
self.spectra = []
3436
self.fig = pyplt.figure()

src/genie_python/genie_scisoft_plot.py

Lines changed: 0 additions & 84 deletions
This file was deleted.

src/genie_python/matplotlib_backend/ibex_websocket_backend.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -277,9 +277,7 @@ def pyplot_show(cls, *args, **kwargs):
277277
with IBEX_BACKEND_LOCK:
278278
WebAggApplication.initialize(port=_web_backend_port)
279279
worker_thread = threading.Thread(
280-
target=WebAggApplication.start,
281-
daemon=True,
282-
name="ibex_websocket_backend"
280+
target=WebAggApplication.start, daemon=True, name="ibex_websocket_backend"
283281
)
284282
worker_thread.start()
285283

0 commit comments

Comments
 (0)