Mercurial > public > mercurial-scm > hg
comparison mercurial/pycompat.py @ 52084:51057ab0dffa stable
py-3-13: stabilize the docstring output across all supported Python versions
Python 3.13 now trims indents from docstrings at compilation time
(to save space in .pyc), so all of our helptext is affected.
The indentation has never served a user-facing purpose and was more here
because nobody cared enough to remove it: we gain some screen space this way.
Rather than undo the transformation (which isn't really possible since the
transform also deletes leading/trailing whitespace), we align the behavior
of older Python versions with that of 3.13.
Unfortunately, this means breaking some of the translations. I've only
touched the ones that need to work for some tooling tests to pass, but
I do not have the time to fix the rest of them across all languages, since
they cannot be done in an automated way. i18n updates have been basically
abandonned for a good while now, hopefully someone cares enough to bring them
back.
author | Rapha?l Gom?s <rgomes@octobus.net> |
---|---|
date | Thu, 24 Oct 2024 15:23:52 +0200 |
parents | 7e6aae033d8d |
children | b5efb7a7d2a5 |
comparison
equal
deleted
inserted
replaced
52083:888e00b2c3ee | 52084:51057ab0dffa |
---|---|
346 def raisewithtb(exc: BaseException, tb) -> NoReturn: | 346 def raisewithtb(exc: BaseException, tb) -> NoReturn: |
347 """Raise exception with the given traceback""" | 347 """Raise exception with the given traceback""" |
348 raise exc.with_traceback(tb) | 348 raise exc.with_traceback(tb) |
349 | 349 |
350 | 350 |
351 # Copied over from the 3.13 Python stdlib `inspect.cleandoc`, with a couple | |
352 # of removals explained inline. | |
353 # It differs slightly from the 3.8+ version, so it's better to use the same | |
354 # version to remove any potential for variation. | |
355 def cleandoc(doc): | |
356 """Clean up indentation from docstrings. | |
357 | |
358 Any whitespace that can be uniformly removed from the second line | |
359 onwards is removed.""" | |
360 lines = doc.expandtabs().split('\n') | |
361 | |
362 # Find minimum indentation of any non-blank lines after first line. | |
363 margin = sys.maxsize | |
364 for line in lines[1:]: | |
365 content = len(line.lstrip(' ')) | |
366 if content: | |
367 indent = len(line) - content | |
368 margin = min(margin, indent) | |
369 # Remove indentation. | |
370 if lines: | |
371 lines[0] = lines[0].lstrip(' ') | |
372 if margin < sys.maxsize: | |
373 for i in range(1, len(lines)): | |
374 lines[i] = lines[i][margin:] | |
375 # Here the upstream *Python* version does newline trimming, but it looks | |
376 # like the compiler (written in C) does not, so go with what the compiler | |
377 # does. | |
378 return '\n'.join(lines) | |
379 | |
380 | |
351 def getdoc(obj: object) -> Optional[bytes]: | 381 def getdoc(obj: object) -> Optional[bytes]: |
352 """Get docstring as bytes; may be None so gettext() won't confuse it | 382 """Get docstring as bytes; may be None so gettext() won't confuse it |
353 with _('')""" | 383 with _('')""" |
354 doc = builtins.getattr(obj, '__doc__', None) | 384 doc = builtins.getattr(obj, '__doc__', None) |
355 if doc is None: | 385 if doc is None: |
356 return doc | 386 return doc |
387 if sys.version_info < (3, 13): | |
388 # Python 3.13+ "cleans up" the docstring at compile time, let's | |
389 # normalize this behavior for previous versions | |
390 doc = cleandoc(doc) | |
357 return sysbytes(doc) | 391 return sysbytes(doc) |
358 | 392 |
359 | 393 |
360 # these wrappers are automagically imported by hgloader | 394 # these wrappers are automagically imported by hgloader |
361 delattr = builtins.delattr | 395 delattr = builtins.delattr |