diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a4ddf6f..0135935 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,11 +3,17 @@ --- name: CI -on: [push, pull_request] +on: + pull_request: + branches: + - master + push: + branches: + - master jobs: lint: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 @@ -23,20 +29,20 @@ jobs: - run: python -m tox -e lint check-commits: - if: github.event_name == 'pull_request' + if: ${{ github.event.pull_request.commits }} runs-on: ubuntu-latest env: - SRPY_START_COMMIT: "${{ github.event.pull_request.base.sha }}" - SRPY_END_COMMIT: "${{ github.event.pull_request.head.sha }}" + SRPY_COMMIT_RANGE: "HEAD~${{ github.event.pull_request.commits }}.." steps: - run: sudo apt-get install git make - uses: actions/checkout@v4 with: fetch-depth: 0 + ref: ${{ github.event.pull_request.head.sha || github.ref }} - run: make check-commits test: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 strategy: matrix: include: @@ -67,7 +73,7 @@ jobs: - run: python -m tox -e ${{ matrix.toxenv }} coverage: - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 @@ -86,7 +92,7 @@ jobs: deploy: needs: [lint, test] if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags/v') - runs-on: ubuntu-latest + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v4 - uses: actions/setup-python@v4 diff --git a/Makefile b/Makefile index 9722c0e..bfd2b48 100644 --- a/Makefile +++ b/Makefile @@ -12,10 +12,9 @@ tests: format: tox -e format -SRPY_START_COMMIT ?= origin/master -SRPY_END_COMMIT ?= HEAD +SRPY_COMMIT_RANGE ?= origin/master.. check-commits: - ./check-commits.sh $(SRPY_START_COMMIT)..$(SRPY_END_COMMIT) + ./check-commits.sh $(SRPY_COMMIT_RANGE) .PHONY: lint tests format check-commits diff --git a/cffi/cdefs.h b/cffi/cdefs.h index fb5db03..b820eef 100644 --- a/cffi/cdefs.h +++ b/cffi/cdefs.h @@ -95,7 +95,7 @@ int sr_session_switch_ds(sr_session_ctx_t *, sr_datastore_t); sr_datastore_t sr_session_get_ds(sr_session_ctx_t *); sr_conn_ctx_t *sr_session_get_connection(sr_session_ctx_t *); int sr_session_get_error(sr_session_ctx_t *, const sr_error_info_t **); -int sr_session_set_error_message(sr_session_ctx_t *, const char *, ...); +int sr_session_set_error(sr_session_ctx_t *, const char *, sr_error_t, const char *, ...); const char *sr_session_get_orig_name(sr_session_ctx_t *session); int sr_session_set_orig_name(sr_session_ctx_t *session, const char *); int sr_session_get_orig_data(sr_session_ctx_t *session, uint32_t idx, uint32_t *size, const void **data); diff --git a/pylintrc b/pylintrc index 41fca43..a02ca62 100644 --- a/pylintrc +++ b/pylintrc @@ -71,6 +71,7 @@ disable= missing-docstring, suppressed-message, too-many-lines, + too-many-positional-arguments, unnecessary-pass, unused-argument, use-implicit-booleaness-not-comparison-to-string, diff --git a/sysrepo/session.py b/sysrepo/session.py index 582362a..a04db6a 100644 --- a/sysrepo/session.py +++ b/sysrepo/session.py @@ -11,6 +11,7 @@ from _sysrepo import ffi, lib from .change import Change from .errors import ( + SysrepoError, SysrepoInternalError, SysrepoNotFoundError, SysrepoUnsupportedError, @@ -164,7 +165,7 @@ def switch_datastore(self, datastore: str) -> None: ds = datastore_value(datastore) check_call(lib.sr_session_switch_ds, self.cdata, ds) - def set_error(self, message: str): + def set_error(self, err: BaseException): """ Set detailed error information into provided session. Used to notify the client library about errors that occurred in the application code. Does not print the @@ -173,13 +174,24 @@ def set_error(self, message: str): Intended for change, RPC/action, or operational callbacks to be used on the provided session. - :arg str message: - The detailed error message. + :arg BaseException err: + The python exception object that carries the error information. """ if not self.is_implicit: raise SysrepoUnsupportedError("can only report errors on implicit sessions") + if isinstance(err, SysrepoError): + code = err.rc + message = err.msg + else: + code = lib.SR_ERR_CALLBACK_FAILED + message = str(err) check_call( - lib.sr_session_set_error_message, self.cdata, str2c("%s"), str2c(message) + lib.sr_session_set_error, + self.cdata, + ffi.NULL, + code, + str2c("%s"), + str2c(message), ) def get_originator_name(self) -> str: diff --git a/sysrepo/subscription.py b/sysrepo/subscription.py index d54bab7..dd8ff92 100644 --- a/sysrepo/subscription.py +++ b/sysrepo/subscription.py @@ -304,7 +304,7 @@ def module_change_callback(session, sub_id, module, xpath, event, req_id, priv): and isinstance(session, SysrepoSession) and isinstance(xpath, str) ): - session.set_error(e.msg) + session.set_error(e) return e.rc except BaseException as e: @@ -317,7 +317,7 @@ def module_change_callback(session, sub_id, module, xpath, event, req_id, priv): and isinstance(session, SysrepoSession) and isinstance(xpath, str) ): - session.set_error(str(e)) + session.set_error(e) return lib.SR_ERR_CALLBACK_FAILED @@ -421,7 +421,7 @@ def oper_data_callback(session, sub_id, module, xpath, req_xpath, req_id, parent except SysrepoError as e: if e.msg and isinstance(session, SysrepoSession) and isinstance(xpath, str): - session.set_error(e.msg) + session.set_error(e) return e.rc except BaseException as e: @@ -430,7 +430,7 @@ def oper_data_callback(session, sub_id, module, xpath, req_xpath, req_id, parent # We are in a C callback, we cannot let any error pass LOG.exception("%r callback failed", locals().get("callback", priv)) if isinstance(session, SysrepoSession) and isinstance(xpath, str): - session.set_error(str(e)) + session.set_error(e) return lib.SR_ERR_CALLBACK_FAILED @@ -548,7 +548,7 @@ def rpc_callback(session, sub_id, xpath, input_node, event, req_id, output_node, except SysrepoError as e: if e.msg and isinstance(session, SysrepoSession) and isinstance(xpath, str): - session.set_error(e.msg) + session.set_error(e) return e.rc except BaseException as e: @@ -557,7 +557,7 @@ def rpc_callback(session, sub_id, xpath, input_node, event, req_id, output_node, # We are in a C callback, we cannot let any error pass LOG.exception("%r callback failed", locals().get("callback", priv)) if isinstance(session, SysrepoSession) and isinstance(xpath, str): - session.set_error(str(e)) + session.set_error(e) return lib.SR_ERR_CALLBACK_FAILED diff --git a/tests/test_subs_module_change.py b/tests/test_subs_module_change.py index afda04c..79b64c1 100644 --- a/tests/test_subs_module_change.py +++ b/tests/test_subs_module_change.py @@ -74,7 +74,7 @@ def module_change_cb(event, req_id, changes, private_data): # 2. sent_config = {"conf": {"system": {"hostname": "INVALID"}}} expected_changes = [] - with self.assertRaises(sysrepo.SysrepoCallbackFailedError): + with self.assertRaises(sysrepo.SysrepoValidationFailedError): ch_sess.replace_config(sent_config, "sysrepo-example", strict=True) # 3. sent_config = { @@ -347,7 +347,7 @@ def module_change_cb(session, event, req_id, private_data): # 2. sent_config = {"conf": {"system": {"hostname": "INVALID"}}} expected_changes = [] - with self.assertRaises(sysrepo.SysrepoCallbackFailedError): + with self.assertRaises(sysrepo.SysrepoValidationFailedError): ch_sess.replace_config(sent_config, "sysrepo-example", strict=True) # 3. sent_config = { diff --git a/tox.ini b/tox.ini index 1b9d52b..da47b14 100644 --- a/tox.ini +++ b/tox.ini @@ -56,8 +56,8 @@ basepython = python3 description = Format python code using isort and black. changedir = . deps = - black~=23.12.1 - isort~=5.13.2 + black~=25.1.0 + isort~=6.0.0 skip_install = true install_command = python3 -m pip install {opts} {packages} allowlist_externals = @@ -73,14 +73,14 @@ description = Run coding style checks. install_command = {toxinidir}/tox-install.sh {toxworkdir} {opts} {packages} changedir = . deps = - astroid~=3.0.2 - black~=23.12.1 - flake8~=7.0.0 - isort~=5.13.2 - pycodestyle~=2.11.1 + astroid~=3.3.8 + black~=25.1.0 + flake8~=7.1.1 + isort~=6.0.0 + pycodestyle~=2.12.1 pyflakes~=3.2.0 - pylint~=3.0.3 - setuptools~=69.0.3 + pylint~=3.3.4 + setuptools~=75.8.0 allowlist_externals = /bin/sh /usr/bin/sh