lv24-opencode-consilium 1.10.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.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 LevapVeeskela
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.4
2
+ Name: lv24-opencode-consilium
3
+ Version: 1.10.0
4
+ Summary: Python launcher for the lv24-opencode-consilium (Consilium) Node.js CLI
5
+ Author: LevapVeeskela
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/LevapVeeskela/lv24-opencode-consilium
8
+ Project-URL: Repository, https://github.com/LevapVeeskela/lv24-opencode-consilium
9
+ Project-URL: Issues, https://github.com/LevapVeeskela/lv24-opencode-consilium/issues
10
+ Project-URL: Documentation, https://github.com/LevapVeeskela/lv24-opencode-consilium/tree/master/docs
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.9
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Dynamic: license-file
17
+
18
+ # lv24-opencode-consilium (Python launcher)
19
+
20
+ A thin Python launcher for **Consilium**, the multi-agent review and audit CLI
21
+ for the [OpenCode](https://opencode.ai/) ecosystem. Consilium itself is a
22
+ Node.js command-line tool published on npm as
23
+ [`lv24-opencode-consilium`](https://www.npmjs.com/package/lv24-opencode-consilium).
24
+ This package does not reimplement Consilium and does not bundle Node.js: the
25
+ `consilium` command delegates to the npm package through `npx`.
26
+
27
+ The npm package remains the canonical distribution. The PyPI package only
28
+ contains this launcher.
29
+
30
+ ## Prerequisites
31
+
32
+ - **Node.js 18 or newer**, including npm and npx
33
+ ([nodejs.org](https://nodejs.org/)).
34
+ - The **OpenCode CLI** installed and available on `PATH`
35
+ ([OpenCode docs](https://opencode.ai/docs/)).
36
+ - Network access on first run, or an npm cache that already contains the
37
+ requested package, because `npx` may download it.
38
+ - Python 3.9 or newer.
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ pip install lv24-opencode-consilium
44
+ ```
45
+
46
+ This installs two equivalent console scripts:
47
+
48
+ - `consilium`
49
+ - `lv24-opencode-consilium`
50
+
51
+ ## Usage
52
+
53
+ ```bash
54
+ consilium --help
55
+ consilium "review this repository"
56
+ consilium review --model opencode/gpt-5
57
+ ```
58
+
59
+ All arguments are forwarded unchanged to the npm CLI. The child process
60
+ inherits the terminal, environment, and exit code. You can also run:
61
+
62
+ ```bash
63
+ python -m lv24_opencode_consilium --help
64
+ ```
65
+
66
+ If `npx` cannot be found, the launcher exits with code `127` and prints an
67
+ installation hint. An interrupted run exits with code `130`.
68
+
69
+ ## Version pinning
70
+
71
+ By default the launcher runs the npm package version matching its own version
72
+ (currently `1.10.0`). Override it with `CONSILIUM_NPM_VERSION` to use any npm
73
+ version or tag:
74
+
75
+ ```bash
76
+ CONSILIUM_NPM_VERSION=latest consilium --help
77
+ CONSILIUM_NPM_VERSION=1.9.0 consilium --help
78
+ ```
79
+
80
+ PowerShell:
81
+
82
+ ```powershell
83
+ $env:CONSILIUM_NPM_VERSION = "latest"; consilium --help
84
+ ```
85
+
86
+ ## Links
87
+
88
+ - Main repository and documentation:
89
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium>
90
+ - Documentation:
91
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium/tree/master/docs>
92
+ - Issues:
93
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium/issues>
94
+ - npm package:
95
+ <https://www.npmjs.com/package/lv24-opencode-consilium>
96
+
97
+ ## License
98
+
99
+ MIT
@@ -0,0 +1,82 @@
1
+ # lv24-opencode-consilium (Python launcher)
2
+
3
+ A thin Python launcher for **Consilium**, the multi-agent review and audit CLI
4
+ for the [OpenCode](https://opencode.ai/) ecosystem. Consilium itself is a
5
+ Node.js command-line tool published on npm as
6
+ [`lv24-opencode-consilium`](https://www.npmjs.com/package/lv24-opencode-consilium).
7
+ This package does not reimplement Consilium and does not bundle Node.js: the
8
+ `consilium` command delegates to the npm package through `npx`.
9
+
10
+ The npm package remains the canonical distribution. The PyPI package only
11
+ contains this launcher.
12
+
13
+ ## Prerequisites
14
+
15
+ - **Node.js 18 or newer**, including npm and npx
16
+ ([nodejs.org](https://nodejs.org/)).
17
+ - The **OpenCode CLI** installed and available on `PATH`
18
+ ([OpenCode docs](https://opencode.ai/docs/)).
19
+ - Network access on first run, or an npm cache that already contains the
20
+ requested package, because `npx` may download it.
21
+ - Python 3.9 or newer.
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ pip install lv24-opencode-consilium
27
+ ```
28
+
29
+ This installs two equivalent console scripts:
30
+
31
+ - `consilium`
32
+ - `lv24-opencode-consilium`
33
+
34
+ ## Usage
35
+
36
+ ```bash
37
+ consilium --help
38
+ consilium "review this repository"
39
+ consilium review --model opencode/gpt-5
40
+ ```
41
+
42
+ All arguments are forwarded unchanged to the npm CLI. The child process
43
+ inherits the terminal, environment, and exit code. You can also run:
44
+
45
+ ```bash
46
+ python -m lv24_opencode_consilium --help
47
+ ```
48
+
49
+ If `npx` cannot be found, the launcher exits with code `127` and prints an
50
+ installation hint. An interrupted run exits with code `130`.
51
+
52
+ ## Version pinning
53
+
54
+ By default the launcher runs the npm package version matching its own version
55
+ (currently `1.10.0`). Override it with `CONSILIUM_NPM_VERSION` to use any npm
56
+ version or tag:
57
+
58
+ ```bash
59
+ CONSILIUM_NPM_VERSION=latest consilium --help
60
+ CONSILIUM_NPM_VERSION=1.9.0 consilium --help
61
+ ```
62
+
63
+ PowerShell:
64
+
65
+ ```powershell
66
+ $env:CONSILIUM_NPM_VERSION = "latest"; consilium --help
67
+ ```
68
+
69
+ ## Links
70
+
71
+ - Main repository and documentation:
72
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium>
73
+ - Documentation:
74
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium/tree/master/docs>
75
+ - Issues:
76
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium/issues>
77
+ - npm package:
78
+ <https://www.npmjs.com/package/lv24-opencode-consilium>
79
+
80
+ ## License
81
+
82
+ MIT
@@ -0,0 +1,32 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "lv24-opencode-consilium"
7
+ version = "1.10.0"
8
+ description = "Python launcher for the lv24-opencode-consilium (Consilium) Node.js CLI"
9
+ readme = "README.md"
10
+ requires-python = ">=3.9"
11
+ license = "MIT"
12
+ license-files = ["LICENSE"]
13
+ authors = [
14
+ { name = "LevapVeeskela" },
15
+ ]
16
+ classifiers = [
17
+ "Programming Language :: Python :: 3",
18
+ "Operating System :: OS Independent",
19
+ ]
20
+
21
+ [project.urls]
22
+ Homepage = "https://github.com/LevapVeeskela/lv24-opencode-consilium"
23
+ Repository = "https://github.com/LevapVeeskela/lv24-opencode-consilium"
24
+ Issues = "https://github.com/LevapVeeskela/lv24-opencode-consilium/issues"
25
+ Documentation = "https://github.com/LevapVeeskela/lv24-opencode-consilium/tree/master/docs"
26
+
27
+ [project.scripts]
28
+ consilium = "lv24_opencode_consilium.cli:main"
29
+ lv24-opencode-consilium = "lv24_opencode_consilium.cli:main"
30
+
31
+ [tool.setuptools.packages.find]
32
+ where = ["src"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,5 @@
1
+ """Python launcher for the Consilium Node.js CLI."""
2
+
3
+ __version__ = "1.10.0"
4
+
5
+ __all__ = ["__version__"]
@@ -0,0 +1,6 @@
1
+ """Allow running the launcher with ``python -m lv24_opencode_consilium``."""
2
+
3
+ from .cli import main
4
+
5
+ if __name__ == "__main__":
6
+ raise SystemExit(main())
@@ -0,0 +1,52 @@
1
+ """Command-line entry point that delegates to the npm Consilium CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import os
6
+ import shutil
7
+ import subprocess
8
+ import sys
9
+ from typing import Optional, Sequence
10
+
11
+ from . import __version__
12
+
13
+ NPM_PACKAGE = "lv24-opencode-consilium"
14
+ NPM_VERSION_ENV = "CONSILIUM_NPM_VERSION"
15
+
16
+ _NPX_MISSING_MESSAGE = """\
17
+ consilium: npx was not found on PATH.
18
+
19
+ This package is a Python launcher for the Node.js Consilium CLI; it does not
20
+ bundle Node.js. Install Node.js 18 or newer (npm and npx are included) from
21
+ https://nodejs.org/ and make sure the OpenCode CLI is installed and available:
22
+ https://opencode.ai/docs/
23
+ """
24
+
25
+
26
+ def npm_spec() -> str:
27
+ """Return the npm package spec, honoring CONSILIUM_NPM_VERSION."""
28
+ version = os.environ.get(NPM_VERSION_ENV, "").strip() or __version__
29
+ return "{0}@{1}".format(NPM_PACKAGE, version)
30
+
31
+
32
+ def main(argv: Optional[Sequence[str]] = None) -> int:
33
+ """Run the npm CLI through npx and return its exit code."""
34
+ args = list(sys.argv[1:] if argv is None else argv)
35
+
36
+ npx = shutil.which("npx")
37
+ if npx is None:
38
+ sys.stderr.write(_NPX_MISSING_MESSAGE)
39
+ return 127
40
+
41
+ command = [npx, "--yes", npm_spec(), *args]
42
+
43
+ try:
44
+ completed = subprocess.run(command, check=False)
45
+ return completed.returncode
46
+ except KeyboardInterrupt:
47
+ return 130
48
+ except OSError as exc:
49
+ sys.stderr.write(
50
+ "consilium: failed to start {0}: {1}\n".format(npx, exc)
51
+ )
52
+ return 127
@@ -0,0 +1,99 @@
1
+ Metadata-Version: 2.4
2
+ Name: lv24-opencode-consilium
3
+ Version: 1.10.0
4
+ Summary: Python launcher for the lv24-opencode-consilium (Consilium) Node.js CLI
5
+ Author: LevapVeeskela
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/LevapVeeskela/lv24-opencode-consilium
8
+ Project-URL: Repository, https://github.com/LevapVeeskela/lv24-opencode-consilium
9
+ Project-URL: Issues, https://github.com/LevapVeeskela/lv24-opencode-consilium/issues
10
+ Project-URL: Documentation, https://github.com/LevapVeeskela/lv24-opencode-consilium/tree/master/docs
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Operating System :: OS Independent
13
+ Requires-Python: >=3.9
14
+ Description-Content-Type: text/markdown
15
+ License-File: LICENSE
16
+ Dynamic: license-file
17
+
18
+ # lv24-opencode-consilium (Python launcher)
19
+
20
+ A thin Python launcher for **Consilium**, the multi-agent review and audit CLI
21
+ for the [OpenCode](https://opencode.ai/) ecosystem. Consilium itself is a
22
+ Node.js command-line tool published on npm as
23
+ [`lv24-opencode-consilium`](https://www.npmjs.com/package/lv24-opencode-consilium).
24
+ This package does not reimplement Consilium and does not bundle Node.js: the
25
+ `consilium` command delegates to the npm package through `npx`.
26
+
27
+ The npm package remains the canonical distribution. The PyPI package only
28
+ contains this launcher.
29
+
30
+ ## Prerequisites
31
+
32
+ - **Node.js 18 or newer**, including npm and npx
33
+ ([nodejs.org](https://nodejs.org/)).
34
+ - The **OpenCode CLI** installed and available on `PATH`
35
+ ([OpenCode docs](https://opencode.ai/docs/)).
36
+ - Network access on first run, or an npm cache that already contains the
37
+ requested package, because `npx` may download it.
38
+ - Python 3.9 or newer.
39
+
40
+ ## Installation
41
+
42
+ ```bash
43
+ pip install lv24-opencode-consilium
44
+ ```
45
+
46
+ This installs two equivalent console scripts:
47
+
48
+ - `consilium`
49
+ - `lv24-opencode-consilium`
50
+
51
+ ## Usage
52
+
53
+ ```bash
54
+ consilium --help
55
+ consilium "review this repository"
56
+ consilium review --model opencode/gpt-5
57
+ ```
58
+
59
+ All arguments are forwarded unchanged to the npm CLI. The child process
60
+ inherits the terminal, environment, and exit code. You can also run:
61
+
62
+ ```bash
63
+ python -m lv24_opencode_consilium --help
64
+ ```
65
+
66
+ If `npx` cannot be found, the launcher exits with code `127` and prints an
67
+ installation hint. An interrupted run exits with code `130`.
68
+
69
+ ## Version pinning
70
+
71
+ By default the launcher runs the npm package version matching its own version
72
+ (currently `1.10.0`). Override it with `CONSILIUM_NPM_VERSION` to use any npm
73
+ version or tag:
74
+
75
+ ```bash
76
+ CONSILIUM_NPM_VERSION=latest consilium --help
77
+ CONSILIUM_NPM_VERSION=1.9.0 consilium --help
78
+ ```
79
+
80
+ PowerShell:
81
+
82
+ ```powershell
83
+ $env:CONSILIUM_NPM_VERSION = "latest"; consilium --help
84
+ ```
85
+
86
+ ## Links
87
+
88
+ - Main repository and documentation:
89
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium>
90
+ - Documentation:
91
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium/tree/master/docs>
92
+ - Issues:
93
+ <https://github.com/LevapVeeskela/lv24-opencode-consilium/issues>
94
+ - npm package:
95
+ <https://www.npmjs.com/package/lv24-opencode-consilium>
96
+
97
+ ## License
98
+
99
+ MIT
@@ -0,0 +1,12 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ src/lv24_opencode_consilium/__init__.py
5
+ src/lv24_opencode_consilium/__main__.py
6
+ src/lv24_opencode_consilium/cli.py
7
+ src/lv24_opencode_consilium.egg-info/PKG-INFO
8
+ src/lv24_opencode_consilium.egg-info/SOURCES.txt
9
+ src/lv24_opencode_consilium.egg-info/dependency_links.txt
10
+ src/lv24_opencode_consilium.egg-info/entry_points.txt
11
+ src/lv24_opencode_consilium.egg-info/top_level.txt
12
+ tests/test_cli.py
@@ -0,0 +1,3 @@
1
+ [console_scripts]
2
+ consilium = lv24_opencode_consilium.cli:main
3
+ lv24-opencode-consilium = lv24_opencode_consilium.cli:main
@@ -0,0 +1,185 @@
1
+ """Tests for the Python launcher that delegates to the npm CLI."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import contextlib
6
+ import io
7
+ import json
8
+ import os
9
+ import stat
10
+ import sys
11
+ import tempfile
12
+ import unittest
13
+ from pathlib import Path
14
+ from unittest import mock
15
+
16
+ SRC_DIR = Path(__file__).resolve().parents[1] / "src"
17
+ if str(SRC_DIR) not in sys.path:
18
+ sys.path.insert(0, str(SRC_DIR))
19
+
20
+ from lv24_opencode_consilium import __version__
21
+ from lv24_opencode_consilium.cli import NPM_PACKAGE, NPM_VERSION_ENV, main
22
+
23
+ _FAKE_NPX = '''\
24
+ import json
25
+ import os
26
+ import sys
27
+
28
+ record = {
29
+ "argv": sys.argv[1:],
30
+ "env": {
31
+ key: value
32
+ for key, value in os.environ.items()
33
+ if key.startswith("CONSILIUM_") or key == "PATH"
34
+ },
35
+ }
36
+ with open(os.environ["CONSILIUM_TEST_LOG"], "a", encoding="utf-8") as handle:
37
+ handle.write(json.dumps(record, sort_keys=True) + "\\n")
38
+ raise SystemExit(3)
39
+ '''
40
+
41
+
42
+ class MainTests(unittest.TestCase):
43
+ def setUp(self):
44
+ self._tempdir = tempfile.TemporaryDirectory()
45
+ self.addCleanup(self._tempdir.cleanup)
46
+ self.root = Path(self._tempdir.name)
47
+ self.bin_dir = self.root / "bin"
48
+ self.bin_dir.mkdir()
49
+ self.empty_dir = self.root / "empty"
50
+ self.empty_dir.mkdir()
51
+ self.log_path = self.root / "calls.jsonl"
52
+
53
+ self._saved_env = {
54
+ key: os.environ.get(key)
55
+ for key in ("CONSILIUM_NPM_VERSION", "CONSILIUM_TEST_LOG")
56
+ }
57
+ self.addCleanup(self._restore_env)
58
+ os.environ.pop("CONSILIUM_NPM_VERSION", None)
59
+ os.environ["CONSILIUM_TEST_LOG"] = str(self.log_path)
60
+
61
+ self._write_fake_npx()
62
+
63
+ def _restore_env(self):
64
+ for key, value in self._saved_env.items():
65
+ if value is None:
66
+ os.environ.pop(key, None)
67
+ else:
68
+ os.environ[key] = value
69
+
70
+ def _write_fake_npx(self):
71
+ script = self.bin_dir / "fake_npx.py"
72
+ script.write_text(_FAKE_NPX, encoding="utf-8")
73
+
74
+ if os.name == "nt":
75
+ launcher = self.bin_dir / "npx.cmd"
76
+ content = '@echo off\r\n"{0}" "%~dp0fake_npx.py" %*\r\n'.format(
77
+ sys.executable
78
+ )
79
+ with launcher.open("w", encoding="utf-8", newline="") as handle:
80
+ handle.write(content)
81
+ else:
82
+ launcher = self.bin_dir / "npx"
83
+ content = '#!/bin/sh\nexec "{0}" "$(dirname "$0")/fake_npx.py" "$@"\n'.format(
84
+ sys.executable
85
+ )
86
+ launcher.write_text(content, encoding="utf-8")
87
+ launcher.chmod(
88
+ launcher.stat().st_mode
89
+ | stat.S_IXUSR
90
+ | stat.S_IXGRP
91
+ | stat.S_IXOTH
92
+ )
93
+
94
+ def _invoke(self, args, *, env=None, path=None, cwd=None):
95
+ call_env = {
96
+ "PATH": str(self.bin_dir if path is None else path),
97
+ "CONSILIUM_TEST_LOG": str(self.log_path),
98
+ }
99
+ if os.name == "nt":
100
+ call_env["PATHEXT"] = ".COM;.EXE;.BAT;.CMD"
101
+ if env:
102
+ call_env.update(env)
103
+
104
+ stderr = io.StringIO()
105
+ previous_cwd = os.getcwd()
106
+ if cwd is not None:
107
+ os.chdir(cwd)
108
+ try:
109
+ with mock.patch.dict(os.environ, call_env, clear=False):
110
+ with contextlib.redirect_stderr(stderr):
111
+ code = main(list(args))
112
+ finally:
113
+ if cwd is not None:
114
+ os.chdir(previous_cwd)
115
+ return code, stderr.getvalue()
116
+
117
+ def _calls(self):
118
+ if not self.log_path.exists():
119
+ return []
120
+ return [
121
+ json.loads(line)
122
+ for line in self.log_path.read_text(encoding="utf-8").splitlines()
123
+ if line
124
+ ]
125
+
126
+ def test_forwards_arguments_and_returns_child_exit_code(self):
127
+ code, stderr = self._invoke(["review", "the", "repo"])
128
+
129
+ self.assertEqual(code, 3)
130
+ self.assertEqual(stderr, "")
131
+ calls = self._calls()
132
+ self.assertEqual(len(calls), 1)
133
+ self.assertEqual(
134
+ calls[0]["argv"],
135
+ [
136
+ "--yes",
137
+ "{0}@{1}".format(NPM_PACKAGE, __version__),
138
+ "review",
139
+ "the",
140
+ "repo",
141
+ ],
142
+ )
143
+
144
+ def test_version_matches_expected_release(self):
145
+ self.assertEqual(__version__, "1.10.0")
146
+
147
+ def test_uses_env_override_and_inherits_it(self):
148
+ code, stderr = self._invoke(
149
+ ["--help"], env={NPM_VERSION_ENV: "latest"}
150
+ )
151
+
152
+ self.assertEqual(code, 3)
153
+ self.assertEqual(stderr, "")
154
+ call = self._calls()[0]
155
+ self.assertEqual(
156
+ call["argv"],
157
+ ["--yes", "{0}@latest".format(NPM_PACKAGE), "--help"],
158
+ )
159
+ self.assertEqual(call["env"][NPM_VERSION_ENV], "latest")
160
+
161
+ def test_missing_npx_returns_127_with_install_hint(self):
162
+ code, stderr = self._invoke(
163
+ [], path=self.empty_dir, cwd=self.empty_dir
164
+ )
165
+
166
+ self.assertEqual(code, 127)
167
+ self.assertIn("npx", stderr)
168
+ self.assertIn("Node.js", stderr)
169
+ self.assertIn("npm", stderr)
170
+ self.assertIn("OpenCode", stderr)
171
+ self.assertEqual(self._calls(), [])
172
+
173
+ def test_keyboard_interrupt_returns_130(self):
174
+ with mock.patch(
175
+ "lv24_opencode_consilium.cli.subprocess.run",
176
+ side_effect=KeyboardInterrupt,
177
+ ):
178
+ code, stderr = self._invoke([])
179
+
180
+ self.assertEqual(code, 130)
181
+ self.assertEqual(stderr, "")
182
+
183
+
184
+ if __name__ == "__main__":
185
+ unittest.main()