• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

domdfcoding / domdf_python_tools / 20027381159

08 Dec 2025 12:01PM UTC coverage: 97.275% (-0.04%) from 97.313%
20027381159

push

github

domdfcoding
Make UserFloat hashable again

2 of 2 new or added lines in 1 file covered. (100.0%)

4 existing lines in 2 files now uncovered.

2142 of 2202 relevant lines covered (97.28%)

0.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.24
/domdf_python_tools/bases.py
1
#  !/usr/bin/env python
2
#
3
#  bases.py
4
"""
5
Useful base classes.
6
"""
7
#
8
#  Copyright © 2020 Dominic Davis-Foster <dominic@davis-foster.co.uk>
9
#
10
#  Permission is hereby granted, free of charge, to any person obtaining a copy
11
#  of this software and associated documentation files (the "Software"), to deal
12
#  in the Software without restriction, including without limitation the rights
13
#  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
#  copies of the Software, and to permit persons to whom the Software is
15
#  furnished to do so, subject to the following conditions:
16
#
17
#  The above copyright notice and this permission notice shall be included in all
18
#  copies or substantial portions of the Software.
19
#
20
#  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
21
#  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22
#  MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23
#  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
24
#  DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
25
#  OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
26
#  OR OTHER DEALINGS IN THE SOFTWARE.
27
#
28
#  UserList based on CPython.
29
#  Licensed under the Python Software Foundation License Version 2.
30
#  Copyright © 2001-2020 Python Software Foundation. All rights reserved.
31
#  Copyright © 2000 BeOpen.com. All rights reserved.
32
#  Copyright © 1995-2000 Corporation for National Research Initiatives. All rights reserved.
33
#  Copyright © 1991-1995 Stichting Mathematisch Centrum. All rights reserved.
34
#
35

36
# stdlib
37
from abc import abstractmethod
1✔
38
from numbers import Real
1✔
39
from pprint import pformat
1✔
40
from typing import (
1✔
41
                Any,
42
                Dict,
43
                Iterable,
44
                Iterator,
45
                List,
46
                MutableSequence,
47
                Optional,
48
                SupportsFloat,
49
                Tuple,
50
                Type,
51
                TypeVar,
52
                Union,
53
                overload
54
                )
55

56
# this package
57
from domdf_python_tools._is_match import is_match_with
1✔
58
from domdf_python_tools.doctools import prettify_docstrings
1✔
59
from domdf_python_tools.typing import SupportsIndex
1✔
60

61
__all__ = [
1✔
62
                "Dictable",
63
                "NamedList",
64
                "namedlist",
65
                "UserList",
66
                "UserFloat",
67
                "Lineup",
68
                "_V",
69
                "_LU",
70
                "_T",
71
                "_S",
72
                "_F",
73
                ]
74

75
_F = TypeVar("_F", bound="UserFloat")
1✔
76
_LU = TypeVar("_LU", bound="Lineup")
1✔
77
_S = TypeVar("_S", bound="UserList")
1✔
78
_T = TypeVar("_T")
1✔
79
_V = TypeVar("_V")
1✔
80

81

82
@prettify_docstrings
1✔
83
class Dictable(Iterable[Tuple[str, _V]]):
1✔
84
        """
85
        The basic structure of a class that can be converted into a dictionary.
86
        """
87

88
        @abstractmethod
1✔
89
        def __init__(self, *args, **kwargs):
1✔
UNCOV
90
                pass
×
91

92
        def __repr__(self) -> str:
1✔
93
                return super().__repr__()
1✔
94

95
        def __str__(self) -> str:
1✔
96
                return self.__repr__()
1✔
97

98
        def __iter__(self) -> Iterator[Tuple[str, _V]]:
1✔
99
                """
100
                Iterate over the attributes of the class.
101
                """
102

103
                yield from self.__dict__.items()
1✔
104

105
        def __getstate__(self) -> Dict[str, _V]:
1✔
106
                return self.__dict__
1✔
107

108
        def __setstate__(self, state):
1✔
109
                self.__init__(**state)  # type: ignore[misc]
1✔
110

111
        def __copy__(self):
1✔
112
                return self.__class__(**self.__dict__)
1✔
113

114
        def __deepcopy__(self, memodict={}):
1✔
115
                return self.__copy__()
1✔
116

117
        @property
1✔
118
        @abstractmethod
1✔
119
        def __dict__(self):  # type: ignore[override]
1✔
120
                return dict()  # pragma: no cover (abc)
121

122
        def __eq__(self, other) -> bool:
1✔
123
                if isinstance(other, self.__class__):
1✔
124
                        return is_match_with(other.__dict__, self.__dict__)
1✔
125

126
                return NotImplemented
1✔
127

128

129
@prettify_docstrings
1✔
130
class UserList(MutableSequence[_T]):
1✔
131
        """
132
        Typed version of :class:`collections.UserList`.
133

134
        Class that simulates a list. The instance’s contents are kept in a regular list,
135
        which is accessible via the :attr:`~.UserList.data` attribute of :class:`~.UserList` instances.
136
        The instance’s contents are initially set to a copy of list, defaulting to the empty list ``[]``.
137

138
        .. versionadded:: 0.10.0
139

140
        :param initlist: The initial values to populate the :class:`~.UserList` with.
141
        :default initlist: ``[]``
142

143
        .. latex:clearpage::
144

145
        .. admonition:: Subclassing requirements
146

147
                Subclasses of :class:`~.UserList` are expected to offer a constructor which can be called with
148
                either no arguments or one argument. List operations which return a new sequence
149
                attempt to create an instance of the actual implementation class. To do so,
150
                it assumes that the constructor can be called with a single parameter, which is a
151
                sequence object used as a data source.
152

153
                If a derived class does not wish to comply with this requirement, all of the special
154
                methods supported by this class will need to be overridden; please consult the
155
                sources for information about the methods which need to be provided in that case.
156
        """
157

158
        #: A real list object used to store the contents of the :class:`~domdf_python_tools.bases.UserList`.
159
        data: List[_T]
1✔
160

161
        def __init__(self, initlist: Optional[Iterable[_T]] = None):
1✔
162
                self.data = []
1✔
163
                if initlist is not None:
1✔
164
                        # XXX should this accept an arbitrary sequence?
165
                        if type(initlist) is type(self.data):  # noqa: E721
1✔
166
                                self.data[:] = initlist
1✔
167
                        elif isinstance(initlist, UserList):
1✔
168
                                self.data[:] = initlist.data[:]
1✔
169
                        else:
170
                                self.data = list(initlist)
1✔
171

172
        def __repr__(self) -> str:
1✔
173
                return repr(self.data)
1✔
174

175
        def __lt__(self, other: object) -> bool:
1✔
176
                return self.data < self.__cast(other)
×
177

178
        def __le__(self, other: object) -> bool:
1✔
179
                return self.data <= self.__cast(other)
×
180

181
        def __eq__(self, other: object) -> bool:
1✔
182
                return self.data == self.__cast(other)
1✔
183

184
        def __gt__(self, other: object) -> bool:
1✔
185
                return self.data > self.__cast(other)
×
186

187
        def __ge__(self, other: object) -> bool:
1✔
188
                return self.data >= self.__cast(other)
×
189

190
        @staticmethod
1✔
191
        def __cast(other):
1✔
192
                return other.data if isinstance(other, UserList) else other
1✔
193

194
        def __contains__(self, item: object) -> bool:
1✔
195
                return item in self.data
1✔
196

197
        def __len__(self) -> int:
1✔
198
                return len(self.data)
1✔
199

200
        def __iter__(self) -> Iterator[_T]:
1✔
201
                yield from self.data
1✔
202

203
        @overload
1✔
204
        def __getitem__(self, i: int) -> _T: ...
1✔
205

206
        @overload
1✔
207
        def __getitem__(self, i: slice) -> MutableSequence[_T]: ...
1✔
208

209
        def __getitem__(self, i: Union[int, slice]) -> Union[_T, MutableSequence[_T]]:
1✔
210
                if isinstance(i, slice):
1✔
211
                        return self.__class__(self.data[i])
1✔
212
                else:
213
                        return self.data[i]
1✔
214

215
        @overload
1✔
216
        def __setitem__(self, i: int, o: _T) -> None: ...
1✔
217

218
        @overload
1✔
219
        def __setitem__(self, i: slice, o: Iterable[_T]) -> None: ...
1✔
220

221
        def __setitem__(self, i: Union[int, slice], item: Union[_T, Iterable[_T]]) -> None:
1✔
222
                self.data[i] = item  # type: ignore[index, assignment]
1✔
223

224
        def __delitem__(self, i: Union[int, slice]):
1✔
225
                del self.data[i]
1✔
226

227
        def __add__(self: _S, other: Iterable[_T]) -> _S:
1✔
228
                if isinstance(other, UserList):
1✔
229
                        return self.__class__(self.data + other.data)
1✔
230
                elif isinstance(other, type(self.data)):
1✔
231
                        return self.__class__(self.data + other)
1✔
232
                return self.__class__(self.data + list(other))
1✔
233

234
        def __radd__(self, other):
1✔
235
                if isinstance(other, UserList):
1✔
236
                        return self.__class__(other.data + self.data)
1✔
237
                elif isinstance(other, type(self.data)):
1✔
238
                        return self.__class__(other + self.data)
1✔
239
                return self.__class__(list(other) + self.data)
1✔
240

241
        def __iadd__(self: _S, other: Iterable[_T]) -> _S:
1✔
242
                if isinstance(other, UserList):
1✔
243
                        self.data += other.data
1✔
244
                elif isinstance(other, type(self.data)):
1✔
245
                        self.data += other
1✔
246
                else:
247
                        self.data += list(other)
1✔
248
                return self
1✔
249

250
        def __mul__(self: _S, n: int) -> _S:
1✔
251
                return self.__class__(self.data * n)
1✔
252

253
        __rmul__ = __mul__
1✔
254

255
        def __imul__(self: _S, n: int) -> _S:
1✔
256
                self.data *= n
1✔
257
                return self
1✔
258

259
        def __copy__(self):
1✔
260
                inst = self.__class__.__new__(self.__class__)
×
261
                inst.__dict__.update(self.__dict__)
×
262
                # Create a copy and avoid triggering descriptors
263
                inst.__dict__["data"] = self.__dict__["data"][:]
×
264
                return inst
×
265

266
        def append(self, item: _T) -> None:
1✔
267
                """
268
                Append ``item`` to the end of the :class:`~.domdf_python_tools.bases.UserList`.
269
                """
270

271
                self.data.append(item)
1✔
272

273
        def insert(self, i: int, item: _T) -> None:
1✔
274
                """
275
                Insert ``item`` at position ``i`` in the :class:`~.domdf_python_tools.bases.UserList`.
276
                """
277

278
                self.data.insert(i, item)
1✔
279

280
        def pop(self, i: int = -1) -> _T:
1✔
281
                """
282
                Removes and returns the item at index ``i``.
283

284
                :raises IndexError: if list is empty or index is out of range.
285
                """
286

287
                return self.data.pop(i)
1✔
288

289
        def remove(self, item: _T) -> None:
1✔
290
                """
291
                Removes the first occurrence of ``item`` from the list.
292

293
                :param item:
294

295
                :rtype:
296

297
                :raises ValueError: if the item is not present.
298

299
                .. latex:clearpage::
300
                """
301

302
                self.data.remove(item)
1✔
303

304
        def clear(self) -> None:
1✔
305
                """
306
                Remove all items from the :class:`~.domdf_python_tools.bases.UserList`.
307
                """
308

309
                self.data.clear()
1✔
310

311
        def copy(self: _S) -> _S:
1✔
312
                """
313
                Returns a copy of the :class:`~.domdf_python_tools.bases.UserList`.
314
                """
315

316
                return self.__class__(self)
1✔
317

318
        def count(self, item: _T) -> int:
1✔
319
                """
320
                Returns the number of occurrences of ``item`` in the :class:`~.domdf_python_tools.bases.UserList`.
321
                """
322

323
                return self.data.count(item)
1✔
324

325
        def index(self, item: _T, *args: Any) -> int:
1✔
326
                """
327
                Returns the index of the fist element matching ``item``.
328

329
                :param item:
330
                :param args:
331

332
                :raises ValueError: if the item is not present.
333
                """
334

335
                return self.data.index(item, *args)
1✔
336

337
        def reverse(self) -> None:
1✔
338
                """
339
                Reverse the list in place.
340
                """
341

342
                self.data.reverse()
1✔
343

344
        def sort(self, *, key=None, reverse: bool = False) -> None:
1✔
345
                """
346
                Sort the list in ascending order and return :py:obj:`None`.
347

348
                The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
349
                order of two equal elements is maintained).
350

351
                If a key function is given, apply it once to each list item and sort them,
352
                ascending or descending, according to their function values.
353

354
                The reverse flag can be set to sort in descending order.
355
                """
356

357
                self.data.sort(key=key, reverse=reverse)
1✔
358

359
        def extend(self, other: Iterable[_T]) -> None:
1✔
360
                """
361
                Extend the :class:`~.domdf_python_tools.bases.NamedList` by appending elements from ``other``.
362

363
                :param other:
364
                """
365

366
                if isinstance(other, UserList):
1✔
367
                        self.data.extend(other.data)
1✔
368
                else:
369
                        self.data.extend(other)
1✔
370

371

372
@prettify_docstrings
1✔
373
class UserFloat(Real):
1✔
374
        """
375
        Class which simulates a float.
376

377
        .. versionadded:: 1.6.0
378

379
        :param value: The values to initialise the :class:`~domdf_python_tools.bases.UserFloat` with.
380
        """
381

382
        def __init__(self, value: Union[SupportsFloat, SupportsIndex, str, bytes, bytearray] = 0.0):
1✔
383
                self._value = (float(value), )
1✔
384

385
        def as_integer_ratio(self) -> Tuple[int, int]:
1✔
386
                """
387
                Returns the float as a fraction.
388
                """
389

390
                return float(self).as_integer_ratio()
1✔
391

392
        def hex(self) -> str:  # noqa: A003  # pylint: disable=redefined-builtin
1✔
393
                """
394
                Returns the hexadecimal (base 16) representation of the float.
395
                """
396

397
                return float(self).hex()
1✔
398

399
        def is_integer(self) -> bool:
1✔
400
                """
401
                Returns whether the float is an integer.
402
                """
403

404
                return float(self).is_integer()
1✔
405

406
        @classmethod
1✔
407
        def fromhex(cls: Type[_F], string: str) -> _F:
1✔
408
                """
409
                Create a floating-point number from a hexadecimal string.
410

411
                :param string:
412
                """
413

414
                return cls(float.fromhex(string))
×
415

416
        def __add__(self: _F, other: float) -> _F:
1✔
417
                return self.__class__(float(self).__add__(other))
1✔
418

419
        def __sub__(self: _F, other: float) -> _F:
1✔
420
                return self.__class__(float(self).__sub__(other))
1✔
421

422
        def __mul__(self: _F, other: float) -> _F:
1✔
423
                return self.__class__(float(self).__mul__(other))
1✔
424

425
        def __floordiv__(self: _F, other: float) -> _F:
1✔
426
                return self.__class__(float(self).__floordiv__(other))
1✔
427

428
        def __truediv__(self: _F, other: float) -> _F:
1✔
429
                return self.__class__(float(self).__truediv__(other))
1✔
430

431
        def __mod__(self: _F, other: float) -> _F:
1✔
432
                return self.__class__(float(self).__mod__(other))
1✔
433

434
        def __divmod__(self: _F, other: float) -> Tuple[_F, _F]:
1✔
435
                return tuple(self.__class__(x) for x in float(self).__divmod__(other))  # type: ignore[return-value]
×
436

437
        def __pow__(self: _F, other: float, mod=None) -> _F:
1✔
438
                return self.__class__(float(self).__pow__(other, mod))
1✔
439

440
        def __radd__(self: _F, other: float) -> _F:
1✔
441
                return self.__class__(float(self).__radd__(other))
1✔
442

443
        def __rsub__(self: _F, other: float) -> _F:
1✔
444
                return self.__class__(float(self).__rsub__(other))
1✔
445

446
        def __rmul__(self: _F, other: float) -> _F:
1✔
447
                return self.__class__(float(self).__rmul__(other))
1✔
448

449
        def __rfloordiv__(self: _F, other: float) -> _F:
1✔
450
                return self.__class__(float(self).__rfloordiv__(other))
1✔
451

452
        def __rtruediv__(self: _F, other: float) -> _F:
1✔
453
                return self.__class__(float(self).__rtruediv__(other))
1✔
454

455
        def __rmod__(self: _F, other: float) -> _F:
1✔
456
                return self.__class__(float(self).__rmod__(other))
1✔
457

458
        def __rdivmod__(self: _F, other: float) -> Tuple[_F, _F]:
1✔
459
                return tuple(self.__class__(x) for x in float(self).__rdivmod__(other))  # type: ignore[return-value]
×
460

461
        def __rpow__(self: _F, other: float, mod=None) -> _F:
1✔
462
                return self.__class__(float(self).__rpow__(other, mod))
1✔
463

464
        def __getnewargs__(self) -> Tuple[float]:
1✔
465
                return self._value
×
466

467
        def __trunc__(self) -> int:
1✔
468
                """
469
                Truncates the float to an integer.
470
                """
471

472
                return float(self).__trunc__()
×
473

474
        @overload
1✔
475
        def __round__(self, ndigits: None = ...) -> int: ...
1✔
476

477
        @overload
1✔
478
        def __round__(self, ndigits: int) -> float: ...
1✔
479

480
        def __round__(self, ndigits: Optional[int] = None) -> Union[int, float]:
1✔
481
                """
482
                Round the :class:`~.UserFloat` to ``ndigits`` decimal places, defaulting to ``0``.
483

484
                If ``ndigits`` is omitted or :py:obj:`None`, returns an :class:`int`,
485
                otherwise returns a :class:`float`.
486
                Rounds half toward even.
487

488
                :param ndigits:
489
                """
490

491
                return float(self).__round__(ndigits)
1✔
492

493
        def __eq__(self, other: object) -> bool:
1✔
494
                if isinstance(other, UserFloat) and not isinstance(other, float):
1✔
495
                        return self._value == other._value
1✔
496
                else:
497
                        return float(self).__eq__(other)
1✔
498

499
        def __ne__(self, other: object) -> bool:
1✔
500
                if isinstance(other, UserFloat) and not isinstance(other, float):
1✔
501
                        return self._value != other._value
1✔
502
                else:
503
                        return float(self).__ne__(other)
1✔
504

505
        def __lt__(self, other: Union[float, "UserFloat"]) -> bool:
1✔
506
                if isinstance(other, UserFloat) and not isinstance(other, float):
1✔
507
                        return self._value < other._value
1✔
508
                else:
509
                        return float(self).__lt__(other)
1✔
510

511
        def __le__(self, other: Union[float, "UserFloat"]) -> bool:
1✔
512
                if isinstance(other, UserFloat) and not isinstance(other, float):
1✔
513
                        return self._value <= other._value
1✔
514
                else:
515
                        return float(self).__le__(other)
1✔
516

517
        def __gt__(self, other: Union[float, "UserFloat"]) -> bool:
1✔
518
                if isinstance(other, UserFloat) and not isinstance(other, float):
1✔
519
                        return self._value > other._value
1✔
520
                else:
521
                        return float(self).__gt__(other)
1✔
522

523
        def __ge__(self, other: Union[float, "UserFloat"]) -> bool:
1✔
524
                if isinstance(other, UserFloat) and not isinstance(other, float):
1✔
525
                        return self._value >= other._value
1✔
526
                else:
527
                        return float(self).__ge__(other)
1✔
528

529
        def __neg__(self: _F) -> _F:
1✔
530
                return self.__class__(float(self).__neg__())
1✔
531

532
        def __pos__(self: _F) -> _F:
1✔
533
                return self.__class__(float(self).__pos__())
1✔
534

535
        def __str__(self) -> str:
1✔
536
                return str(float(self))
1✔
537

538
        def __int__(self) -> int:
1✔
539
                return int(float(self))
1✔
540

541
        def __float__(self) -> float:
1✔
542
                return self._value[0]
1✔
543

544
        def __abs__(self: _F) -> _F:
1✔
545
                return self.__class__(float(self).__abs__())
1✔
546

547
        def __hash__(self) -> int:  # type: ignore[override]
1✔
548
                return float(self).__hash__()
1✔
549

550
        def __repr__(self) -> str:
1✔
551
                return str(self)
1✔
552

553
        def __ceil__(self):
1✔
554
                raise NotImplementedError
555

556
        def __floor__(self):
1✔
557
                raise NotImplementedError
558

559
        def __bool__(self) -> bool:
1✔
560
                """
561
                Return ``self != 0``.
562
                """
563

UNCOV
564
                return super().__bool__()
×
565

566
        def __complex__(self) -> complex:
1✔
567
                """
568
                Return :class:`complex(self) <complex>`.
569

570
                .. code-block:: python
571

572
                        complex(self) == complex(float(self), 0)
573
                """
574

UNCOV
575
                return super().__complex__()
×
576

577

578
@prettify_docstrings
1✔
579
class NamedList(UserList[_T]):
1✔
580
        """
581
        A list with a name.
582

583
        The name of the list is taken from the name of the subclass.
584

585
        .. versionchanged:: 0.10.0
586

587
                :class:`~.NamedList` now subclasses :class:`.UserList` rather than :class:`collections.UserList`.
588
        """
589

590
        def __repr__(self) -> str:
1✔
591
                return f"{super().__repr__()}"
1✔
592

593
        def __str__(self) -> str:
1✔
594
                return f"{self.__class__.__name__}{pformat(list(self))}"
1✔
595

596

597
def namedlist(name: str = "NamedList") -> Type[NamedList]:
1✔
598
        """
599
        A factory function to return a custom list subclass with a name.
600

601
        :param name: The name of the list.
602
        """
603

604
        class cls(NamedList):
1✔
605
                pass
1✔
606

607
        cls.__name__ = name
1✔
608

609
        return cls
1✔
610

611

612
class Lineup(UserList[_T]):
1✔
613
        """
614
        List-like type with fluent methods and some star players.
615

616
        .. latex:vspace:: -10px
617
        """
618

619
        def replace(self: _LU, what: _T, with_: _T) -> _LU:
1✔
620
                r"""
621
                Replace the first instance of ``what`` with ``with_``.
622

623
                :param what: The object to find and replace.
624
                :param with\_: The new value for the position in the list.
625
                """
626

627
                self[self.index(what)] = with_
1✔
628

629
                return self
1✔
630

631
        def sort(  # type: ignore[override]
1✔
632
                        self: _LU,
633
                        *,
634
                        key=None,
635
                        reverse: bool = False,
636
                        ) -> _LU:
637
                """
638
                Sort the list in ascending order and return the self.
639

640
                The sort is in-place (i.e. the list itself is modified) and stable (i.e. the
641
                order of two equal elements is maintained).
642

643
                If a key function is given, apply it once to each list item and sort them,
644
                ascending or descending, according to their function values.
645

646
                The reverse flag can be set to sort in descending order.
647
                """
648

649
                super().sort(key=key, reverse=reverse)
1✔
650
                return self
1✔
651

652
        def reverse(self: _LU) -> _LU:  # type: ignore[override]  # noqa: D102
1✔
653
                super().reverse()
1✔
654
                return self
1✔
655

656
        def append(  # type: ignore[override]  # noqa: D102
1✔
657
                        self: _LU,
658
                        item: _T,
659
                        ) -> _LU:
660
                super().append(item)
1✔
661
                return self
1✔
662

663
        def extend(  # type: ignore[override]  # noqa: D102
1✔
664
                        self: _LU,
665
                        other: Iterable[_T],
666
                        ) -> _LU:
667
                super().extend(other)
1✔
668
                return self
1✔
669

670
        def insert(  # type: ignore[override]  # noqa: D102
1✔
671
                        self: _LU,
672
                        i: int,
673
                        item: _T,
674
                        ) -> _LU:
675
                super().insert(i, item)
1✔
676
                return self
1✔
677

678
        def remove(  # type: ignore[override]  # noqa: D102
1✔
679
                        self: _LU,
680
                        item: _T,
681
                        ) -> _LU:
682
                super().remove(item)
1✔
683
                return self
1✔
684

685
        def clear(self: _LU) -> _LU:  # type: ignore[override]  # noqa: D102
1✔
686
                super().clear()
1✔
687
                return self
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc