Skip to content

Commit

Permalink
Merge Stable-0-46 to main as new beta (#109)
Browse files Browse the repository at this point in the history
* bumping 0.46.0-beta.0 to 0.46.0 for minor release

* [stable-0-46] Fixing a new mypy error

* [stable-0-46] Trying to fix issue with Pypi uploading with tags

* [stable-0-46] Prepare branch for merging back to main with new beta revision

---------

Co-authored-by: heevasti <[email protected]>
  • Loading branch information
heevasti and heevasti authored Oct 15, 2024
1 parent 928e984 commit 92ddc9a
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 11 deletions.
2 changes: 1 addition & 1 deletion .bumpversion.cfg
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
[bumpversion]
current_version = 0.46.0-beta.0
current_version = 0.47.0-beta.0
commit = False
tag = False
parse = (?P<major>\d+)\.(?P<minor>\d+)\.(?P<patch>\d+)(\-(?P<release>[a-z]+))?(\.(?P<build>\d+))?
Expand Down
6 changes: 3 additions & 3 deletions .github/workflows/pypi-publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ jobs:
run: python -m build --sdist --wheel

- name: Publish package
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: python -m twine upload --verbose dist/*
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
11 changes: 11 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,17 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## \[x.y.z] - Unreleased

### Added

### Changed

### Fixed

### Removed


## [0.46.0] - 2024-10-14

### Added
- The `QMI_Instrument` and `QMI_TaskRunner` (which inherit from `QMI_RpcObject`) are now equipped with specific `__enter__` and `__exit__` methods, which in the case of `QMI_Instrument`
also open and close the instrument when run with a `with` context manager protocol. Meanwhile `QMI_TaskRunner` starts and stops then joins a QMI task thread. In practise, these context managers
Expand Down
2 changes: 1 addition & 1 deletion documentation/sphinx/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
author = 'QuTech'

# The full version, including alpha/beta/rc tags
release = '0.46.0-beta.0'
release = '0.47.0-beta.0'

# The default master_doc used to be 'index', but it was changed to 'contents'.
# Override that here (maybe rename the file to the new default later).
Expand Down
2 changes: 1 addition & 1 deletion qmi/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import atexit


__version__ = "0.46.0-beta.0"
__version__ = "0.47.0-beta.0"


# Check Python version.
Expand Down
11 changes: 7 additions & 4 deletions qmi/instruments/montana/cryostation_s50.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,16 @@ def _send_request(self, url: str, request_type: str, data: Optional[bytes] = Non
try:
with urllib.request.urlopen(req) as response:
status = response.status
res = response.read() if request_type == 'GET' else None
if status != http.HTTPStatus.OK:
raise QMI_InstrumentException(f"HTTP error code: {status}")
if status != http.HTTPStatus.OK:
raise QMI_InstrumentException(f"HTTP error code: {status}")

if request_type == 'GET':
return json.loads(response.read())

except urllib.error.HTTPError as exc:
raise QMI_InstrumentException("Error in communication with device") from exc

return json.loads(res) if request_type == 'GET' else None
return None

def _set_property(self, subsystem: str, key: str, value: Union[str, float, bool]) -> None:
"""
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ def read(*names, **kwargs):

setup(
name="qmi",
version="0.46.0-beta.0",
version="0.47.0-beta.0",
description="The Quantum Measurement Infrastructure framework",
long_description="{}\n".format(read('README.md')),
long_description_content_type='text/markdown',
Expand Down
114 changes: 114 additions & 0 deletions tests/core/test_instrument.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
#! /usr/bin/env python3
"""Unit-tests for testing context managing for `QMI_Instrument` class."""
import logging
import unittest

from numpy import random

from tests.patcher import PatcherQmiContext as QMI_Context
from qmi.core.context import QMI_Instrument, rpc_method


class MyInstrument_TestDriver(QMI_Instrument):

def __init__(self, context: QMI_Context, name: str) -> None:
super().__init__(context, name)
self._it_is_open = False

@rpc_method
def open(self):
super().open()
self._it_is_open = True

@rpc_method
def close(self):
super().close()
self._it_is_open = False

@rpc_method
def is_it_open_then(self):
return self._it_is_open


class TestInstrumentContextManager(unittest.TestCase):

def setUp(self):
# Suppress logging.
logging.getLogger("qmi.core.rpc").setLevel(logging.CRITICAL)

self._ctx_qmi_id = f"test-qmi-instrument-{random.randint(0, 100)}"
self.qmi_patcher = QMI_Context("test_instrument_context_manager")
self.qmi_patcher.start(self._ctx_qmi_id)

def tearDown(self) -> None:
self.qmi_patcher.stop()

def test_create_instance(self):
"""Test creating an instrument object works without starting qmi."""
instr = MyInstrument_TestDriver(self.qmi_patcher, self._ctx_qmi_id)
# Get RPC object info
name = instr.get_name()
category = instr.get_category()
# Assert
self.assertFalse(instr.is_open())
self.assertEqual(self._ctx_qmi_id, name)
self.assertEqual("instrument", category)

def test_make_instrument_with_with(self):
"""Test creating an instrument object with context manager and also opens and closes it."""
with MyInstrument_TestDriver(self.qmi_patcher, self._ctx_qmi_id) as instr:
# Assert
name = instr.get_name()
category = instr.get_category()
# Assert
self.assertTrue(instr.is_open())
self.assertEqual(self._ctx_qmi_id, name)
self.assertEqual("instrument", category)
# Also see extra action in the instrument driver's `open` has been executed
self.assertTrue(instr.is_it_open_then())

# Assert
self.assertFalse(instr.is_open())
# Also see extra action in the instrument driver's `close` has been executed
self.assertFalse(instr.is_it_open_then())


class TestInstrumentMakeFunction(unittest.TestCase):

def setUp(self):
# Suppress logging.
logging.getLogger("qmi.core.rpc").setLevel(logging.CRITICAL)

# Start a context with creating the "instrument".
self.c1 = QMI_Context("c1")
self.c1.start()

def tearDown(self):
self.c1.stop()
self.c1 = None

logging.getLogger("qmi.core.rpc").setLevel(logging.NOTSET)

def test_make_instrument(self):
"""Test making the instrument with 'make_instrument' works as expected"""
instr_proxy = self.c1.make_instrument("instr", MyInstrument_TestDriver)

# Assert
self.assertFalse(instr_proxy.is_open())

def test_make_instrument_with_with(self):
"""Test making the instrument with 'make_instrument' works also with context manager."""
with self.c1.make_instrument("instr", MyInstrument_TestDriver) as instr_proxy:
# Assert
self.assertTrue(instr_proxy.is_open())
# Also see extra action in the instrument driver's `open` has been executed
self.assertTrue(instr_proxy.is_it_open_then())

# Assert
self.assertFalse(instr_proxy.is_open())
# Also see extra action in the instrument driver's `close` has been executed
self.assertFalse(instr_proxy.is_it_open_then())


if __name__ == '__main__':
unittest.main()

0 comments on commit 92ddc9a

Please sign in to comment.