• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In
Info updated!

earwig / mwparserfromhell / 15990296633

01 Jul 2025 05:01AM UTC coverage: 98.438% (-0.2%) from 98.662%
15990296633

push

github

earwig
Improve Wikicode/Node typing

239 of 252 new or added lines in 6 files covered. (94.84%)

2 existing lines in 2 files now uncovered.

3276 of 3328 relevant lines covered (98.44%)

9.84 hits per line

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

93.26
/src/mwparserfromhell/string_mixin.py
1
# Copyright (C) 2012-2025 Ben Kurtovic <ben.kurtovic@gmail.com>
2
#
3
# Permission is hereby granted, free of charge, to any person obtaining a copy
4
# of this software and associated documentation files (the "Software"), to deal
5
# in the Software without restriction, including without limitation the rights
6
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
# copies of the Software, and to permit persons to whom the Software is
8
# furnished to do so, subject to the following conditions:
9
#
10
# The above copyright notice and this permission notice shall be included in
11
# all copies or substantial portions of the Software.
12
#
13
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
# SOFTWARE.
20

21
"""
22
This module contains the :class:`.StringMixIn` type, which implements the
23
interface for the ``str`` type in a dynamic manner.
24
"""
25

26
from __future__ import annotations
10✔
27

28
import sys
10✔
29
from collections.abc import Iterable, Iterator, Mapping
10✔
30
from typing import Any, SupportsIndex
10✔
31

32
__all__ = ["StringMixIn"]
10✔
33

34

35
def inheritdoc(method):
10✔
36
    """Set __doc__ of *method* to __doc__ of *method* in its parent class.
37

38
    Since this is used on :class:`.StringMixIn`, the "parent class" used is
39
    ``str``. This function can be used as a decorator.
40
    """
41
    method.__doc__ = getattr(str, method.__name__).__doc__
10✔
42
    return method
10✔
43

44

45
class StringMixIn:
10✔
46
    """Implement the interface for ``str`` in a dynamic manner.
47

48
    To use this class, inherit from it and override the :meth:`__str__` method
49
    to return the string representation of the object. The various string
50
    methods will operate on the value of :meth:`__str__` instead of the
51
    immutable ``self`` like the regular ``str`` type.
52
    """
53

54
    # This is based on collections.UserString, but:
55
    # - Requires overriding __str__ instead of setting .data
56
    # - Returns new strings as strs instead of StringMixIns
57

58
    __slots__ = ()
10✔
59

60
    def __str__(self) -> str:
10✔
UNCOV
61
        raise NotImplementedError()
×
62

63
    def __bytes__(self) -> bytes:
10✔
64
        return bytes(str(self), sys.getdefaultencoding())
10✔
65

66
    def __repr__(self) -> str:
10✔
67
        return repr(str(self))
10✔
68

69
    def __lt__(self, other: str | StringMixIn) -> bool:
10✔
70
        return str(self) < other
10✔
71

72
    def __le__(self, other: str | StringMixIn) -> bool:
10✔
73
        return str(self) <= other
10✔
74

75
    def __eq__(self, other: Any) -> bool:
10✔
76
        return str(self) == other
10✔
77

78
    def __ne__(self, other: Any) -> bool:
10✔
79
        return str(self) != other
10✔
80

81
    def __gt__(self, other: str | StringMixIn) -> bool:
10✔
82
        return str(self) > other
10✔
83

84
    def __ge__(self, other: str | StringMixIn) -> bool:
10✔
85
        return str(self) >= other
10✔
86

87
    def __bool__(self) -> bool:
10✔
88
        return bool(str(self))
10✔
89

90
    def __len__(self) -> int:
10✔
91
        return len(str(self))
10✔
92

93
    def __iter__(self) -> Iterator[str]:
10✔
94
        yield from str(self)
10✔
95

96
    def __getitem__(self, key: SupportsIndex | slice) -> str:
10✔
97
        return str(self)[key]
10✔
98

99
    def __reversed__(self) -> Iterator[str]:
10✔
100
        return reversed(str(self))
10✔
101

102
    def __contains__(self, item: Any) -> bool:
10✔
103
        return str(item) in str(self)
10✔
104

105
    @inheritdoc
10✔
106
    def capitalize(self) -> str:
10✔
107
        return str(self).capitalize()
10✔
108

109
    @inheritdoc
10✔
110
    def casefold(self) -> str:
10✔
111
        return str(self).casefold()
10✔
112

113
    @inheritdoc
10✔
114
    def center(self, width: int, fillchar: str = " ") -> str:
10✔
115
        return str(self).center(width, fillchar)
10✔
116

117
    @inheritdoc
10✔
118
    def count(
10✔
119
        self,
120
        sub: str | StringMixIn,
121
        start: SupportsIndex | None = None,
122
        end: SupportsIndex | None = None,
123
    ) -> int:
124
        if isinstance(sub, StringMixIn):
10✔
NEW
125
            sub = str(sub)
×
126
        return str(self).count(sub, start, end)
10✔
127

128
    @inheritdoc
10✔
129
    def encode(self, encoding: str = "utf-8", errors: str = "strict") -> bytes:
10✔
130
        return str(self).encode(encoding, errors)
10✔
131

132
    @inheritdoc
10✔
133
    def endswith(
10✔
134
        self,
135
        suffix: str | tuple[str, ...],
136
        start: SupportsIndex | None = None,
137
        end: SupportsIndex | None = None,
138
    ) -> bool:
139
        return str(self).endswith(suffix, start, end)
10✔
140

141
    @inheritdoc
10✔
142
    def expandtabs(self, tabsize: int = 8) -> str:
10✔
143
        return str(self).expandtabs(tabsize)
10✔
144

145
    @inheritdoc
10✔
146
    def find(
10✔
147
        self,
148
        sub: str | StringMixIn,
149
        start: SupportsIndex | None = None,
150
        end: SupportsIndex | None = None,
151
    ) -> int:
152
        if isinstance(sub, StringMixIn):
10✔
NEW
153
            sub = str(sub)
×
154
        return str(self).find(sub, start, end)
10✔
155

156
    @inheritdoc
10✔
157
    def format(self, /, *args: Any, **kwds: Any) -> str:
10✔
158
        return str(self).format(*args, **kwds)
10✔
159

160
    @inheritdoc
10✔
161
    def format_map(self, mapping: Mapping[str, Any]) -> str:
10✔
162
        return str(self).format_map(mapping)
10✔
163

164
    @inheritdoc
10✔
165
    def index(
10✔
166
        self,
167
        sub: str,
168
        start: SupportsIndex | None = None,
169
        end: SupportsIndex | None = None,
170
    ) -> int:
171
        return str(self).index(sub, start, end)
10✔
172

173
    @inheritdoc
10✔
174
    def isalpha(self) -> bool:
10✔
175
        return str(self).isalpha()
10✔
176

177
    @inheritdoc
10✔
178
    def isalnum(self) -> bool:
10✔
179
        return str(self).isalnum()
10✔
180

181
    @inheritdoc
10✔
182
    def isascii(self) -> bool:
10✔
NEW
183
        return str(self).isascii()
×
184

185
    @inheritdoc
10✔
186
    def isdecimal(self) -> bool:
10✔
187
        return str(self).isdecimal()
10✔
188

189
    @inheritdoc
10✔
190
    def isdigit(self) -> bool:
10✔
191
        return str(self).isdigit()
10✔
192

193
    @inheritdoc
10✔
194
    def isidentifier(self) -> bool:
10✔
195
        return str(self).isidentifier()
10✔
196

197
    @inheritdoc
10✔
198
    def islower(self) -> bool:
10✔
199
        return str(self).islower()
10✔
200

201
    @inheritdoc
10✔
202
    def isnumeric(self) -> bool:
10✔
203
        return str(self).isnumeric()
10✔
204

205
    @inheritdoc
10✔
206
    def isprintable(self) -> bool:
10✔
207
        return str(self).isprintable()
10✔
208

209
    @inheritdoc
10✔
210
    def isspace(self) -> bool:
10✔
211
        return str(self).isspace()
10✔
212

213
    @inheritdoc
10✔
214
    def istitle(self) -> bool:
10✔
215
        return str(self).istitle()
10✔
216

217
    @inheritdoc
10✔
218
    def isupper(self) -> bool:
10✔
219
        return str(self).isupper()
10✔
220

221
    @inheritdoc
10✔
222
    def join(self, seq: Iterable[str]) -> str:
10✔
223
        return str(self).join(seq)
10✔
224

225
    @inheritdoc
10✔
226
    def ljust(self, width: int, fillchar: str = " ") -> str:
10✔
227
        return str(self).ljust(width, fillchar)
10✔
228

229
    @inheritdoc
10✔
230
    def lower(self) -> str:
10✔
231
        return str(self).lower()
10✔
232

233
    @inheritdoc
10✔
234
    def lstrip(self, chars: str | None = None) -> str:
10✔
235
        return str(self).lstrip(chars)
10✔
236

237
    maketrans = str.maketrans
10✔
238

239
    @inheritdoc
10✔
240
    def partition(self, sep: str) -> tuple[str, str, str]:
10✔
241
        return str(self).partition(sep)
10✔
242

243
    @inheritdoc
10✔
244
    def removeprefix(self, prefix: str | StringMixIn, /) -> str:
10✔
NEW
245
        if isinstance(prefix, StringMixIn):
×
NEW
246
            prefix = str(prefix)
×
NEW
247
        return str(self).removeprefix(prefix)
×
248

249
    @inheritdoc
10✔
250
    def removesuffix(self, suffix: str | StringMixIn, /) -> str:
10✔
NEW
251
        if isinstance(suffix, StringMixIn):
×
NEW
252
            suffix = str(suffix)
×
NEW
253
        return str(self).removesuffix(suffix)
×
254

255
    @inheritdoc
10✔
256
    def replace(
10✔
257
        self,
258
        old: str | StringMixIn,
259
        new: str | StringMixIn,
260
        /,
261
        count: SupportsIndex = -1,
262
    ):
263
        if isinstance(old, StringMixIn):
10✔
NEW
264
            old = str(old)
×
265
        if isinstance(new, StringMixIn):
10✔
NEW
266
            new = str(new)
×
267
        return str(self).replace(old, new, count)
10✔
268

269
    @inheritdoc
10✔
270
    def rfind(
10✔
271
        self,
272
        sub: str | StringMixIn,
273
        start: SupportsIndex | None = None,
274
        end: SupportsIndex | None = None,
275
    ) -> int:
276
        if isinstance(sub, StringMixIn):
10✔
NEW
277
            sub = str(sub)
×
278
        return str(self).rfind(sub, start, end)
10✔
279

280
    @inheritdoc
10✔
281
    def rindex(
10✔
282
        self,
283
        sub: str,
284
        start: SupportsIndex | None = None,
285
        end: SupportsIndex | None = None,
286
    ) -> int:
287
        return str(self).rindex(sub, start, end)
10✔
288

289
    @inheritdoc
10✔
290
    def rjust(self, width: int, fillchar: str = " ") -> str:
10✔
291
        return str(self).rjust(width, fillchar)
10✔
292

293
    @inheritdoc
10✔
294
    def rpartition(self, sep: str) -> tuple[str, str, str]:
10✔
295
        return str(self).rpartition(sep)
10✔
296

297
    @inheritdoc
10✔
298
    def rstrip(self, chars: str | None = None) -> str:
10✔
299
        return str(self).rstrip(chars)
10✔
300

301
    @inheritdoc
10✔
302
    def split(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]:
10✔
303
        return str(self).split(sep, maxsplit)
10✔
304

305
    @inheritdoc
10✔
306
    def rsplit(self, sep: str | None = None, maxsplit: SupportsIndex = -1) -> list[str]:
10✔
307
        return str(self).rsplit(sep, maxsplit)
10✔
308

309
    @inheritdoc
10✔
310
    def splitlines(self, keepends: bool = False) -> list[str]:
10✔
311
        return str(self).splitlines(keepends)
10✔
312

313
    @inheritdoc
10✔
314
    def startswith(
10✔
315
        self,
316
        prefix: str | tuple[str, ...],
317
        start: SupportsIndex | None = None,
318
        end: SupportsIndex | None = None,
319
    ) -> bool:
320
        return str(self).startswith(prefix, start, end)
10✔
321

322
    @inheritdoc
10✔
323
    def strip(self, chars: str | None = None) -> str:
10✔
324
        return str(self).strip(chars)
10✔
325

326
    @inheritdoc
10✔
327
    def swapcase(self) -> str:
10✔
328
        return str(self).swapcase()
10✔
329

330
    @inheritdoc
10✔
331
    def title(self) -> str:
10✔
332
        return str(self).title()
10✔
333

334
    @inheritdoc
10✔
335
    def translate(self, *args: Any) -> str:
10✔
336
        return str(self).translate(*args)
10✔
337

338
    @inheritdoc
10✔
339
    def upper(self) -> str:
10✔
340
        return str(self).upper()
10✔
341

342
    @inheritdoc
10✔
343
    def zfill(self, width: int) -> str:
10✔
344
        return str(self).zfill(width)
10✔
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