Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
Expand Up @@ -473,8 +473,9 @@ Lib/test/test_functools.py @rhettinger
Modules/_functoolsmodule.c @rhettinger

# Garbage collector
Modules/gcmodule.c @pablogsal
Doc/library/gc.rst @pablogsal
Modules/gcmodule.c @pablogsal
Doc/library/gc.rst @pablogsal
InternalDocs/garbage_collector.md @pablogsal

# Gettext
Doc/library/gettext.rst @tomasr8
Expand Down
3 changes: 2 additions & 1 deletion .github/ISSUE_TEMPLATE/documentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ body:
> [!NOTE]
> Trivial changes (for example typos) don’t require an issue before opening a PR.
- type: textarea
id: description
attributes:
label: "Documentation"
description: "A clear and concise description of the issue."
description: "A clear and concise description of the issue. Include a link to the page."
validations:
required: true
4 changes: 0 additions & 4 deletions Doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -227,10 +227,6 @@
# Temporary undocumented names.
# In future this list must be empty.
nitpick_ignore += [
# Do not error nit-picky mode builds when _SubParsersAction.add_parser cannot
# be resolved, as the method is currently undocumented. For context, see
# https://github.com/python/cpython/pull/103289.
('py:meth', '_SubParsersAction.add_parser'),
# Attributes/methods/etc. that definitely should be documented better,
# but are deferred for now:
('py:attr', '__wrapped__'),
Expand Down
29 changes: 29 additions & 0 deletions Doc/improve-page-nojs.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
:orphan:

****************************
Improve a documentation page
****************************

.. This is the no-javascript version of this page. The one most people
will see (with JavaScript enabled) is improve-page.rst. If you edit
this page, please also edit that one, and vice versa.
.. only:: html and not epub

We are always interested to hear ideas about improvements to the documentation.

.. only:: translation

If the bug or suggested improvement concerns the translation of this
documentation, open an issue or edit the page in
`translation's repository <TRANSLATION_REPO_>`_ instead.

You have a few ways to ask questions or suggest changes:

- You can start a discussion about the page on the Python discussion forum.
This link will start a topic in the Documentation category:
`New Documentation topic <https://discuss.python.org/new-topic?category=documentation>`_.

- You can open an issue on the Python GitHub issue tracker. This link will
create a new issue with the "docs" label:
`New docs issue <https://github.com/python/cpython/issues/new?template=documentation.yml>`_.
65 changes: 65 additions & 0 deletions Doc/improve-page.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
:orphan:

****************************
Improve a documentation page
****************************

.. This is the JavaScript-enabled version of this page. Another version
(for those with JavaScript disabled) is improve-page-nojs.rst. If you
edit this page, please also edit that one, and vice versa.

.. only:: html and not epub

.. raw:: html

<script>
function applyReplacements(text, params) {
return text
.replace(/PAGETITLE/g, params.get('pagetitle'))
.replace(/PAGEURL/g, params.get('pageurl'))
.replace(/PAGESOURCE/g, params.get('pagesource'));
}

document.addEventListener('DOMContentLoaded', () => {
const params = new URLSearchParams(window.location.search);
const walker = document.createTreeWalker(
document.body,
NodeFilter.SHOW_ELEMENT | NodeFilter.SHOW_TEXT,
null
);

while (walker.nextNode()) {
const node = walker.currentNode;

if (node.nodeType === Node.TEXT_NODE) {
node.textContent = applyReplacements(node.textContent, params)
} else if (node.nodeName === 'A' && node.href) {
node.setAttribute('href', applyReplacements(node.getAttribute('href'), params));
}
}
});
</script>

We are always interested to hear ideas about improvements to the documentation.

You were reading "PAGETITLE" at `<PAGEURL>`_. The source for that page is on
`GitHub <https://github.com/python/cpython/blob/main/Doc/PAGESOURCE?plain=1>`_.

.. only:: translation

If the bug or suggested improvement concerns the translation of this
documentation, open an issue or edit the page in
`translation's repository <TRANSLATION_REPO_>`_ instead.

You have a few ways to ask questions or suggest changes:

- You can start a discussion about the page on the Python discussion forum.
This link will start a pre-populated topic:
`Question about page "PAGETITLE" <https://discuss.python.org/new-topic?category=documentation&title=Question+about+page+%22PAGETITLE%22&body=About+the+page+at+PAGEURL%3A>`_.

- You can open an issue on the Python GitHub issue tracker. This link will
create a new pre-populated issue:
`Docs: problem with page "PAGETITLE" <https://github.com/python/cpython/issues/new?template=documentation.yml&title=Docs%3A+problem+with+page+%22PAGETITLE%22&description=The+page+at+PAGEURL+has+a+problem%3A>`_.

- You can `edit the page on GitHub <https://github.com/python/cpython/blob/main/Doc/PAGESOURCE?plain=1>`_
to open a pull request and begin the contribution process.
34 changes: 19 additions & 15 deletions Doc/reference/compound_stmts.rst
Original file line number Diff line number Diff line change
Expand Up @@ -544,21 +544,24 @@ The following code::
is semantically equivalent to::

manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
enter = manager.__enter__
exit = manager.__exit__
value = enter()
hit_except = False

try:
TARGET = value
SUITE
except:
hit_except = True
if not exit(manager, *sys.exc_info()):
if not exit(*sys.exc_info()):
raise
finally:
if not hit_except:
exit(manager, None, None, None)
exit(None, None, None)

except that implicit :ref:`special method lookup <special-lookup>` is used
for :meth:`~object.__enter__` and :meth:`~object.__exit__`.

With more than one item, the context managers are processed as if multiple
:keyword:`with` statements were nested::
Expand Down Expand Up @@ -1679,21 +1682,21 @@ The following code::

Is semantically equivalent to::

iter = (ITER)
iter = type(iter).__aiter__(iter)
iter = (ITER).__aiter__()
running = True

while running:
try:
TARGET = await type(iter).__anext__(iter)
TARGET = await iter.__anext__()
except StopAsyncIteration:
running = False
else:
SUITE
else:
SUITE2

See also :meth:`~object.__aiter__` and :meth:`~object.__anext__` for details.
except that implicit :ref:`special method lookup <special-lookup>` is used
for :meth:`~object.__aiter__` and :meth:`~object.__anext__`.

It is a :exc:`SyntaxError` to use an ``async for`` statement outside the
body of a coroutine function.
Expand All @@ -1719,23 +1722,24 @@ The following code::
is semantically equivalent to::

manager = (EXPRESSION)
aenter = type(manager).__aenter__
aexit = type(manager).__aexit__
value = await aenter(manager)
aenter = manager.__aenter__
aexit = manager.__aexit__
value = await aenter()
hit_except = False

try:
TARGET = value
SUITE
except:
hit_except = True
if not await aexit(manager, *sys.exc_info()):
if not await aexit(*sys.exc_info()):
raise
finally:
if not hit_except:
await aexit(manager, None, None, None)
await aexit(None, None, None)

See also :meth:`~object.__aenter__` and :meth:`~object.__aexit__` for details.
except that implicit :ref:`special method lookup <special-lookup>` is used
for :meth:`~object.__aenter__` and :meth:`~object.__aexit__`.

It is a :exc:`SyntaxError` to use an ``async with`` statement outside the
body of a coroutine function.
Expand Down
17 changes: 16 additions & 1 deletion Doc/tools/templates/customsourcelink.html
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
{%- if show_source and has_source and sourcename %}
<script>
document.addEventListener('DOMContentLoaded', () => {
const title = document.querySelector('meta[property="og:title"]').content;
const elements = document.querySelectorAll('.improvepage');
const pageurl = window.location.href.split('?')[0];
elements.forEach(element => {
const url = new URL(element.href.split('?')[0].replace("-nojs", ""));
url.searchParams.set('pagetitle', title);
url.searchParams.set('pageurl', pageurl);
url.searchParams.set('pagesource', "{{ pagename }}.rst");
element.href = url.toString();
});
});
</script>
<div role="note" aria-label="source link">
<h3>{{ _('This page') }}</h3>
<ul class="this-page-menu">
<li><a href="{{ pathto('bugs') }}">{% trans %}Report a bug{% endtrans %}</a></li>
<li><a class="improvepage" href="{{ pathto('improve-page-nojs') }}">{% trans %}Improve this page{% endtrans %}</a></li>
<li>
<a href="https://github.com/python/cpython/blob/main/Doc/{{ sourcename|replace('.rst.txt', '.rst') }}?plain=1"
<a href="https://github.com/python/cpython/blob/main/Doc/{{ pagename }}.rst?plain=1"
rel="nofollow">{{ _('Show source') }}
</a>
</li>
Expand Down
21 changes: 16 additions & 5 deletions Lib/test/test_unicodedata.py
Original file line number Diff line number Diff line change
Expand Up @@ -319,7 +319,7 @@ def test_category(self):
self.assertRaises(TypeError, self.db.category, 'xx')

def test_bidirectional(self):
self.assertEqual(self.db.bidirectional('\uFFFE'), '')
self.assertEqual(self.db.bidirectional('\uFFFE'), 'BN')
self.assertEqual(self.db.bidirectional(' '), 'WS')
self.assertEqual(self.db.bidirectional('A'), 'L')
self.assertEqual(self.db.bidirectional('\U00020000'), 'L')
Expand Down Expand Up @@ -347,6 +347,17 @@ def test_bidirectional(self):
self.assertRaises(TypeError, self.db.bidirectional)
self.assertRaises(TypeError, self.db.bidirectional, 'xx')

def test_bidirectional_unassigned(self):
if self.old:
return
self.assertEqual(self.db.bidirectional('\u0378'), 'L')
self.assertEqual(self.db.bidirectional('\u077F'), 'AL')
self.assertEqual(self.db.bidirectional('\u20CF'), 'ET')
self.assertEqual(self.db.bidirectional('\u0590'), 'R')
self.assertEqual(self.db.bidirectional('\uFFFF'), 'BN')
self.assertEqual(self.db.bidirectional('\U0001FFFE'), 'BN')
self.assertEqual(self.db.bidirectional('\U00010D01'), 'AL')

def test_decomposition(self):
self.assertEqual(self.db.decomposition('\uFFFE'),'')
self.assertEqual(self.db.decomposition('\u00bc'), '<fraction> 0031 2044 0034')
Expand Down Expand Up @@ -676,9 +687,9 @@ class UnicodeFunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest):

# Update this if the database changes. Make sure to do a full rebuild
# (e.g. 'make distclean && make') to get the correct checksum.
expectedchecksum = ('83cc43a2fbb779185832b4c049217d80b05bf349'
expectedchecksum = ('668dbbea1136e69d4f00677a5988b23bc78aefc6'
if quicktest else
'180bdc91143d8aa2eb9dd6726e66d37606205942')
'b869af769bd8fe352c04622ab90533dc54df5cf3')

@requires_resource('network')
def test_all_names(self):
Expand Down Expand Up @@ -966,9 +977,9 @@ def graphemes(*args):
class Unicode_3_2_0_FunctionsTest(unittest.TestCase, BaseUnicodeFunctionsTest):
db = unicodedata.ucd_3_2_0
old = True
expectedchecksum = ('4154d8d1232837e255edf3cdcbb5ab184d71f4a4'
expectedchecksum = ('2164a66700e03cba9c9f5ed9e9a8d594d2da136a'
if quicktest else
'3aabaf66823b21b3d305dad804a62f6f6387c93e')
'a8276cec9b6991779c5bdaa46c1ae7cc50bc2403')


class UnicodeMiscTest(unittest.TestCase):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
A new "Improve this page" link is available in the left-hand sidebar of the
docs, offering links to create GitHub issues, discussion forum posts, or
pull requests.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
:func:`unicodedata.bidirectional` now return the correct default bidi class
for unassigned code points.
Loading
Loading