Add option for ignore all system exit codes#2017
Conversation
| PROPERTIES = { | ||
| # Common | ||
| "breakOnSystemExitZero": False, | ||
| "breakOnSystemExit": (), |
There was a problem hiding this comment.
Copilot generated:
The default "breakOnSystemExit": () is risky. If the test framework serializes all config properties (including defaults) into launch args, () becomes [] in JSON, which the adapter interprets as "never break on any SystemExit" — silently breaking all existing SystemExit tests. Use None instead: the adapter's args.get("breakOnSystemExit", None) already handles None correctly by falling through to legacy behavior.
| :param list ranges: | ||
| List of (from_code, to_code) tuples (inclusive) to break on. | ||
| """ | ||
| self._break_on_system_exit = (codes, ranges) |
There was a problem hiding this comment.
Copilot generated:
-952
Behavior regression for string exit codes. When _break_on_system_exit is set and sys.exit("fatal error") is called: the string is not in codes_set, isinstance("fatal error", int) is False so ranges are skipped, and the method returns True (ignore). Previously, string codes were NOT in _ignore_system_exit_codes so the debugger would break. This silently suppresses breaks that users previously got. Consider treating non-int, non-None codes as "always break" when _break_on_system_exit is set, or document this limitation clearly.
| self._exclude_by_filter_cache = {} | ||
| self._apply_filter_cache = {} | ||
| self._ignore_system_exit_codes = set() | ||
| self._break_on_system_exit = None # None = default behavior, tuple = (codes_set, ranges_list) |
There was a problem hiding this comment.
Copilot generated:
Dual state variables can conflict silently. _break_on_system_exit and _ignore_system_exit_codes are independent state for the same decision. If a caller uses the old set_ignore_system_exit_codes API and another sets set_break_on_system_exit, the new one silently wins with no warning. Consider clearing _ignore_system_exit_codes when set_break_on_system_exit is called (or vice versa), or unifying the internal representation.
| assert isinstance(ignore_system_exit_codes, (list, tuple, set)) | ||
| self._ignore_system_exit_codes = set(ignore_system_exit_codes) | ||
|
|
||
| def set_break_on_system_exit(self, codes, ranges): |
There was a problem hiding this comment.
Copilot generated:
-952
Method name ignore_system_exit_code is now semantically misleading. When _break_on_system_exit is set, the method answers "should I ignore this?" but the configuration semantics are "should I break on this?" — the logic is inverted. Consider adding a clearer wrapper like should_break_on_system_exit_code() or at minimum updating the docstring to explain the dual semantics.
|
|
||
| if break_on_system_exit is not None: | ||
| codes = set() | ||
| ranges = [] |
There was a problem hiding this comment.
Copilot generated:
-456
Silent opposite-of-intended behavior for string items. If a user writes "breakOnSystemExit": ["1", "2"] (strings instead of ints), all items are silently dropped because none match int, None, or dict. Result: codes=set(), ranges=[] — meaning "never break on anything," the exact opposite of intent. Add a log warning for unrecognized item types, or coerce numeric strings to int.
| if item is None: | ||
| codes.add(None) | ||
| elif isinstance(item, int): | ||
| codes.add(item) |
There was a problem hiding this comment.
Copilot generated:
-453
Non-integer range values cause TypeError crash. If a user writes {"from": "abc", "to": "xyz"}, item.get("from", 0) stores the string. Later in ignore_system_exit_code, "abc" <= code <= "xyz" (where code is an int) raises TypeError in Python 3. This crashes during exception handling. Validate that range_from and range_to are ints during parsing, and skip with a log warning if not.
| if item is None: | ||
| codes.add(None) | ||
| elif isinstance(item, int): | ||
| codes.add(item) |
There was a problem hiding this comment.
Copilot generated:
-453
No validation that from ≤ to in ranges. {"from": 100, "to": 3} silently matches nothing. While fail-safe, a pydev_log.info warning for inverted ranges would save users debugging time when their configuration doesn't work as expected.
| self.api.set_show_return_values(py_db, self._options.show_return_value) | ||
|
|
||
| if not self._options.break_system_exit_zero: | ||
| break_on_system_exit = args.get("breakOnSystemExit", None) |
There was a problem hiding this comment.
Copilot generated:
-456
Consider extracting the breakOnSystemExit parsing into a small helper function (e.g., _parse_break_on_system_exit(args)) that validates input and returns (codes, ranges) or None. This would isolate the parsing logic from the large _set_arguments method and make validation easier to test independently.
| @@ -0,0 +1,48 @@ | |||
| --- | |||
There was a problem hiding this comment.
Copilot generated:
📍 .github/skills/django/SKILL.md (and all 7 skill files)
The Rules reviewer found these skill files are under .github/skills/ instead of the repo-canonical .claude/skills/ directory. The customization loader is scoped to .claude/skills/*/SKILL.md, so these files won't be discovered. Move all seven to .claude/skills/<name>/SKILL.md and update PythonSelfImproving.selfEval.json's skillsDir accordingly.
This MR contains the following updates: | Package | Type | Update | Change | OpenSSF | |---|---|---|---|---| | [debugpy](https://aka.ms/debugpy) ([source](https://github.com/microsoft/debugpy)) | dev | patch | `1.8.20` → `1.8.21` | [](https://securityscorecards.dev/viewer/?uri=github.com/microsoft/debugpy) | | [numpy](https://github.com/numpy/numpy) ([changelog](https://numpy.org/doc/stable/release)) | dependencies | patch | `2.4.4` → `2.4.6` | [](https://securityscorecards.dev/viewer/?uri=github.com/numpy/numpy) | | [pydantic-settings](https://github.com/pydantic/pydantic-settings) ([changelog](https://github.com/pydantic/pydantic-settings/releases)) | dependencies | patch | `2.14.0` → `2.14.2` | [](https://securityscorecards.dev/viewer/?uri=github.com/pydantic/pydantic-settings) | | [python-multipart](https://github.com/Kludex/python-multipart) ([changelog](https://github.com/Kludex/python-multipart/blob/master/CHANGELOG.md)) | dependencies | patch | `^0.0.22` → `^0.0.32` | [](https://securityscorecards.dev/viewer/?uri=github.com/Kludex/python-multipart) | | [types-requests](https://github.com/python/typeshed) ([changelog](https://github.com/typeshed-internal/stub_uploader/blob/main/data/changelogs/requests.md)) | dependencies | patch | `2.32.0.20240523` → `2.32.4.20260324` | [](https://securityscorecards.dev/viewer/?uri=github.com/python/typeshed) | --- ### Release Notes <details> <summary>microsoft/debugpy (debugpy)</summary> ### [`v1.8.21`](https://github.com/microsoft/debugpy/releases/tag/v1.8.21): debugpy v1.8.21 [Compare Source](microsoft/debugpy@v1.8.20...v1.8.21) Fixes for: - Return evaluate result in DAP response body instead of writing to stdout: [#​2027](microsoft/debugpy#2027) - Prevent invalid `scopes` request from crashing debug session: [#​2026](microsoft/debugpy#2026) - Skip uninitialized `__slots__` in variable resolver: [#​2024](microsoft/debugpy#2024) - Handle `-c` arguments that are `bytes` instead of `str`: [#​2021](microsoft/debugpy#2021) - Fix evaluation of variables from chained exception frames: [#​2018](microsoft/debugpy#2018) - `ContinueRequest` with a specific `threadId` no longer resumes all threads (in-process adapter): [#​2012](microsoft/debugpy#2012) - Avoid strong reference to exceptions during unwind: [#​2008](microsoft/debugpy#2008) - Show error message on evaluate failures in the hover context: [#​2006](microsoft/debugpy#2006) - Display `dlerror` output when `dlopen` fails: [#​2000](microsoft/debugpy#2000) - Replace removed `pkgutil.get_loader` with `importlib.util.find_spec` in `get_fullname`: [#​1998](microsoft/debugpy#1998) Enhancements: - Add option to ignore all system exit codes: [#​2017](microsoft/debugpy#2017) - Pull changes from pydevd up to March 2026: [#​2010](microsoft/debugpy#2010) Infrastructure work: - Suppress Flawfinder false positives on Cython memcpy / read-loop iterators (TSA [#​2816216](https://github.com/microsoft/debugpy/issues/2816216), [#​2816217](https://github.com/microsoft/debugpy/issues/2816217), [#​2816218](https://github.com/microsoft/debugpy/issues/2816218), [#​2816219](https://github.com/microsoft/debugpy/issues/2816219), [#​2816220](https://github.com/microsoft/debugpy/issues/2816220)): [#​2028](microsoft/debugpy#2028), [#​2029](microsoft/debugpy#2029), [#​2030](microsoft/debugpy#2030), [#​2031](microsoft/debugpy#2031), [#​2032](microsoft/debugpy#2032) Thanks to [@​maxbachmann](https://github.com/maxbachmann), [@​mfussenegger](https://github.com/mfussenegger), and [@​sambrightman](https://github.com/sambrightman) for the commits. </details> <details> <summary>numpy/numpy (numpy)</summary> ### [`v2.4.6`](https://github.com/numpy/numpy/releases/tag/v2.4.6): (May 18, 2026) [Compare Source](numpy/numpy@v2.4.5...v2.4.6) ### NumPy 2.4.6 Release Notes NumPy 2.4.6 is a quick release that fixes a regression discovered in the 2.4.5 release. This release supports Python versions 3.11-3.14 #### Contributors A total of 4 people contributed to this release. People with a "+" by their names contributed a patch for the first time. - !EarlMilktea - Charles Harris - Sebastian Berg - Warren Weckesser #### Pull requests merged A total of 4 pull requests were merged for this release. - [#​31444](numpy/numpy#31444): MAINT: Prepare 2.4.x for further development - [#​31453](numpy/numpy#31453): BUG: Fix regression in `arr.conj()` - [#​31459](numpy/numpy#31459): BUG: `np.linalg.svd(..., hermitian=True)` returns non-unitary... - [#​31460](numpy/numpy#31460): BUG: Don't call INCREF/DECREF on descr in NpyStringAcquireAllocator... ### [`v2.4.5`](https://github.com/numpy/numpy/releases/tag/v2.4.5): (May 15, 2026) [Compare Source](numpy/numpy@v2.4.4...v2.4.5) ### NumPy 2.4.5 Release Notes NumPy 2.4.5 is a patch release that fixes bugs discovered after the 2.4.4 release, has some typing improvements, and maintains infrastructure. This release supports Python versions 3.11-3.14 #### Contributors A total of 17 people contributed to this release. People with a "+" by their names contributed a patch for the first time. - Aleksei Nikiforov - Anarion Zuo + - Ankit Ahlawat - Breno Favaretto + - Charles Harris - Igor Krivenko + - Ijtihed Kilani + - Joren Hammudoglu - Maarten Baert + - Matti Picus - Nathan Goldbaum - Praneeth Kodumagulla + - Ralf Gommers - RoomWithOutRoof + - Sebastian Berg - Warren Weckesser - div + #### Pull requests merged A total of 28 pull requests were merged for this release. - [#​31093](numpy/numpy#31093): MAINT: Prepare 2.4.x for further development - [#​31182](numpy/numpy#31182): TYP: fix `np.shape` assignability issue for python lists ([#​31171](numpy/numpy#31171)) - [#​31197](numpy/numpy#31197): ENH: Return rank 0 for empty matrices in matrix\_rank ([#​30422](numpy/numpy#30422)) - [#​31198](numpy/numpy#31198): CI/BUG: add native jobs for s390x, fix bug in `pack_inner`... - [#​31199](numpy/numpy#31199): BUG: f2py map complex\_long\_double to NPY\_CLONGDOUBLE - [#​31205](numpy/numpy#31205): MAINT: f2py: Stop setting re.\_MAXCACHE to 50. - [#​31206](numpy/numpy#31206): BUG: fix heap buffer overflow in timedelta to string casts - [#​31207](numpy/numpy#31207): MAINT: Rename ppc64le and s390x workflow ([#​31121](numpy/numpy#31121)) - [#​31208](numpy/numpy#31208): BUG: Fix matvec/vecmat in-place aliasing (out=input produces... - [#​31209](numpy/numpy#31209): TYP: `tile`: accept numpy scalars and arrays as second argument... - [#​31211](numpy/numpy#31211): DEP: Undo deprecation for np.dtype() signature used by old pickles... - [#​31212](numpy/numpy#31212): REV: Manual revert of float16 svml use ([#​31178](numpy/numpy#31178)) - [#​31222](numpy/numpy#31222): TYP: `ix_` fix for boolean and non-1d input ([#​31218](numpy/numpy#31218)) - [#​31329](numpy/numpy#31329): BUG: incorrect temp elision for new-style (NEP 43) user-defined... - [#​31330](numpy/numpy#31330): TYP: fix sliding\_window\_view axis parameter typing - [#​31335](numpy/numpy#31335): BUG: Prevent deadlock due to downstream importing NumPy in dlopen... - [#​31336](numpy/numpy#31336): BUG: Fix segfault in nditer.multi\_index when \_\_getitem\_\_ raises... - [#​31338](numpy/numpy#31338): TYP: Fix ruff lint error - [#​31357](numpy/numpy#31357): BUG: fix memory leak in np.zeros when fill-zero loop raises ([#​31320](numpy/numpy#31320)) - [#​31358](numpy/numpy#31358): BUG: np.einsum() fails with a 0-dimensional out argument and... - [#​31379](numpy/numpy#31379): BUG: Fix signed overflow issue in npy\_gcd for INT\_MIN on s390x... - [#​31383](numpy/numpy#31383): CI: remove Cirrus CI FreeBSD job ([#​31380](numpy/numpy#31380)) - [#​31390](numpy/numpy#31390): BUILD: newer MKL uses so.3 - [#​31391](numpy/numpy#31391): BLD/MAINT: improve support for Intel LLVM compilers - [#​31401](numpy/numpy#31401): BUG: Avoid UB in [safe]()\[add,sub,mul] helpers ([#​31396](numpy/numpy#31396)) - [#​31402](numpy/numpy#31402): BUG: exclude \_\_pycache\_\_ directories from wheels ([#​31397](numpy/numpy#31397)) - [#​31404](numpy/numpy#31404): TYP: `_NestedSequence` type parameter default to work around... - [#​31426](numpy/numpy#31426): TYP: Fix `DTypeLike` runtime type-checker support ([#​31425](numpy/numpy#31425)) </details> <details> <summary>pydantic/pydantic-settings (pydantic-settings)</summary> ### [`v2.14.2`](https://github.com/pydantic/pydantic-settings/releases/tag/v2.14.2) [Compare Source](pydantic/pydantic-settings@v2.14.1...v2.14.2) #### What's Changed This is a security patch release. - Prevent `NestedSecretsSettingsSource` from following symlinks outside `secrets_dir` by [@​hramezani](https://github.com/hramezani) in [#​889](pydantic/pydantic-settings#889) - Prepare release 2.14.2 by [@​hramezani](https://github.com/hramezani) in [#​890](pydantic/pydantic-settings#890) ##### Security Fixes [GHSA-4xgf-cpjx-pc3j](GHSA-4xgf-cpjx-pc3j): `NestedSecretsSettingsSource` with `secrets_nested_subdir=True` could follow a symbolic link inside `secrets_dir` pointing outside it, reading out-of-tree files into settings values and bypassing the `secrets_dir_max_size` cap. Affected versions: `>= 2.12.0, < 2.14.2`. **Full Changelog**: <pydantic/pydantic-settings@v2.14.1...v2.14.2> ### [`v2.14.1`](https://github.com/pydantic/pydantic-settings/releases/tag/v2.14.1) [Compare Source](pydantic/pydantic-settings@v2.14.0...v2.14.1) #### What's Changed - Bump the python-packages group with 4 updates by [@​dependabot](https://github.com/dependabot)\[bot] in [#​850](pydantic/pydantic-settings#850) - Bump the python-packages group with 5 updates by [@​dependabot](https://github.com/dependabot)\[bot] in [#​854](pydantic/pydantic-settings#854) - Bump the github-actions group with 3 updates by [@​dependabot](https://github.com/dependabot)\[bot] in [#​853](pydantic/pydantic-settings#853) - Bump the python-packages group with 2 updates by [@​dependabot](https://github.com/dependabot)\[bot] in [#​856](pydantic/pydantic-settings#856) - Fix field named `cls` conflicting with classmethod parameter by [@​hramezani](https://github.com/hramezani) in [#​858](pydantic/pydantic-settings#858) - Prepare release 2.14.1 by [@​hramezani](https://github.com/hramezani) in [#​859](pydantic/pydantic-settings#859) **Full Changelog**: <pydantic/pydantic-settings@v2.14.0...v2.14.1> </details> <details> <summary>Kludex/python-multipart (python-multipart)</summary> ### [`v0.0.32`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0032-2026-06-04) [Compare Source](Kludex/python-multipart@0.0.31...0.0.32) - Speed up partial-boundary scanning for CR/LF-dense part data [#​300](Kludex/python-multipart#300). ### [`v0.0.31`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0031-2026-06-04) [Compare Source](Kludex/python-multipart@0.0.30...0.0.31) - Speed up multipart header parsing and callback dispatch [#​295](Kludex/python-multipart#295). - Bound header field name size before validating [#​296](Kludex/python-multipart#296). - Validate `Content-Length` is non-negative in `parse_form` [#​297](Kludex/python-multipart#297). ### [`v0.0.30`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0030-2026-05-31) [Compare Source](Kludex/python-multipart@0.0.29...0.0.30) - Parse `application/x-www-form-urlencoded` bodies per the WHATWG URL standard, treating only `&` as a field separator [#​290](Kludex/python-multipart#290). - Ignore RFC 2231/5987 extended parameters (`name*`, `filename*`) in `parse_options_header`, keeping the plain parameter authoritative per [RFC 7578 §4.2](https://datatracker.ietf.org/doc/html/rfc7578#section-4.2) [#​291](Kludex/python-multipart#291). ### [`v0.0.29`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0029-2026-05-17) [Compare Source](Kludex/python-multipart@0.0.28...0.0.29) - Handle malformed RFC 2231 continuations in `parse_options_header` [#​270](Kludex/python-multipart#270). ### [`v0.0.28`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0028-2026-05-10) [Compare Source](Kludex/python-multipart@0.0.27...0.0.28) - Speed up partial-boundary tail scan via `bytes.find` [#​281](Kludex/python-multipart#281). - Cap multipart boundary length at 256 bytes [#​282](Kludex/python-multipart#282). ### [`v0.0.27`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0027-2026-04-27) [Compare Source](Kludex/python-multipart@0.0.26...0.0.27) - Add multipart header limits [#​267](Kludex/python-multipart#267). - Pass parse offsets via constructors [#​268](Kludex/python-multipart#268). ### [`v0.0.26`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0026-2026-04-10) [Compare Source](Kludex/python-multipart@0.0.25...0.0.26) - Skip preamble before the first multipart boundary more efficiently [#​262](Kludex/python-multipart#262). - Silently discard epilogue data after the closing multipart boundary [#​259](Kludex/python-multipart#259). ### [`v0.0.25`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0025-2026-04-10) [Compare Source](Kludex/python-multipart@0.0.24...0.0.25) - Add MIME content type info to `File` [#​143](Kludex/python-multipart#143). - Handle CTE values case-insensitively [#​258](Kludex/python-multipart#258). - Remove custom `FormParser` classes [#​257](Kludex/python-multipart#257). - Add `UPLOAD_DELETE_TMP` to `FormParser` config [#​254](Kludex/python-multipart#254). - Emit `field_end` for trailing bare field names on finalize [#​230](Kludex/python-multipart#230). - Handle multipart headers case-insensitively [#​252](Kludex/python-multipart#252). - Apply Apache-2.0 properly [#​247](Kludex/python-multipart#247). ### [`v0.0.24`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0024-2026-04-05) [Compare Source](Kludex/python-multipart@0.0.23...0.0.24) - Validate `chunk_size` in `parse_form()` [#​244](Kludex/python-multipart#244). ### [`v0.0.23`](https://github.com/Kludex/python-multipart/blob/HEAD/CHANGELOG.md#0023-2026-04-05) [Compare Source](Kludex/python-multipart@0.0.22...0.0.23) - Remove unused `trust_x_headers` parameter and `X-File-Name` fallback [#​196](Kludex/python-multipart#196). - Return processed length from `QuerystringParser._internal_write` [#​229](Kludex/python-multipart#229). - Cleanup metadata dunders from `__init__.py` [#​227](Kludex/python-multipart#227). </details> --- - [ ] <!-- rebase-check -->If you want to rebase/retry this MR, check this box --- This MR has been generated by [Mend Renovate](https://github.com/renovatebot/renovate). <!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0My4xMTAuMTYiLCJ1cGRhdGVkSW5WZXIiOiI0My4yNDYuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIiwicmVub3ZhdGUiXX0=--> See merge request swiss-armed-forces/cyber-command/cea/loom!460 Co-authored-by: Loom MR Pipeline Trigger <group_103951964_bot_9504bb8dead6d4e406ad817a607f24be@noreply.gitlab.com> Co-authored-by: shrewd-laidback palace <shrewd-laidback-palace-736-c41-2c1-e464fc974@swiss-armed-forces-open-source.ch>
Potentially a solution for #1591.
Adds a new launch.json entry that allows the user to specify the breakOnSystemExit codes. Like so:
{ "name": "Python: Current File", "type": "debugpy", "request": "launch", "program": "${file}", "breakOnSystemExit": [] }That launch.json will NEVER break on System.exit. The default is break on everything except zero or None.
You can also specify ranges:
{ "name": "Python: Current File", "type": "debugpy", "request": "launch", "program": "${file}", "breakOnSystemExit": [0, {"from": 3, "to": 100}] }That launch.json would NOT break on 1,2 but break on everything else.