shrinkray 0.0.2__tar.gz → 25.12.26__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.
Files changed (79) hide show
  1. shrinkray-25.12.26/LICENSE +21 -0
  2. shrinkray-25.12.26/PKG-INFO +183 -0
  3. shrinkray-25.12.26/README.md +144 -0
  4. shrinkray-25.12.26/pyproject.toml +112 -0
  5. shrinkray-25.12.26/src/shrinkray/__init__.py +1 -0
  6. shrinkray-25.12.26/src/shrinkray/__main__.py +375 -0
  7. shrinkray-25.12.26/src/shrinkray/cli.py +70 -0
  8. shrinkray-25.12.26/src/shrinkray/display.py +75 -0
  9. shrinkray-25.12.26/src/shrinkray/formatting.py +108 -0
  10. shrinkray-25.12.26/src/shrinkray/passes/__init__.py +0 -0
  11. shrinkray-25.12.26/src/shrinkray/passes/bytes.py +754 -0
  12. shrinkray-25.12.26/src/shrinkray/passes/clangdelta.py +260 -0
  13. shrinkray-25.12.26/src/shrinkray/passes/definitions.py +132 -0
  14. shrinkray-25.12.26/src/shrinkray/passes/genericlanguages.py +331 -0
  15. shrinkray-25.12.26/src/shrinkray/passes/json.py +97 -0
  16. shrinkray-25.12.26/src/shrinkray/passes/patching.py +288 -0
  17. shrinkray-25.12.26/src/shrinkray/passes/python.py +219 -0
  18. shrinkray-25.12.26/src/shrinkray/passes/sat.py +590 -0
  19. shrinkray-25.12.26/src/shrinkray/passes/sequences.py +89 -0
  20. shrinkray-25.12.26/src/shrinkray/problem.py +470 -0
  21. shrinkray-25.12.26/src/shrinkray/process.py +49 -0
  22. shrinkray-25.12.26/src/shrinkray/py.typed +0 -0
  23. shrinkray-25.12.26/src/shrinkray/reducer.py +466 -0
  24. shrinkray-25.12.26/src/shrinkray/state.py +599 -0
  25. shrinkray-25.12.26/src/shrinkray/subprocess/__init__.py +24 -0
  26. shrinkray-25.12.26/src/shrinkray/subprocess/client.py +220 -0
  27. shrinkray-25.12.26/src/shrinkray/subprocess/protocol.py +141 -0
  28. shrinkray-25.12.26/src/shrinkray/subprocess/worker.py +398 -0
  29. shrinkray-25.12.26/src/shrinkray/tui.py +595 -0
  30. shrinkray-25.12.26/src/shrinkray/ui.py +72 -0
  31. shrinkray-25.12.26/src/shrinkray/work.py +245 -0
  32. shrinkray-25.12.26/src/shrinkray.egg-info/PKG-INFO +183 -0
  33. shrinkray-25.12.26/src/shrinkray.egg-info/SOURCES.txt +64 -0
  34. shrinkray-25.12.26/src/shrinkray.egg-info/entry_points.txt +3 -0
  35. shrinkray-25.12.26/src/shrinkray.egg-info/requires.txt +24 -0
  36. shrinkray-25.12.26/tests/test_byte_reduction_passes.py +240 -0
  37. shrinkray-25.12.26/tests/test_clang_delta.py +429 -0
  38. shrinkray-25.12.26/tests/test_cli.py +130 -0
  39. shrinkray-25.12.26/tests/test_definitions.py +90 -0
  40. shrinkray-25.12.26/tests/test_dimacs_cnf.py +342 -0
  41. shrinkray-25.12.26/tests/test_display.py +135 -0
  42. shrinkray-25.12.26/tests/test_formatting.py +223 -0
  43. shrinkray-25.12.26/tests/test_generic_language.py +382 -0
  44. shrinkray-25.12.26/tests/test_generic_shrinking_properties.py +237 -0
  45. shrinkray-25.12.26/tests/test_json_passes.py +292 -0
  46. shrinkray-25.12.26/tests/test_main.py +1609 -0
  47. shrinkray-25.12.26/tests/test_misc_reduction_performance.py +48 -0
  48. shrinkray-25.12.26/tests/test_patching.py +939 -0
  49. shrinkray-25.12.26/tests/test_problem.py +913 -0
  50. shrinkray-25.12.26/tests/test_process.py +242 -0
  51. shrinkray-25.12.26/tests/test_python_reducers.py +349 -0
  52. shrinkray-25.12.26/tests/test_reducer.py +1432 -0
  53. shrinkray-25.12.26/tests/test_reduction_passes.py +1155 -0
  54. shrinkray-25.12.26/tests/test_sat.py +221 -0
  55. shrinkray-25.12.26/tests/test_state.py +1864 -0
  56. shrinkray-25.12.26/tests/test_subprocess_client.py +995 -0
  57. shrinkray-25.12.26/tests/test_subprocess_integration.py +150 -0
  58. shrinkray-25.12.26/tests/test_subprocess_protocol.py +180 -0
  59. shrinkray-25.12.26/tests/test_subprocess_worker.py +1545 -0
  60. shrinkray-25.12.26/tests/test_tui.py +1720 -0
  61. shrinkray-25.12.26/tests/test_tui_snapshots.py +197 -0
  62. shrinkray-25.12.26/tests/test_ui.py +89 -0
  63. shrinkray-25.12.26/tests/test_work.py +218 -0
  64. shrinkray-0.0.2/PKG-INFO +0 -19
  65. shrinkray-0.0.2/README.md +0 -61
  66. shrinkray-0.0.2/setup.py +0 -44
  67. shrinkray-0.0.2/src/shrinkray/__init__.py +0 -3
  68. shrinkray-0.0.2/src/shrinkray/__main__.py +0 -196
  69. shrinkray-0.0.2/src/shrinkray/cutting.py +0 -316
  70. shrinkray-0.0.2/src/shrinkray/junkdrawer.py +0 -141
  71. shrinkray-0.0.2/src/shrinkray/reducer.py +0 -321
  72. shrinkray-0.0.2/src/shrinkray.egg-info/PKG-INFO +0 -19
  73. shrinkray-0.0.2/src/shrinkray.egg-info/SOURCES.txt +0 -14
  74. shrinkray-0.0.2/src/shrinkray.egg-info/entry_points.txt +0 -3
  75. shrinkray-0.0.2/src/shrinkray.egg-info/not-zip-safe +0 -1
  76. shrinkray-0.0.2/src/shrinkray.egg-info/requires.txt +0 -2
  77. {shrinkray-0.0.2 → shrinkray-25.12.26}/setup.cfg +0 -0
  78. {shrinkray-0.0.2 → shrinkray-25.12.26}/src/shrinkray.egg-info/dependency_links.txt +0 -0
  79. {shrinkray-0.0.2 → shrinkray-25.12.26}/src/shrinkray.egg-info/top_level.txt +0 -0
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright © 2023 David R. MacIver
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,183 @@
1
+ Metadata-Version: 2.4
2
+ Name: shrinkray
3
+ Version: 25.12.26
4
+ Summary: Shrink Ray
5
+ Author-email: "David R. MacIver" <david@drmaciver.com>
6
+ License: MIT
7
+ Project-URL: Homepage, https://github.com/DRMacIver/shrinkray
8
+ Project-URL: Repository, https://github.com/DRMacIver/shrinkray
9
+ Project-URL: Documentation, https://shrinkray.readthedocs.io
10
+ Project-URL: Changelog, https://github.com/DRMacIver/shrinkray/releases
11
+ Classifier: Development Status :: 4 - Beta
12
+ Requires-Python: >=3.12
13
+ Description-Content-Type: text/markdown
14
+ License-File: LICENSE
15
+ Requires-Dist: click>=8.0.1
16
+ Requires-Dist: chardet>=5.2.0
17
+ Requires-Dist: trio>=0.28.0
18
+ Requires-Dist: textual>=0.47.0
19
+ Requires-Dist: humanize>=4.9.0
20
+ Requires-Dist: libcst>=1.1.0
21
+ Requires-Dist: exceptiongroup>=1.2.0
22
+ Requires-Dist: binaryornot>=0.4.4
23
+ Requires-Dist: black
24
+ Provides-Extra: dev
25
+ Requires-Dist: coverage>=7.13.0; extra == "dev"
26
+ Requires-Dist: hypothesis>=6.92.1; extra == "dev"
27
+ Requires-Dist: hypothesmith>=0.3.1; extra == "dev"
28
+ Requires-Dist: pytest; extra == "dev"
29
+ Requires-Dist: pytest-trio; extra == "dev"
30
+ Requires-Dist: pytest-asyncio; extra == "dev"
31
+ Requires-Dist: pytest-textual-snapshot; extra == "dev"
32
+ Requires-Dist: coverage[toml]; extra == "dev"
33
+ Requires-Dist: pygments; extra == "dev"
34
+ Requires-Dist: basedpyright; extra == "dev"
35
+ Requires-Dist: ruff; extra == "dev"
36
+ Requires-Dist: pexpect>=4.9.0; extra == "dev"
37
+ Requires-Dist: pyte>=0.8.2; extra == "dev"
38
+ Dynamic: license-file
39
+
40
+ # Shrink Ray
41
+
42
+ Shrink Ray is a modern multiformat test-case reducer.
43
+
44
+ ## What is test-case reduction?
45
+
46
+ Test-case reduction is the process of automatically taking a *test case* and *reducing* it to something close to a [minimal reproducible example](https://en.wikipedia.org/wiki/Minimal_reproducible_example).
47
+
48
+ That is, you have some file that has some interesting property (usually that it triggers a bug in some software),
49
+ but it is large and complicated and as a result you can't figure out what about the file actually matters.
50
+ You want to be able to trigger the bug with a small, simple, version of it that contains only the features of interest.
51
+
52
+ For example, the following is some Python code that [triggered a bug in libcst](https://github.com/Instagram/LibCST/issues/1061):
53
+
54
+ ```python
55
+ () if 0 else(lambda:())
56
+ ```
57
+
58
+ This was extracted from a large Python file (probably several thousand lines of code) and systematically reduced down to this example.
59
+
60
+ You would obtain this by running `shrinkray breakslibcst.py mytestcase.py`, where `breakslibcst.py` looks something like this:
61
+
62
+ ```python
63
+ import libcst
64
+ import sys
65
+
66
+ if __name__ == '__main__':
67
+ try:
68
+ libcst.parse_module(sys.stdin.read())
69
+ except TypeError:
70
+ sys.exit(0)
71
+ sys.exit(1)
72
+ ```
73
+
74
+ This script exits with 0 if the code passed to it on standard input triggers the relevant bug (that libcst raises a TypeError when parsing this code), and with a non-zero exit code otherwise.
75
+
76
+ shrinkray (or any other test-case reducer) then systematically tries smaller and simpler variants of your original source file until it reduces it to something as small as it can manage.
77
+
78
+ While it runs, you will see the following user interface:
79
+
80
+ ![Demo of shrink ray running](demo.png)
81
+
82
+ When it finishes you will be left with the reduced test case in `mytestcase.py`.
83
+
84
+ Test-case reducers are useful for any tools that handle files with complex formats that can trigger bugs in them. Historically this has been particularly useful for compilers and other programming tools, but in principle it can be used for anything.
85
+
86
+ Most test-case reducers only work well on a few formats. Shrink Ray is designed to be able to support a wide variety of formats, including binary ones, although it's currently best tuned for "things that look like programming languages".
87
+
88
+ ## What makes Shrink Ray distinctive?
89
+
90
+ It's designed to be highly parallel, and work with a very wide variety of formats, through a mix of good generic algorithms and format-specific reduction passes.
91
+
92
+ Currently shrink ray is a "prerelease" version in the sense that there is no official release yet and you're expected to just run off main (don't worry this is easy to do), as it's a bit experimental.
93
+
94
+ That being said this probably doesn't matter that much for the question of whether to use it. It's in the nature of test-case reduction that it doesn't matter all that much if it's bad, because it's still going to do a bunch of work that you didn't have to do by hand. Try it out, see if it works. If it doesn't, please tell me and I'll make it work better.
95
+
96
+ ## Installation
97
+
98
+ Shrink Ray requires Python 3.11 or later, and can be installed using pip.
99
+
100
+ Official releases for shrink ray are infrequent, and I recommend running off main. You can install it as follows:
101
+
102
+ ```
103
+ pipx install shrinkray
104
+ # or
105
+ pipx install git+https://github.com/DRMacIver/shrinkray.git
106
+ ```
107
+
108
+ (if you don't have or want [pipx](https://pypa.github.io/pipx/) you could also do this with pip or `uv pip` and it would work fine)
109
+
110
+ Shrink Ray requires Python 3.11 or later and won't work on earlier versions. If everything is working correctly, it should refuse to install
111
+ on versions it's incompatible with. If you do not have Python 3.11 installed, I recommend [pyenv](https://github.com/pyenv/pyenv) for managing
112
+ Python installs.
113
+
114
+ If you want to use it from the git repo directly, you can do the following:
115
+
116
+ ```
117
+ git clone https://github.com/DRMacIver/shrinkray.git
118
+ cd shrinkray
119
+ python -m venv .venv
120
+ .venv/bin/pip install -e .
121
+ ```
122
+
123
+ You will now have a shrinkray executable in .venv/bin, which you can also put on your path by running `source .venv/bin/activate`.
124
+
125
+ ## Usage
126
+
127
+ Shrink Ray is run as follows:
128
+
129
+ ```
130
+ shrinkray is_interesting.sh my-test-case
131
+ ```
132
+
133
+ Where `my-test-case` is some file you want to reduce and `is_interesting.sh` can be any executable that exits with `0` when a test case passed to it is interesting and non-zero otherwise.
134
+
135
+ Variant test cases are passed to the interestingness test both on STDIN and as a file name passed as an argument. Additionally for creduce compatibility, the file has the same base name as the original test case and is in the current working directory the script is run with. This behaviour can be customised with the `--input-type` argument.
136
+
137
+ `shrinkray --help` will give more usage instructions.
138
+
139
+ ## Supported formats
140
+
141
+ Shrink Ray is fully generic in the sense that it will work with literally any file you give it in any format. However, some formats will work a lot better than others.
142
+
143
+ It has a generic reduction algorithm that should work pretty well with any textual format, and an architecture that is designed to make it easy to add specialised support for specific formats as needed.
144
+
145
+ Additionally, Shrink Ray has special support for the following formats:
146
+
147
+ * C and C++ (via `clang_delta`, which you will have if creduce is installed)
148
+ * Python
149
+ * JSON
150
+ * Dimacs CNF format for SAT problems
151
+
152
+ Most of this support is quite basic and is just designed to deal with specific cases that the generic logic is known
153
+ not to handle well, but it's easy to extend with additional transformations.
154
+ It is also fairly easy to add support for new formats as needed.
155
+
156
+ If you run into a test case and interestingness test that you care about that shrink ray handles badly please let me know and I'll likely see about improving its handling of that format.
157
+
158
+ ## Parallelism
159
+
160
+ You can control the number of parallel tasks shrinkray will run with the `--parallelism` flag. By default this will be the number of CPU cores you have available
161
+
162
+ Shrink Ray is designed to be able to run heavily in parallel, with a basic heuristic of aiming to be embarrassingly parallel when making no progress, mostly sequential when making progress, and smoothly scaling in between the two. It mostly succeeds at this.
163
+
164
+ Currently the bottleneck on scaling to a very large number of cores is how fast the controlling Python program can generate variant test cases to try and pass them to the interestingness test. This isn't well optimised at present and I don't currently have good benchmarks for it, but I'd expect you to be able to get linear speedups on most workflows while running 10-20 test cases in parallel, and to start to struggle past that.
165
+
166
+ This also depends on the performance of the interestingness test - the slower your test is to run, the more you'll be able to scale linearly with the number of cores available.
167
+
168
+ I'm quite interested in getting this part to scale well, so please let me know if you find examples where it doesn't seem to work.
169
+
170
+ ## Bug Reports
171
+
172
+ Shrink Ray is still pretty new and under-tested software, so it definitely has bugs. If you run into any, [please file an issue](https://github.com/DRMacIver/shrinkray/issues).
173
+
174
+ As well as obvious bugs (crashes, etc) I'm also very interested in hearing about usability issues and cases where the reduced test case isn't very good.
175
+
176
+ Requests for new features, new supported formats, etc. also welcome although I'm less likely to jump right on them.
177
+
178
+ ## Sponsorship
179
+
180
+ Shrink Ray is something of a labour of love - I wanted to have a tool that actually put into practice many of my ideas about test-case reduction, as I think the previous state of the art was well behind where I'd like it to be.
181
+
182
+ That being said, it is first and foremost designed to be a useful tool for practical engineering problems.
183
+ If you find it useful as such, please [consider sponsoring my development of it](https://github.com/sponsors/DRMacIver).
@@ -0,0 +1,144 @@
1
+ # Shrink Ray
2
+
3
+ Shrink Ray is a modern multiformat test-case reducer.
4
+
5
+ ## What is test-case reduction?
6
+
7
+ Test-case reduction is the process of automatically taking a *test case* and *reducing* it to something close to a [minimal reproducible example](https://en.wikipedia.org/wiki/Minimal_reproducible_example).
8
+
9
+ That is, you have some file that has some interesting property (usually that it triggers a bug in some software),
10
+ but it is large and complicated and as a result you can't figure out what about the file actually matters.
11
+ You want to be able to trigger the bug with a small, simple, version of it that contains only the features of interest.
12
+
13
+ For example, the following is some Python code that [triggered a bug in libcst](https://github.com/Instagram/LibCST/issues/1061):
14
+
15
+ ```python
16
+ () if 0 else(lambda:())
17
+ ```
18
+
19
+ This was extracted from a large Python file (probably several thousand lines of code) and systematically reduced down to this example.
20
+
21
+ You would obtain this by running `shrinkray breakslibcst.py mytestcase.py`, where `breakslibcst.py` looks something like this:
22
+
23
+ ```python
24
+ import libcst
25
+ import sys
26
+
27
+ if __name__ == '__main__':
28
+ try:
29
+ libcst.parse_module(sys.stdin.read())
30
+ except TypeError:
31
+ sys.exit(0)
32
+ sys.exit(1)
33
+ ```
34
+
35
+ This script exits with 0 if the code passed to it on standard input triggers the relevant bug (that libcst raises a TypeError when parsing this code), and with a non-zero exit code otherwise.
36
+
37
+ shrinkray (or any other test-case reducer) then systematically tries smaller and simpler variants of your original source file until it reduces it to something as small as it can manage.
38
+
39
+ While it runs, you will see the following user interface:
40
+
41
+ ![Demo of shrink ray running](demo.png)
42
+
43
+ When it finishes you will be left with the reduced test case in `mytestcase.py`.
44
+
45
+ Test-case reducers are useful for any tools that handle files with complex formats that can trigger bugs in them. Historically this has been particularly useful for compilers and other programming tools, but in principle it can be used for anything.
46
+
47
+ Most test-case reducers only work well on a few formats. Shrink Ray is designed to be able to support a wide variety of formats, including binary ones, although it's currently best tuned for "things that look like programming languages".
48
+
49
+ ## What makes Shrink Ray distinctive?
50
+
51
+ It's designed to be highly parallel, and work with a very wide variety of formats, through a mix of good generic algorithms and format-specific reduction passes.
52
+
53
+ Currently shrink ray is a "prerelease" version in the sense that there is no official release yet and you're expected to just run off main (don't worry this is easy to do), as it's a bit experimental.
54
+
55
+ That being said this probably doesn't matter that much for the question of whether to use it. It's in the nature of test-case reduction that it doesn't matter all that much if it's bad, because it's still going to do a bunch of work that you didn't have to do by hand. Try it out, see if it works. If it doesn't, please tell me and I'll make it work better.
56
+
57
+ ## Installation
58
+
59
+ Shrink Ray requires Python 3.11 or later, and can be installed using pip.
60
+
61
+ Official releases for shrink ray are infrequent, and I recommend running off main. You can install it as follows:
62
+
63
+ ```
64
+ pipx install shrinkray
65
+ # or
66
+ pipx install git+https://github.com/DRMacIver/shrinkray.git
67
+ ```
68
+
69
+ (if you don't have or want [pipx](https://pypa.github.io/pipx/) you could also do this with pip or `uv pip` and it would work fine)
70
+
71
+ Shrink Ray requires Python 3.11 or later and won't work on earlier versions. If everything is working correctly, it should refuse to install
72
+ on versions it's incompatible with. If you do not have Python 3.11 installed, I recommend [pyenv](https://github.com/pyenv/pyenv) for managing
73
+ Python installs.
74
+
75
+ If you want to use it from the git repo directly, you can do the following:
76
+
77
+ ```
78
+ git clone https://github.com/DRMacIver/shrinkray.git
79
+ cd shrinkray
80
+ python -m venv .venv
81
+ .venv/bin/pip install -e .
82
+ ```
83
+
84
+ You will now have a shrinkray executable in .venv/bin, which you can also put on your path by running `source .venv/bin/activate`.
85
+
86
+ ## Usage
87
+
88
+ Shrink Ray is run as follows:
89
+
90
+ ```
91
+ shrinkray is_interesting.sh my-test-case
92
+ ```
93
+
94
+ Where `my-test-case` is some file you want to reduce and `is_interesting.sh` can be any executable that exits with `0` when a test case passed to it is interesting and non-zero otherwise.
95
+
96
+ Variant test cases are passed to the interestingness test both on STDIN and as a file name passed as an argument. Additionally for creduce compatibility, the file has the same base name as the original test case and is in the current working directory the script is run with. This behaviour can be customised with the `--input-type` argument.
97
+
98
+ `shrinkray --help` will give more usage instructions.
99
+
100
+ ## Supported formats
101
+
102
+ Shrink Ray is fully generic in the sense that it will work with literally any file you give it in any format. However, some formats will work a lot better than others.
103
+
104
+ It has a generic reduction algorithm that should work pretty well with any textual format, and an architecture that is designed to make it easy to add specialised support for specific formats as needed.
105
+
106
+ Additionally, Shrink Ray has special support for the following formats:
107
+
108
+ * C and C++ (via `clang_delta`, which you will have if creduce is installed)
109
+ * Python
110
+ * JSON
111
+ * Dimacs CNF format for SAT problems
112
+
113
+ Most of this support is quite basic and is just designed to deal with specific cases that the generic logic is known
114
+ not to handle well, but it's easy to extend with additional transformations.
115
+ It is also fairly easy to add support for new formats as needed.
116
+
117
+ If you run into a test case and interestingness test that you care about that shrink ray handles badly please let me know and I'll likely see about improving its handling of that format.
118
+
119
+ ## Parallelism
120
+
121
+ You can control the number of parallel tasks shrinkray will run with the `--parallelism` flag. By default this will be the number of CPU cores you have available
122
+
123
+ Shrink Ray is designed to be able to run heavily in parallel, with a basic heuristic of aiming to be embarrassingly parallel when making no progress, mostly sequential when making progress, and smoothly scaling in between the two. It mostly succeeds at this.
124
+
125
+ Currently the bottleneck on scaling to a very large number of cores is how fast the controlling Python program can generate variant test cases to try and pass them to the interestingness test. This isn't well optimised at present and I don't currently have good benchmarks for it, but I'd expect you to be able to get linear speedups on most workflows while running 10-20 test cases in parallel, and to start to struggle past that.
126
+
127
+ This also depends on the performance of the interestingness test - the slower your test is to run, the more you'll be able to scale linearly with the number of cores available.
128
+
129
+ I'm quite interested in getting this part to scale well, so please let me know if you find examples where it doesn't seem to work.
130
+
131
+ ## Bug Reports
132
+
133
+ Shrink Ray is still pretty new and under-tested software, so it definitely has bugs. If you run into any, [please file an issue](https://github.com/DRMacIver/shrinkray/issues).
134
+
135
+ As well as obvious bugs (crashes, etc) I'm also very interested in hearing about usability issues and cases where the reduced test case isn't very good.
136
+
137
+ Requests for new features, new supported formats, etc. also welcome although I'm less likely to jump right on them.
138
+
139
+ ## Sponsorship
140
+
141
+ Shrink Ray is something of a labour of love - I wanted to have a tool that actually put into practice many of my ideas about test-case reduction, as I think the previous state of the art was well behind where I'd like it to be.
142
+
143
+ That being said, it is first and foremost designed to be a useful tool for practical engineering problems.
144
+ If you find it useful as such, please [consider sponsoring my development of it](https://github.com/sponsors/DRMacIver).
@@ -0,0 +1,112 @@
1
+ [project]
2
+ name = "shrinkray"
3
+ version = "25.12.26"
4
+ description = "Shrink Ray"
5
+ authors = [
6
+ {name = "David R. MacIver", email = "david@drmaciver.com"}
7
+ ]
8
+ license = {text = "MIT"}
9
+ readme = "README.md"
10
+ classifiers = [
11
+ "Development Status :: 4 - Beta",
12
+ ]
13
+ requires-python = ">=3.12"
14
+ dependencies = [
15
+ "click>=8.0.1",
16
+ "chardet>=5.2.0",
17
+ "trio>=0.28.0",
18
+ "textual>=0.47.0",
19
+ "humanize>=4.9.0",
20
+ "libcst>=1.1.0",
21
+ "exceptiongroup>=1.2.0",
22
+ "binaryornot>=0.4.4",
23
+ "black",
24
+ ]
25
+
26
+ [project.urls]
27
+ Homepage = "https://github.com/DRMacIver/shrinkray"
28
+ Repository = "https://github.com/DRMacIver/shrinkray"
29
+ Documentation = "https://shrinkray.readthedocs.io"
30
+ Changelog = "https://github.com/DRMacIver/shrinkray/releases"
31
+
32
+ [project.scripts]
33
+ shrinkray = "shrinkray.__main__:main"
34
+ shrinkray-worker = "shrinkray.__main__:worker_main"
35
+
36
+ [project.optional-dependencies]
37
+ dev = [
38
+ "coverage>=7.13.0",
39
+ "hypothesis>=6.92.1",
40
+ "hypothesmith>=0.3.1",
41
+ "pytest",
42
+ "pytest-trio",
43
+ "pytest-asyncio",
44
+ "pytest-textual-snapshot",
45
+ "coverage[toml]",
46
+ "pygments",
47
+ "basedpyright",
48
+ "ruff",
49
+ "pexpect>=4.9.0",
50
+ "pyte>=0.8.2",
51
+ ]
52
+
53
+ [tool.setuptools.packages.find]
54
+ where = ["src"]
55
+
56
+ [tool.coverage.paths]
57
+ source = ["src", "*/site-packages"]
58
+
59
+ [tool.coverage.run]
60
+ branch = true
61
+ source = ["shrinkray"]
62
+ # Use ctrace core instead of sysmon to avoid Python 3.14 async for branch bug
63
+ core = "ctrace"
64
+
65
+ [tool.coverage.report]
66
+ show_missing = true
67
+ fail_under = 100
68
+
69
+ [tool.ruff]
70
+ line-length = 88
71
+ target-version = "py312"
72
+
73
+ [tool.ruff.lint]
74
+ select = ["E", "F", "W", "I", "B", "C4", "UP"]
75
+ ignore = [
76
+ "E501", # line too long - handled by formatter
77
+ "B007", # unused loop variable
78
+ "B023", # function definition in loop
79
+ "B904", # raise without from - intentional in some exception handling
80
+ "C408", # unnecessary dict() call - sometimes more readable
81
+ "UP031", # use format specifiers - % format is fine
82
+ "B018", # useless expression - sometimes intentional for side effects
83
+ "C403", # unnecessary list comprehension - sometimes more readable
84
+ "UP022", # prefer capture_output - explicit is fine
85
+ ]
86
+
87
+ [tool.ruff.lint.isort]
88
+ force-single-line = false
89
+ lines-after-imports = 2
90
+
91
+ [tool.basedpyright]
92
+ include = ["src", "tests"]
93
+ exclude = ["build", "bugs", ".venv", ".venv2"]
94
+ typeCheckingMode = "strict"
95
+ reportMissingTypeStubs = false
96
+ # These are too noisy with third-party libraries that lack type stubs
97
+ reportUnknownVariableType = false
98
+ reportUnknownMemberType = false
99
+ reportUnknownParameterType = false
100
+ reportMissingParameterType = false
101
+ reportUnknownArgumentType = false
102
+ reportUnknownLambdaType = false
103
+ # These are often false positives or stylistic
104
+ reportUnusedFunction = false
105
+ reportMissingTypeArgument = false
106
+ reportPrivateUsage = false # Tests need to access private attributes
107
+ reportIncompatibleMethodOverride = false # Often false positives with textual
108
+ reportUnnecessaryIsInstance = false # Needed for runtime type checking of untrusted input
109
+
110
+ [build-system]
111
+ requires = ["setuptools>=61.0", "wheel"]
112
+ build-backend = "setuptools.build_meta"
@@ -0,0 +1 @@
1
+ """Shrink Ray."""