domenukk: Why not deprecate all returns? 
ldruschk: That would also work, but unless we enforce the type annotations in the checkers and change the return type from the functions from `Optional[Result]` to `None`, there is no difference in returning a `Result.OK` that is discarded or returning nothing at all.
domenukk: My gut feeling is that we should either do it completely (deprecate all returns now, change the return type to `none` and remove the handling in a few months or so) or not deprecate it at all. Allowing exactly one return seems odd.
domenukk: But anyway it's also fine to allow and ignore it, just odd
diff --git a/src/enochecker/enochecker.py b/src/enochecker/enochecker.py
index 831cb5b..0e0e4ca 100644
--- a/src/enochecker/enochecker.py
+++ b/src/enochecker/enochecker.py
@@ -455,6 +455,11 @@ class BaseChecker(metaclass=_CheckerMeta):
 
                 # Better wrap this, in case somebody returns raw ints (?)
                 ret = Result(ret)
+                if ret != Result.OK:
+                    warnings.warn(
+                        "Returning a non-ok status code is not recommended and will be removed in the future. Raise an Exception with additional text instead.",
+                        DeprecationWarning,
+                    )
                 self.info("Checker [{}] resulted in {}".format(self.method, ret.name))
                 self.team_db[
                     f"__Checker-internals-RESULT:{str(method)},{self.flag_round},{self.flag_idx}__"

Show warning when returning error status without accompanying message
As mentioned in https://github.com/enowars/enochecker/pull/55 while returning Result.MUMBLE or Result.OFFLINE is supported it does not include details which would be necessary for e.g. https://github.com/enowars/enowars4-scoreboard/issues/2

The preferred and documented way should be using Exceptions instead
diff --git a/tests/test_run_method.py b/tests/test_run_method.py
index d059e30..ecaa6af 100644
--- a/tests/test_run_method.py
+++ b/tests/test_run_method.py
@@ -101,7 +101,10 @@ def test_run_return_status(method, result, checker_cls):
 
     setattr(checker_cls, method, meth)
     c = checker_cls(method)
-    res = c.run()
+    with pytest.warns(
+        None
+    ):  # ignore warnings caused by the deprecation of returning Results
+        res = c.run()
     assert isinstance(res, CheckerResult)
     assert res.result == result
 
@@ -293,3 +296,59 @@ def test_offline_exceptions(method, exc, checker_cls):
     assert isinstance(res, CheckerResult)
     assert res.result == Result.OFFLINE
     assert res.message
+
+
+@pytest.mark.parametrize(
+    "method", CHECKER_METHODS,
+)
+def test_no_warn_deprecated_return_ok(method, checker_cls):
+    def meth(self):
+        return Result.OK
+
+    def ok(self):
+        return Result.OK
+
+    if method == "getflag":
+        setattr(checker_cls, "putflag", ok)
+        c = checker_cls("putflag")
+        c.run()
+    elif method == "getnoise":
+        setattr(checker_cls, "putnoise", ok)
+        c = checker_cls("putnoise")
+        c.run()
+
+    setattr(checker_cls, method, meth)
+    c = checker_cls(method)
+    with pytest.warns(None) as record:
+        res = c.run()
+    assert isinstance(res, CheckerResult)
+    assert res.result == Result.OK
+    assert len(record) == 0
+
+
+@pytest.mark.parametrize(
+    "method, ret",
+    product(CHECKER_METHODS, [Result.MUMBLE, Result.OFFLINE, Result.INTERNAL_ERROR]),
+)
+def test_warn_deprecated_return_value(method, ret, checker_cls):
+    def meth(self):
+        return ret
+
+    def ok(self):
+        return Result.OK
+
+    if method == "getflag":
+        setattr(checker_cls, "putflag", ok)
+        c = checker_cls("putflag")
+        c.run()
+    elif method == "getnoise":
+        setattr(checker_cls, "putnoise", ok)
+        c = checker_cls("putnoise")
+        c.run()
+
+    setattr(checker_cls, method, meth)
+    c = checker_cls(method)
+    with pytest.deprecated_call():
+        res = c.run()
+    assert isinstance(res, CheckerResult)
+    assert res.result == ret

pip install -e .[dev]
parse_log_pytest
requirements.txt
pytest pytest-azurepipelines
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
atomicwrites==1.4.0
attrs==19.3.0
blinker==1.4
certifi==2019.3.9
chardet==3.0.4
click==7.1.2
colorama==0.4.1
-e git+https://github.com/enowars/enochecker.git@e1ddd2c15096d22dd76321086ec7fd8687529d54#egg=enochecker
exceptiongroup==1.2.2
Flask==1.0.3
idna==2.8
importlib-metadata==6.7.0
importlib-resources==5.12.0
iniconfig==2.0.0
itsdangerous==1.1.0
Jinja2==2.10.2
MarkupSafe==1.1.1
packaging==24.0
pluggy==1.2.0
psutil==5.6.6
pymongo==3.8.0
pytest==7.4.4
pytest-azurepipelines==1.0.5
pytest-nunit==1.0.7
requests==2.21.0
six==1.15.0
tomli==2.0.1
typing_extensions==4.7.1
urllib3==1.24.3
uwsgidecorators==1.1.0
websocket-client==0.56.0
Werkzeug==0.15.5
zipp==3.15.0

name: enochecker
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - atomicwrites==1.4.0
      - attrs==19.3.0
      - blinker==1.4
      - certifi==2019.3.9
      - chardet==3.0.4
      - click==7.1.2
      - colorama==0.4.1
      - exceptiongroup==1.2.2
      - flask==1.0.3
      - idna==2.8
      - importlib-metadata==6.7.0
      - importlib-resources==5.12.0
      - iniconfig==2.0.0
      - itsdangerous==1.1.0
      - jinja2==2.10.2
      - markupsafe==1.1.1
      - packaging==24.0
      - pluggy==1.2.0
      - psutil==5.6.6
      - pymongo==3.8.0
      - pytest==7.4.4
      - pytest-azurepipelines==1.0.5
      - pytest-nunit==1.0.7
      - requests==2.21.0
      - six==1.15.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - urllib3==1.24.3
      - uwsgidecorators==1.1.0
      - websocket-client==0.56.0
      - werkzeug==0.15.5
      - zipp==3.15.0
prefix: /opt/conda/envs/enochecker

tests/test_run_method.py::test_warn_deprecated_return_value[putflag-Result.MUMBLE] tests/test_run_method.py::test_warn_deprecated_return_value[putflag-Result.OFFLINE] tests/test_run_method.py::test_warn_deprecated_return_value[putflag-Result.INTERNAL_ERROR] tests/test_run_method.py::test_warn_deprecated_return_value[getflag-Result.MUMBLE] tests/test_run_method.py::test_warn_deprecated_return_value[getflag-Result.OFFLINE] tests/test_run_method.py::test_warn_deprecated_return_value[getflag-Result.INTERNAL_ERROR] tests/test_run_method.py::test_warn_deprecated_return_value[putnoise-Result.MUMBLE] tests/test_run_method.py::test_warn_deprecated_return_value[putnoise-Result.OFFLINE] tests/test_run_method.py::test_warn_deprecated_return_value[putnoise-Result.INTERNAL_ERROR] tests/test_run_method.py::test_warn_deprecated_return_value[getnoise-Result.MUMBLE] tests/test_run_method.py::test_warn_deprecated_return_value[getnoise-Result.OFFLINE] tests/test_run_method.py::test_warn_deprecated_return_value[getnoise-Result.INTERNAL_ERROR] tests/test_run_method.py::test_warn_deprecated_return_value[havoc-Result.MUMBLE] tests/test_run_method.py::test_warn_deprecated_return_value[havoc-Result.OFFLINE] tests/test_run_method.py::test_warn_deprecated_return_value[havoc-Result.INTERNAL_ERROR] tests/test_run_method.py::test_warn_deprecated_return_value[exploit-Result.MUMBLE] tests/test_run_method.py::test_warn_deprecated_return_value[exploit-Result.OFFLINE] tests/test_run_method.py::test_warn_deprecated_return_value[exploit-Result.INTERNAL_ERROR]
tests/test_run_method.py::test_run_return_nothing[putflag] tests/test_run_method.py::test_run_return_nothing[getflag] tests/test_run_method.py::test_run_return_nothing[putnoise] tests/test_run_method.py::test_run_return_nothing[getnoise] tests/test_run_method.py::test_run_return_nothing[havoc] tests/test_run_method.py::test_run_return_nothing[exploit] tests/test_run_method.py::test_run_return_status[putflag-Result.OK] tests/test_run_method.py::test_run_return_status[putflag-Result.MUMBLE] tests/test_run_method.py::test_run_return_status[putflag-Result.OFFLINE] tests/test_run_method.py::test_run_return_status[putflag-Result.INTERNAL_ERROR] tests/test_run_method.py::test_run_return_status[getflag-Result.OK] tests/test_run_method.py::test_run_return_status[getflag-Result.MUMBLE] tests/test_run_method.py::test_run_return_status[getflag-Result.OFFLINE] tests/test_run_method.py::test_run_return_status[getflag-Result.INTERNAL_ERROR] tests/test_run_method.py::test_run_return_status[putnoise-Result.OK] tests/test_run_method.py::test_run_return_status[putnoise-Result.MUMBLE] tests/test_run_method.py::test_run_return_status[putnoise-Result.OFFLINE] tests/test_run_method.py::test_run_return_status[putnoise-Result.INTERNAL_ERROR] tests/test_run_method.py::test_run_return_status[getnoise-Result.OK] tests/test_run_method.py::test_run_return_status[getnoise-Result.MUMBLE] tests/test_run_method.py::test_run_return_status[getnoise-Result.OFFLINE] tests/test_run_method.py::test_run_return_status[getnoise-Result.INTERNAL_ERROR] tests/test_run_method.py::test_run_return_status[havoc-Result.OK] tests/test_run_method.py::test_run_return_status[havoc-Result.MUMBLE] tests/test_run_method.py::test_run_return_status[havoc-Result.OFFLINE] tests/test_run_method.py::test_run_return_status[havoc-Result.INTERNAL_ERROR] tests/test_run_method.py::test_run_return_status[exploit-Result.OK] tests/test_run_method.py::test_run_return_status[exploit-Result.MUMBLE] tests/test_run_method.py::test_run_return_status[exploit-Result.OFFLINE] tests/test_run_method.py::test_run_return_status[exploit-Result.INTERNAL_ERROR] tests/test_run_method.py::test_run_get_original_run_failed[getflag] tests/test_run_method.py::test_run_get_original_run_failed[getnoise] tests/test_run_method.py::test_raise_broken_service_exception[putflag] tests/test_run_method.py::test_raise_broken_service_exception[getflag] tests/test_run_method.py::test_raise_broken_service_exception[putnoise] tests/test_run_method.py::test_raise_broken_service_exception[getnoise] tests/test_run_method.py::test_raise_broken_service_exception[havoc] tests/test_run_method.py::test_raise_broken_service_exception[exploit] tests/test_run_method.py::test_raise_offline_exception[putflag] tests/test_run_method.py::test_raise_offline_exception[getflag] tests/test_run_method.py::test_raise_offline_exception[putnoise] tests/test_run_method.py::test_raise_offline_exception[getnoise] tests/test_run_method.py::test_raise_offline_exception[havoc] tests/test_run_method.py::test_raise_offline_exception[exploit] tests/test_run_method.py::test_raise_unhandled_exception[putflag] tests/test_run_method.py::test_raise_unhandled_exception[getflag] tests/test_run_method.py::test_raise_unhandled_exception[putnoise] tests/test_run_method.py::test_raise_unhandled_exception[getnoise] tests/test_run_method.py::test_raise_unhandled_exception[havoc] tests/test_run_method.py::test_raise_unhandled_exception[exploit] tests/test_run_method.py::test_invalid_return[putflag] tests/test_run_method.py::test_invalid_return[getflag] tests/test_run_method.py::test_invalid_return[putnoise] tests/test_run_method.py::test_invalid_return[getnoise] tests/test_run_method.py::test_invalid_return[havoc] tests/test_run_method.py::test_invalid_return[exploit] tests/test_run_method.py::test_run_invalid_method tests/test_run_method.py::test_requests_mumble[putflag-HTTPError] tests/test_run_method.py::test_requests_mumble[putflag-EOFError] tests/test_run_method.py::test_requests_mumble[getflag-HTTPError] tests/test_run_method.py::test_requests_mumble[getflag-EOFError] tests/test_run_method.py::test_requests_mumble[putnoise-HTTPError] tests/test_run_method.py::test_requests_mumble[putnoise-EOFError] tests/test_run_method.py::test_requests_mumble[getnoise-HTTPError] tests/test_run_method.py::test_requests_mumble[getnoise-EOFError] tests/test_run_method.py::test_requests_mumble[havoc-HTTPError] tests/test_run_method.py::test_requests_mumble[havoc-EOFError] tests/test_run_method.py::test_requests_mumble[exploit-HTTPError] tests/test_run_method.py::test_requests_mumble[exploit-EOFError] tests/test_run_method.py::test_offline_exceptions[putflag-ConnectionError0] tests/test_run_method.py::test_offline_exceptions[putflag-ConnectTimeout] tests/test_run_method.py::test_offline_exceptions[putflag-TimeoutError] tests/test_run_method.py::test_offline_exceptions[putflag-timeout] tests/test_run_method.py::test_offline_exceptions[putflag-ConnectionError1] tests/test_run_method.py::test_offline_exceptions[putflag-OSError] tests/test_run_method.py::test_offline_exceptions[putflag-ConnectionAbortedError] tests/test_run_method.py::test_offline_exceptions[getflag-ConnectionError0] tests/test_run_method.py::test_offline_exceptions[getflag-ConnectTimeout] tests/test_run_method.py::test_offline_exceptions[getflag-TimeoutError] tests/test_run_method.py::test_offline_exceptions[getflag-timeout] tests/test_run_method.py::test_offline_exceptions[getflag-ConnectionError1] tests/test_run_method.py::test_offline_exceptions[getflag-OSError] tests/test_run_method.py::test_offline_exceptions[getflag-ConnectionAbortedError] tests/test_run_method.py::test_offline_exceptions[putnoise-ConnectionError0] tests/test_run_method.py::test_offline_exceptions[putnoise-ConnectTimeout] tests/test_run_method.py::test_offline_exceptions[putnoise-TimeoutError] tests/test_run_method.py::test_offline_exceptions[putnoise-timeout] tests/test_run_method.py::test_offline_exceptions[putnoise-ConnectionError1] tests/test_run_method.py::test_offline_exceptions[putnoise-OSError] tests/test_run_method.py::test_offline_exceptions[putnoise-ConnectionAbortedError] tests/test_run_method.py::test_offline_exceptions[getnoise-ConnectionError0] tests/test_run_method.py::test_offline_exceptions[getnoise-ConnectTimeout] tests/test_run_method.py::test_offline_exceptions[getnoise-TimeoutError] tests/test_run_method.py::test_offline_exceptions[getnoise-timeout] tests/test_run_method.py::test_offline_exceptions[getnoise-ConnectionError1] tests/test_run_method.py::test_offline_exceptions[getnoise-OSError] tests/test_run_method.py::test_offline_exceptions[getnoise-ConnectionAbortedError] tests/test_run_method.py::test_offline_exceptions[havoc-ConnectionError0] tests/test_run_method.py::test_offline_exceptions[havoc-ConnectTimeout] tests/test_run_method.py::test_offline_exceptions[havoc-TimeoutError] tests/test_run_method.py::test_offline_exceptions[havoc-timeout] tests/test_run_method.py::test_offline_exceptions[havoc-ConnectionError1] tests/test_run_method.py::test_offline_exceptions[havoc-OSError] tests/test_run_method.py::test_offline_exceptions[havoc-ConnectionAbortedError] tests/test_run_method.py::test_offline_exceptions[exploit-ConnectionError0] tests/test_run_method.py::test_offline_exceptions[exploit-ConnectTimeout] tests/test_run_method.py::test_offline_exceptions[exploit-TimeoutError] tests/test_run_method.py::test_offline_exceptions[exploit-timeout] tests/test_run_method.py::test_offline_exceptions[exploit-ConnectionError1] tests/test_run_method.py::test_offline_exceptions[exploit-OSError] tests/test_run_method.py::test_offline_exceptions[exploit-ConnectionAbortedError] tests/test_run_method.py::test_no_warn_deprecated_return_ok[putflag] tests/test_run_method.py::test_no_warn_deprecated_return_ok[getflag] tests/test_run_method.py::test_no_warn_deprecated_return_ok[putnoise] tests/test_run_method.py::test_no_warn_deprecated_return_ok[getnoise] tests/test_run_method.py::test_no_warn_deprecated_return_ok[havoc] tests/test_run_method.py::test_no_warn_deprecated_return_ok[exploit]
src/enochecker/enochecker.py
src/enochecker/enochecker.py