|
1 | 1 | import codecs |
| 2 | +import gc |
2 | 3 | from collections.abc import Callable, Generator |
3 | 4 | from io import BytesIO |
4 | 5 |
|
@@ -56,32 +57,34 @@ class _UnmatchedFilter(_Rot13Filter): |
56 | 57 | attributes = 'filter=rot13' |
57 | 58 |
|
58 | 59 |
|
| 60 | +def _filter_fixture(name: str, filter: type[Filter]) -> Generator[None, None, None]: |
| 61 | + pygit2.filter_register(name, filter) |
| 62 | + yield |
| 63 | + |
| 64 | + # Collect any FilterLists that may use this filter before unregistering it |
| 65 | + gc.collect() |
| 66 | + |
| 67 | + pygit2.filter_unregister(name) |
| 68 | + |
| 69 | + |
59 | 70 | @pytest.fixture |
60 | 71 | def rot13_filter() -> Generator[None, None, None]: |
61 | | - pygit2.filter_register('rot13', _Rot13Filter) |
62 | | - yield |
63 | | - pygit2.filter_unregister('rot13') |
| 72 | + yield from _filter_fixture('rot13', _Rot13Filter) |
64 | 73 |
|
65 | 74 |
|
66 | 75 | @pytest.fixture |
67 | 76 | def passthrough_filter() -> Generator[None, None, None]: |
68 | | - pygit2.filter_register('passthrough-rot13', _PassthroughFilter) |
69 | | - yield |
70 | | - pygit2.filter_unregister('passthrough-rot13') |
| 77 | + yield from _filter_fixture('passthrough-rot13', _PassthroughFilter) |
71 | 78 |
|
72 | 79 |
|
73 | 80 | @pytest.fixture |
74 | 81 | def buffered_filter() -> Generator[None, None, None]: |
75 | | - pygit2.filter_register('buffered-rot13', _BufferedFilter) |
76 | | - yield |
77 | | - pygit2.filter_unregister('buffered-rot13') |
| 82 | + yield from _filter_fixture('buffered-rot13', _BufferedFilter) |
78 | 83 |
|
79 | 84 |
|
80 | 85 | @pytest.fixture |
81 | 86 | def unmatched_filter() -> Generator[None, None, None]: |
82 | | - pygit2.filter_register('unmatched-rot13', _UnmatchedFilter) |
83 | | - yield |
84 | | - pygit2.filter_unregister('unmatched-rot13') |
| 87 | + yield from _filter_fixture('unmatched-rot13', _UnmatchedFilter) |
85 | 88 |
|
86 | 89 |
|
87 | 90 | def test_filter(testrepo: Repository, rot13_filter: Filter) -> None: |
@@ -153,3 +156,29 @@ def test_filterlist_crlf(testrepo: Repository) -> None: |
153 | 156 |
|
154 | 157 | with pytest.raises(TypeError): |
155 | 158 | 1234 in fl # type: ignore |
| 159 | + |
| 160 | + |
| 161 | +def test_filterlist_rot13(testrepo: Repository, rot13_filter: Filter) -> None: |
| 162 | + fl = testrepo.load_filter_list('hello.txt') |
| 163 | + assert fl is not None |
| 164 | + assert 'rot13' in fl |
| 165 | + |
| 166 | + |
| 167 | +def test_filterlist_dangerous_unregister(testrepo: Repository) -> None: |
| 168 | + pygit2.filter_register('rot13', _Rot13Filter) |
| 169 | + |
| 170 | + fl = testrepo.load_filter_list('hello.txt') |
| 171 | + assert fl is not None |
| 172 | + assert len(fl) == 1 |
| 173 | + assert 'rot13' in fl |
| 174 | + |
| 175 | + # Unregistering a filter that's still in use in a FilterList is dangerous! |
| 176 | + # Our built-in check (that raises RuntimeError) may avert a segfault. |
| 177 | + with pytest.raises(RuntimeError): |
| 178 | + pygit2.filter_unregister('rot13') |
| 179 | + |
| 180 | + # Delete any FilterLists that use the filter, and only then is it safe |
| 181 | + # to unregister the filter. |
| 182 | + del fl |
| 183 | + gc.collect() |
| 184 | + pygit2.filter_unregister('rot13') |
0 commit comments