arelle-release 2.37.18__py3-none-any.whl → 2.37.20__py3-none-any.whl

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.

Potentially problematic release.


This version of arelle-release might be problematic. Click here for more details.

Files changed (59) hide show
  1. arelle/CntlrWinMain.py +4 -1
  2. arelle/FileSource.py +2 -2
  3. arelle/ModelInstanceObject.py +1 -1
  4. arelle/ModelValue.py +1 -0
  5. arelle/ModelXbrl.py +1 -1
  6. arelle/PythonUtil.py +132 -24
  7. arelle/ViewWinTree.py +15 -9
  8. arelle/_version.py +2 -2
  9. arelle/formula/XPathContext.py +22 -22
  10. arelle/formula/XPathParser.py +2 -2
  11. arelle/plugin/OimTaxonomy/ModelValueMore.py +15 -0
  12. arelle/plugin/OimTaxonomy/ValidateDTS.py +484 -0
  13. arelle/plugin/OimTaxonomy/ViewXbrlTxmyObj.py +239 -0
  14. arelle/plugin/OimTaxonomy/XbrlAbstract.py +16 -0
  15. arelle/plugin/OimTaxonomy/XbrlConcept.py +68 -0
  16. arelle/plugin/OimTaxonomy/XbrlConst.py +261 -0
  17. arelle/plugin/OimTaxonomy/XbrlCube.py +91 -0
  18. arelle/plugin/OimTaxonomy/XbrlDimension.py +38 -0
  19. arelle/plugin/OimTaxonomy/XbrlDts.py +152 -0
  20. arelle/plugin/OimTaxonomy/XbrlEntity.py +16 -0
  21. arelle/plugin/OimTaxonomy/XbrlGroup.py +22 -0
  22. arelle/plugin/OimTaxonomy/XbrlImportedTaxonomy.py +22 -0
  23. arelle/plugin/OimTaxonomy/XbrlLabel.py +31 -0
  24. arelle/plugin/OimTaxonomy/XbrlNetwork.py +100 -0
  25. arelle/plugin/OimTaxonomy/XbrlProperty.py +28 -0
  26. arelle/plugin/OimTaxonomy/XbrlReference.py +33 -0
  27. arelle/plugin/OimTaxonomy/XbrlReport.py +24 -0
  28. arelle/plugin/OimTaxonomy/XbrlTableTemplate.py +35 -0
  29. arelle/plugin/OimTaxonomy/XbrlTaxonomy.py +93 -0
  30. arelle/plugin/OimTaxonomy/XbrlTaxonomyObject.py +154 -0
  31. arelle/plugin/OimTaxonomy/XbrlTransform.py +17 -0
  32. arelle/plugin/OimTaxonomy/XbrlTypes.py +23 -0
  33. arelle/plugin/OimTaxonomy/XbrlUnit.py +17 -0
  34. arelle/plugin/OimTaxonomy/__init__.py +1037 -0
  35. arelle/plugin/OimTaxonomy/resources/iso4217.json +4479 -0
  36. arelle/plugin/OimTaxonomy/resources/oim-taxonomy-schema.json +935 -0
  37. arelle/plugin/OimTaxonomy/resources/ref.json +333 -0
  38. arelle/plugin/OimTaxonomy/resources/transform-types.json +2481 -0
  39. arelle/plugin/OimTaxonomy/resources/types.json +727 -0
  40. arelle/plugin/OimTaxonomy/resources/utr.json +3046 -0
  41. arelle/plugin/OimTaxonomy/resources/xbrlSpec.json +1082 -0
  42. arelle/plugin/saveOIMTaxonomy.py +311 -0
  43. arelle/plugin/validate/NL/PluginValidationDataExtension.py +35 -1
  44. arelle/plugin/validate/NL/__init__.py +7 -0
  45. arelle/plugin/validate/NL/rules/nl_kvk.py +144 -2
  46. {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/METADATA +3 -1
  47. {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/RECORD +59 -24
  48. tests/integration_tests/validation/README.md +2 -0
  49. tests/integration_tests/validation/conformance_suite_configurations/nl_inline_2024.py +19 -5
  50. tests/integration_tests/validation/run_conformance_suites.py +10 -1
  51. tests/integration_tests/validation/validation_util.py +10 -5
  52. tests/unit_tests/arelle/test_frozen_dict.py +176 -0
  53. tests/unit_tests/arelle/test_frozen_ordered_set.py +315 -0
  54. tests/unit_tests/arelle/test_import.py +1 -0
  55. tests/unit_tests/arelle/test_ordered_set.py +272 -0
  56. {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/WHEEL +0 -0
  57. {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/entry_points.txt +0 -0
  58. {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/licenses/LICENSE.md +0 -0
  59. {arelle_release-2.37.18.dist-info → arelle_release-2.37.20.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,315 @@
1
+ from collections.abc import Iterable
2
+
3
+ import pytest
4
+
5
+ from arelle.PythonUtil import FrozenOrderedSet, OrderedSet
6
+
7
+
8
+ class TestFrozenOrderedSet:
9
+ def test_empty_initialization(self):
10
+ fos = FrozenOrderedSet()
11
+ assert len(fos) == 0
12
+ assert not fos
13
+ assert list(fos) == []
14
+
15
+ def test_initialization_with_list(self):
16
+ fos = FrozenOrderedSet([1, 2, 3])
17
+ assert list(fos) == [1, 2, 3]
18
+ assert len(fos) == 3
19
+
20
+ def test_initialization_with_tuple(self):
21
+ fos = FrozenOrderedSet((4, 5, 6))
22
+ assert list(fos) == [4, 5, 6]
23
+
24
+ def test_initialization_with_string(self):
25
+ fos = FrozenOrderedSet("abc")
26
+ assert list(fos) == ["a", "b", "c"]
27
+
28
+ def test_initialization_with_set(self):
29
+ fos = FrozenOrderedSet({7, 8, 9})
30
+ assert len(fos) == 3
31
+ assert 7 in fos
32
+ assert 8 in fos
33
+ assert 9 in fos
34
+
35
+ def test_initialization_with_ordered_set(self):
36
+ fos = FrozenOrderedSet(OrderedSet([7, 8, 9]))
37
+ assert len(fos) == 3
38
+ assert 7 in fos
39
+ assert 8 in fos
40
+ assert 9 in fos
41
+
42
+ def test_initialization_with_duplicates(self):
43
+ fos = FrozenOrderedSet([1, 2, 2, 3, 1, 4])
44
+ assert list(fos) == [1, 2, 3, 4]
45
+ assert len(fos) == 4
46
+
47
+ def test_contains(self):
48
+ fos = FrozenOrderedSet([1, 2, 3, "a", "b"])
49
+
50
+ assert 1 in fos
51
+ assert 2 in fos
52
+ assert 3 in fos
53
+
54
+ assert 4 not in fos
55
+ assert None not in fos
56
+
57
+ def test_len(self):
58
+ assert len(FrozenOrderedSet()) == 0
59
+ assert len(FrozenOrderedSet([1])) == 1
60
+ assert len(FrozenOrderedSet([1, 2, 3])) == 3
61
+ assert len(FrozenOrderedSet([1, 1, 2, 2, 3])) == 3
62
+
63
+ def test_iteration(self):
64
+ fos = FrozenOrderedSet(["first", "second", "third"])
65
+ result = []
66
+ for item in fos:
67
+ result.append(item)
68
+ assert result == ["first", "second", "third"]
69
+
70
+ def test_reversed_iteration(self):
71
+ fos = FrozenOrderedSet(["first", "second", "third"])
72
+ result = list(reversed(fos))
73
+ assert result == ["third", "second", "first"]
74
+
75
+ def test_repr(self):
76
+ # Empty set
77
+ fos_empty = FrozenOrderedSet()
78
+ assert repr(fos_empty) == "FrozenOrderedSet()"
79
+
80
+ # Non-empty set
81
+ fos = FrozenOrderedSet([1, 2, 3])
82
+ assert repr(fos) == "FrozenOrderedSet((1, 2, 3))"
83
+
84
+ # With strings
85
+ fos_str = FrozenOrderedSet(["a", "b"])
86
+ assert repr(fos_str) == "FrozenOrderedSet(('a', 'b'))"
87
+
88
+ def test_equality_with_frozen_ordered_set(self):
89
+ fos1 = FrozenOrderedSet([1, 2, 3])
90
+ fos2 = FrozenOrderedSet([1, 2, 3])
91
+ fos3 = FrozenOrderedSet([3, 2, 1])
92
+ fos4 = FrozenOrderedSet([1, 2, 3, 4])
93
+
94
+ assert fos1 == fos2
95
+ assert fos1 != fos3
96
+ assert fos1 != fos4
97
+ assert FrozenOrderedSet() == FrozenOrderedSet()
98
+
99
+ def test_equality_with_ordered_set(self):
100
+ fos = FrozenOrderedSet([1, 2, 3])
101
+ os1 = OrderedSet([1, 2, 3])
102
+ os2 = OrderedSet([3, 2, 1])
103
+
104
+ assert fos == os1
105
+ assert fos != os2
106
+
107
+ def test_equality_with_other_iterables(self):
108
+ fos = FrozenOrderedSet([1, 2, 3])
109
+
110
+ assert fos == {1, 2, 3}
111
+ assert fos == {3, 2, 1}
112
+ assert fos == [1, 2, 3]
113
+ assert fos == [3, 2, 1]
114
+ assert fos == (1, 2, 3)
115
+ assert fos == (3, 2, 1)
116
+ assert fos != [1, 2, 4]
117
+ assert fos != {1, 2, 4}
118
+
119
+ def test_equality_with_non_iterables(self):
120
+ fos = FrozenOrderedSet([1, 2, 3])
121
+
122
+ assert fos != 42
123
+ assert fos != "123"
124
+ assert fos != None
125
+
126
+ def test_hashable(self):
127
+ fos1 = FrozenOrderedSet([1, 2, 3])
128
+ fos2 = FrozenOrderedSet([1, 2, 3])
129
+ fos3 = FrozenOrderedSet([3, 2, 1])
130
+
131
+ assert hash(fos1) == hash(fos2)
132
+ assert hash(fos1) != hash(fos3)
133
+
134
+ d = {fos1: "value1", fos3: "value3"}
135
+ assert d[fos1] == "value1"
136
+ assert d[fos2] == "value1"
137
+ assert d[fos3] == "value3"
138
+
139
+ s = {fos1, fos2, fos3}
140
+ assert len(s) == 2
141
+
142
+ def test_hash_consistency(self):
143
+ fos = FrozenOrderedSet([1, 2, 3])
144
+ hash1 = hash(fos)
145
+ hash2 = hash(fos)
146
+ hash3 = hash(fos)
147
+
148
+ assert hash1 == hash2
149
+ assert hash2 == hash3
150
+
151
+ def test_immutability(self):
152
+ fos = FrozenOrderedSet([1, 2, 3])
153
+
154
+ assert not hasattr(fos, "add")
155
+ assert not hasattr(fos, "remove")
156
+ assert not hasattr(fos, "discard")
157
+ assert not hasattr(fos, "pop")
158
+ assert not hasattr(fos, "clear")
159
+ assert not hasattr(fos, "update")
160
+
161
+ def test_set_operations_type_compatibility(self):
162
+ fos = FrozenOrderedSet([1, 2, 3])
163
+
164
+ assert isinstance(fos, Iterable)
165
+
166
+ def test_with_unhashable_types(self):
167
+ with pytest.raises(TypeError):
168
+ FrozenOrderedSet([[1, 2], [3, 4]])
169
+
170
+ with pytest.raises(TypeError):
171
+ FrozenOrderedSet([{1: 2}, {3: 4}])
172
+
173
+ def test_order_preservation_complex(self):
174
+ fos = FrozenOrderedSet([3, 1, 4, 1, 5, 9, 2, 6, 5])
175
+ expected_order = [3, 1, 4, 5, 9, 2, 6]
176
+ assert list(fos) == expected_order
177
+
178
+ def test_boolean_evaluation(self):
179
+ assert not FrozenOrderedSet()
180
+ assert FrozenOrderedSet([1])
181
+ assert FrozenOrderedSet([0])
182
+ assert FrozenOrderedSet([None])
183
+
184
+ def test_large_dataset(self):
185
+ large_list = list(range(1000))
186
+ fos = FrozenOrderedSet(large_list)
187
+
188
+ assert len(fos) == 1000
189
+ assert list(fos) == large_list
190
+ assert 500 in fos
191
+ assert 1000 not in fos
192
+
193
+ def test_nested_iteration(self):
194
+ fos = FrozenOrderedSet(["a", "b", "c"])
195
+
196
+ iter1 = iter(fos)
197
+ iter2 = iter(fos)
198
+
199
+ assert next(iter1) == "a"
200
+ assert next(iter2) == "a"
201
+ assert next(iter1) == "b"
202
+ assert next(iter2) == "b"
203
+
204
+ def test_edge_cases_empty_string_and_zero(self):
205
+ fos = FrozenOrderedSet(["", 0, False, None])
206
+
207
+ assert len(fos) == 3
208
+ assert "" in fos
209
+ assert 0 in fos
210
+ assert False in fos
211
+ assert None in fos
212
+
213
+ assert list(fos) == ["", 0, None]
214
+
215
+ def test_generator_as_input(self):
216
+
217
+ def gen():
218
+ yield 1
219
+ yield 2
220
+ yield 3
221
+ yield 2
222
+
223
+ fos = FrozenOrderedSet(gen())
224
+ assert list(fos) == [1, 2, 3]
225
+ assert len(fos) == 3
226
+
227
+ def test_comparison_with_different_types(self):
228
+ fos = FrozenOrderedSet([1, 2, 3])
229
+
230
+ assert fos != "not_iterable_comparison"
231
+ assert fos == frozenset([3, 2, 1])
232
+
233
+ def test_index_access(self):
234
+ fos = FrozenOrderedSet([10, 20, 30, 40, 50])
235
+
236
+ assert fos[0] == 10
237
+ assert fos[1] == 20
238
+ assert fos[2] == 30
239
+ assert fos[3] == 40
240
+ assert fos[4] == 50
241
+
242
+ assert fos[-1] == 50
243
+ assert fos[-2] == 40
244
+ assert fos[-3] == 30
245
+ assert fos[-4] == 20
246
+ assert fos[-5] == 10
247
+
248
+ def test_index_access_empty_set(self):
249
+ fos = FrozenOrderedSet()
250
+
251
+ with pytest.raises(IndexError):
252
+ fos[0]
253
+
254
+ with pytest.raises(IndexError):
255
+ fos[-1]
256
+
257
+ def test_index_access_out_of_bounds(self):
258
+ fos = FrozenOrderedSet([1, 2, 3])
259
+
260
+ with pytest.raises(IndexError):
261
+ fos[3]
262
+
263
+ with pytest.raises(IndexError):
264
+ fos[10]
265
+
266
+ with pytest.raises(IndexError):
267
+ fos[-4]
268
+
269
+ with pytest.raises(IndexError):
270
+ fos[-10]
271
+
272
+ def test_index_access_single_element(self):
273
+ fos = FrozenOrderedSet([42])
274
+
275
+ assert fos[0] == 42
276
+ assert fos[-1] == 42
277
+
278
+ with pytest.raises(IndexError):
279
+ fos[1]
280
+
281
+ with pytest.raises(IndexError):
282
+ fos[-2]
283
+
284
+ def test_index_access_with_strings(self):
285
+ fos = FrozenOrderedSet(["apple", "banana", "cherry"])
286
+
287
+ assert fos[0] == "apple"
288
+ assert fos[1] == "banana"
289
+ assert fos[2] == "cherry"
290
+ assert fos[-1] == "cherry"
291
+ assert fos[-2] == "banana"
292
+ assert fos[-3] == "apple"
293
+
294
+ def test_index_access_with_duplicates_removed(self):
295
+ fos = FrozenOrderedSet([5, 3, 5, 1, 3, 7])
296
+
297
+ assert fos[0] == 5
298
+ assert fos[1] == 3
299
+ assert fos[2] == 1
300
+ assert fos[3] == 7
301
+
302
+ with pytest.raises(IndexError):
303
+ fos[4]
304
+
305
+ def test_index_access_invalid_type(self):
306
+ fos = FrozenOrderedSet([1, 2, 3])
307
+
308
+ with pytest.raises(TypeError):
309
+ fos["invalid"] # type: ignore[assignment]
310
+
311
+ with pytest.raises(TypeError):
312
+ fos[1.5] # type: ignore[assignment]
313
+
314
+ with pytest.raises(TypeError):
315
+ fos[None] # type: ignore[assignment]
@@ -17,6 +17,7 @@ KNOWN_FAILURES = frozenset([
17
17
  'arelle.archive.plugin.validate.XFsyntax.xf',
18
18
  'arelle.formula.FormulaEvaluator',
19
19
  ])
20
+
20
21
  # Don't test common third party plugins which may be copied into a developer's workspace.
21
22
  IGNORE_MODULE_PREFIXES = (
22
23
  'arelle.plugin.EDGAR',
@@ -0,0 +1,272 @@
1
+
2
+ import pytest
3
+
4
+ from arelle.PythonUtil import OrderedSet
5
+
6
+
7
+ class TestOrderedSet:
8
+
9
+ def test_init_empty(self):
10
+ os = OrderedSet()
11
+ assert len(os) == 0
12
+ assert list(os) == []
13
+ assert bool(os) is False
14
+
15
+ def test_init_with_iterable(self):
16
+ os = OrderedSet([1, 2, 3, 2, 1])
17
+ assert len(os) == 3
18
+ assert list(os) == [1, 2, 3]
19
+
20
+ def test_add_duplicate_order(self):
21
+ os = OrderedSet()
22
+ os.add(1)
23
+ os.add(2)
24
+ os.add(1)
25
+ assert list(os) == [1, 2]
26
+ assert len(os) == 2
27
+
28
+ def test_contains(self):
29
+ os = OrderedSet([1, 2, 3])
30
+ assert 1 in os
31
+ assert 2 in os
32
+ assert 3 in os
33
+ assert 4 not in os
34
+ assert "1" not in os
35
+
36
+ def test_update(self):
37
+ os = OrderedSet([1, 2])
38
+ os.update([3, 4, 2, 5])
39
+ assert list(os) == [1, 2, 3, 4, 5]
40
+
41
+ def test_update_with_string(self):
42
+ os = OrderedSet(['a', 'b'])
43
+ os.update("bcd")
44
+ assert list(os) == ['a', 'b', 'c', 'd']
45
+
46
+ def test_discard(self):
47
+ os = OrderedSet([1, 2, 3, 4])
48
+ os.discard(2)
49
+ assert list(os) == [1, 3, 4]
50
+
51
+ # Discarding non-existent element should not raise error
52
+ non_existent_element = 10
53
+ os.discard(non_existent_element)
54
+ assert list(os) == [1, 3, 4]
55
+
56
+ def test_discard_from_empty(self):
57
+ os = OrderedSet()
58
+ os.discard(1)
59
+ assert len(os) == 0
60
+
61
+ def test_pop_last(self):
62
+ os = OrderedSet([1, 2, 3, 4])
63
+ result = os.pop()
64
+ assert result == 4
65
+ assert list(os) == [1, 2, 3]
66
+
67
+ def test_pop_first(self):
68
+ os = OrderedSet([1, 2, 3, 4])
69
+ result = os.pop(last=False)
70
+ assert result == 1
71
+ assert list(os) == [2, 3, 4]
72
+
73
+ def test_pop_empty_set(self):
74
+ os = OrderedSet()
75
+ with pytest.raises(KeyError, match="set is empty"):
76
+ os.pop()
77
+
78
+ def test_iteration(self):
79
+ os = OrderedSet([1, 2, 3])
80
+ result = []
81
+ for item in os:
82
+ result.append(item)
83
+ assert result == [1, 2, 3]
84
+
85
+ def test_reversed_iteration(self):
86
+ os = OrderedSet([1, 2, 3])
87
+ result = list(reversed(os))
88
+ assert result == [3, 2, 1]
89
+
90
+ def test_len(self):
91
+ os = OrderedSet()
92
+ assert len(os) == 0
93
+
94
+ os.add(1)
95
+ assert len(os) == 1
96
+
97
+ os.add(2)
98
+ assert len(os) == 2
99
+
100
+ os.add(1) # Duplicate
101
+ assert len(os) == 2
102
+
103
+ def test_bool(self):
104
+ os = OrderedSet()
105
+ assert bool(os) is False
106
+
107
+ os.add(1)
108
+ assert bool(os) is True
109
+
110
+ def test_repr_empty(self):
111
+ os = OrderedSet()
112
+ assert repr(os) == "OrderedSet()"
113
+
114
+ def test_repr_with_elements(self):
115
+ os = OrderedSet([1, 2, 3])
116
+ assert repr(os) == "OrderedSet([1, 2, 3])"
117
+
118
+ def test_eq_with_ordered_set(self):
119
+ os1 = OrderedSet([1, 2, 3])
120
+ os2 = OrderedSet([1, 2, 3])
121
+ os3 = OrderedSet([3, 2, 1])
122
+ os4 = OrderedSet([1, 2])
123
+
124
+ assert os1 == os2
125
+ assert os1 != os3
126
+ assert os1 != os4
127
+
128
+ def test_eq_with_regular_set(self):
129
+ os = OrderedSet([1, 2, 3])
130
+ s = {1, 2, 3}
131
+ s_different = {1, 2}
132
+
133
+ assert os == s
134
+ assert os != s_different
135
+
136
+ def test_eq_with_list(self):
137
+ os = OrderedSet([1, 2, 3])
138
+ lst = [1, 2, 3]
139
+
140
+ assert os == lst
141
+
142
+ def test_eq_with_non_iterable(self):
143
+ os = OrderedSet([1, 2, 3])
144
+ assert os != 42
145
+ assert os != "hello"
146
+
147
+ def test_order_preservation(self):
148
+ os = OrderedSet()
149
+ items = [5, 1, 3, 2, 4]
150
+ for item in items:
151
+ os.add(item)
152
+ assert list(os) == items
153
+
154
+ def test_order_preservation_with_duplicates(self):
155
+ os = OrderedSet()
156
+ os.add(1)
157
+ os.add(2)
158
+ os.add(3)
159
+ os.add(2)
160
+ assert list(os) == [1, 2, 3]
161
+
162
+ def test_complex_operations(self):
163
+ os = OrderedSet([1, 2, 3, 4, 5])
164
+
165
+ os.discard(3)
166
+ os.discard(5)
167
+ assert list(os) == [1, 2, 4]
168
+
169
+ os.add(6)
170
+ os.add(0)
171
+ assert list(os) == [1, 2, 4, 6, 0]
172
+
173
+ os.update([7, 2, 8])
174
+ assert list(os) == [1, 2, 4, 6, 0, 7, 8]
175
+
176
+ last = os.pop()
177
+ first = os.pop(last=False)
178
+ assert last == 8
179
+ assert first == 1
180
+ assert list(os) == [2, 4, 6, 0, 7]
181
+
182
+ def test_empty_set_operations(self):
183
+ os = OrderedSet()
184
+
185
+ assert list(os) == []
186
+ assert list(reversed(os)) == []
187
+
188
+ os.update([])
189
+ assert len(os) == 0
190
+
191
+ def test_single_element_operations(self):
192
+ os = OrderedSet([42])
193
+
194
+ assert len(os) == 1
195
+ assert 42 in os
196
+ assert list(os) == [42]
197
+ assert list(reversed(os)) == [42]
198
+
199
+ result = os.pop()
200
+ assert result == 42
201
+ assert len(os) == 0
202
+
203
+ def test_unhashable_types_not_supported(self):
204
+ os = OrderedSet()
205
+ with pytest.raises(TypeError):
206
+ os.add([1, 2, 3])
207
+
208
+ with pytest.raises(TypeError):
209
+ os.add({1: 2})
210
+
211
+ def test_index_access_basic(self):
212
+ os = OrderedSet([1, 2, 3, 4, 5])
213
+
214
+ assert os[0] == 1
215
+ assert os[1] == 2
216
+ assert os[2] == 3
217
+ assert os[3] == 4
218
+ assert os[4] == 5
219
+
220
+ assert os[-1] == 5
221
+ assert os[-2] == 4
222
+ assert os[-3] == 3
223
+ assert os[-4] == 2
224
+ assert os[-5] == 1
225
+
226
+ def test_index_access_out_of_bounds(self):
227
+ os = OrderedSet([1, 2, 3])
228
+
229
+ with pytest.raises(IndexError):
230
+ os[3]
231
+ with pytest.raises(IndexError):
232
+ os[10]
233
+
234
+ with pytest.raises(IndexError):
235
+ os[-4]
236
+ with pytest.raises(IndexError):
237
+ os[-10]
238
+
239
+ def test_index_access_empty_set(self):
240
+ os = OrderedSet()
241
+
242
+ with pytest.raises(IndexError):
243
+ os[0]
244
+ with pytest.raises(IndexError):
245
+ os[-1]
246
+
247
+ def test_index_access_single_element(self):
248
+ os = OrderedSet([42])
249
+
250
+ assert os[0] == 42
251
+ assert os[-1] == 42
252
+
253
+ with pytest.raises(IndexError):
254
+ os[1]
255
+ with pytest.raises(IndexError):
256
+ os[-2]
257
+
258
+ def test_index_access_after_modifications(self):
259
+ os = OrderedSet([1, 2, 3, 4])
260
+
261
+ os.discard(2)
262
+ assert os[0] == 1
263
+ assert os[1] == 3
264
+ assert os[2] == 4
265
+
266
+ os.add(5)
267
+ assert os[3] == 5
268
+
269
+ os.pop()
270
+ assert len(os) == 3
271
+ with pytest.raises(IndexError):
272
+ os[3]