Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit e33685c

Browse files
author
Marcel Weiler
committed
Merge remote-tracking branch 'origin/master' into support_staticmethod
2 parents 2504078 + 1cdeecd commit e33685c

158 files changed

Lines changed: 2671 additions & 603 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 255 additions & 3 deletions
Large diffs are not rendered by default.

docs/requirements-docs.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
sphinx>=4.2.0,<5.0.0
1+
sphinx>=5.1.0
22
furo>=2022.3.4

docs/source/class_basics.rst

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -263,7 +263,7 @@ effect at runtime:
263263
Abstract base classes and multiple inheritance
264264
**********************************************
265265

266-
Mypy supports Python :doc:`abstract base classes <library/abc>` (ABCs). Abstract classes
266+
Mypy supports Python :doc:`abstract base classes <python:library/abc>` (ABCs). Abstract classes
267267
have at least one abstract method or property that must be implemented
268268
by any *concrete* (non-abstract) subclass. You can define abstract base
269269
classes using the :py:class:`abc.ABCMeta` metaclass and the :py:func:`@abc.abstractmethod <abc.abstractmethod>`
@@ -371,8 +371,7 @@ property or an instance variable.
371371
Slots
372372
*****
373373

374-
When a class has explicitly defined
375-
`__slots__ <https://docs.python.org/3/reference/datamodel.html#slots>`_,
374+
When a class has explicitly defined :std:term:`__slots__`,
376375
mypy will check that all attributes assigned to are members of ``__slots__``:
377376

378377
.. code-block:: python

docs/source/command_line.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -787,7 +787,7 @@ in error messages.
787787
disable reporting most additional errors. The limit only applies
788788
if it seems likely that most of the remaining errors will not be
789789
useful or they may be overly noisy. If ``N`` is negative, there is
790-
no limit. The default limit is 200.
790+
no limit. The default limit is -1.
791791

792792
.. option:: --force-uppercase-builtins
793793

docs/source/config_file.rst

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -238,10 +238,8 @@ section of the command line docs.
238238
Crafting a single regular expression that excludes multiple files while remaining
239239
human-readable can be a challenge. The above example demonstrates one approach.
240240
``(?x)`` enables the ``VERBOSE`` flag for the subsequent regular expression, which
241-
`ignores most whitespace and supports comments`__. The above is equivalent to:
242-
``(^one\.py$|two\.pyi$|^three\.)``.
243-
244-
.. __: https://docs.python.org/3/library/re.html#re.X
241+
:py:data:`ignores most whitespace and supports comments <re.VERBOSE>`.
242+
The above is equivalent to: ``(^one\.py$|two\.pyi$|^three\.)``.
245243

246244
For more details, see :option:`--exclude <mypy --exclude>`.
247245

docs/source/error_code_list2.rst

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -482,6 +482,37 @@ Example:
482482
def g(self, y: int) -> None:
483483
pass
484484
485+
.. _code-mutable-override:
486+
487+
Check that overrides of mutable attributes are safe
488+
---------------------------------------------------
489+
490+
This will enable the check for unsafe overrides of mutable attributes. For
491+
historical reasons, and because this is a relatively common pattern in Python,
492+
this check is not enabled by default. The example below is unsafe, and will be
493+
flagged when this error code is enabled:
494+
495+
.. code-block:: python
496+
497+
from typing import Any
498+
499+
class C:
500+
x: float
501+
y: float
502+
z: float
503+
504+
class D(C):
505+
x: int # Error: Covariant override of a mutable attribute
506+
# (base class "C" defined the type as "float",
507+
# expression has type "int") [mutable-override]
508+
y: float # OK
509+
z: Any # OK
510+
511+
def f(c: C) -> None:
512+
c.x = 1.1
513+
d = D()
514+
f(d)
515+
d.x >> 1 # This will crash at runtime, because d.x is now float, not an int
485516
486517
.. _code-unimported-reveal:
487518

@@ -493,8 +524,7 @@ that only existed during type-checking.
493524
In runtime it fails with expected ``NameError``,
494525
which can cause real problem in production, hidden from mypy.
495526

496-
But, in Python3.11 ``reveal_type``
497-
`was added to typing.py <https://docs.python.org/3/library/typing.html#typing.reveal_type>`_.
527+
But, in Python3.11 :py:func:`typing.reveal_type` was added.
498528
``typing_extensions`` ported this helper to all supported Python versions.
499529

500530
Now users can actually import ``reveal_type`` to make the runtime code safe.

docs/source/getting_started.rst

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -256,8 +256,7 @@ Mypy can also understand how to work with types from libraries that you use.
256256

257257
For instance, mypy comes out of the box with an intimate knowledge of the
258258
Python standard library. For example, here is a function which uses the
259-
``Path`` object from the
260-
`pathlib standard library module <https://docs.python.org/3/library/pathlib.html>`_:
259+
``Path`` object from the :doc:`pathlib standard library module <python:library/pathlib>`:
261260

262261
.. code-block:: python
263262

docs/source/html_builder.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,12 @@
99
from sphinx.addnodes import document
1010
from sphinx.application import Sphinx
1111
from sphinx.builders.html import StandaloneHTMLBuilder
12+
from sphinx.environment import BuildEnvironment
1213

1314

1415
class MypyHTMLBuilder(StandaloneHTMLBuilder):
15-
def __init__(self, app: Sphinx) -> None:
16-
super().__init__(app)
16+
def __init__(self, app: Sphinx, env: BuildEnvironment) -> None:
17+
super().__init__(app, env)
1718
self._ref_to_doc = {}
1819

1920
def write_doc(self, docname: str, doctree: document) -> None:

docs/source/more_types.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -829,7 +829,7 @@ Typing async/await
829829

830830
Mypy lets you type coroutines that use the ``async/await`` syntax.
831831
For more information regarding coroutines, see :pep:`492` and the
832-
`asyncio documentation <https://docs.python.org/3/library/asyncio.html>`_.
832+
`asyncio documentation <python:library/asyncio>`_.
833833

834834
Functions defined using ``async def`` are typed similar to normal functions.
835835
The return type annotation should be the same as the type of the value you

misc/gen_blog_post_html.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
"""Converter from CHANGELOG.md (Markdown) to HTML suitable for a mypy blog post.
2+
3+
How to use:
4+
5+
1. Write release notes in CHANGELOG.md.
6+
2. Make sure the heading for the next release is of form `## Mypy X.Y`.
7+
2. Run `misc/gen_blog_post_html.py X.Y > target.html`.
8+
4. Manually inspect and tweak the result.
9+
10+
Notes:
11+
12+
* There are some fragile assumptions. Double check the output.
13+
"""
14+
15+
import argparse
16+
import html
17+
import os
18+
import re
19+
import sys
20+
21+
22+
def format_lists(h: str) -> str:
23+
a = h.splitlines()
24+
r = []
25+
i = 0
26+
bullets = ("- ", "* ", " * ")
27+
while i < len(a):
28+
if a[i].startswith(bullets):
29+
r.append("<p><ul>")
30+
while i < len(a) and a[i].startswith(bullets):
31+
r.append("<li>%s" % a[i][2:].lstrip())
32+
i += 1
33+
r.append("</ul>")
34+
else:
35+
r.append(a[i])
36+
i += 1
37+
return "\n".join(r)
38+
39+
40+
def format_code(h: str) -> str:
41+
a = h.splitlines()
42+
r = []
43+
i = 0
44+
while i < len(a):
45+
if a[i].startswith(" ") or a[i].startswith("```"):
46+
indent = a[i].startswith(" ")
47+
if not indent:
48+
i += 1
49+
r.append("<pre>")
50+
while i < len(a) and (
51+
(indent and a[i].startswith(" ")) or (not indent and not a[i].startswith("```"))
52+
):
53+
# Undo &gt; and &lt;
54+
line = a[i].replace("&gt;", ">").replace("&lt;", "<")
55+
if not indent:
56+
line = " " + line
57+
r.append(html.escape(line))
58+
i += 1
59+
r.append("</pre>")
60+
if not indent and a[i].startswith("```"):
61+
i += 1
62+
else:
63+
r.append(a[i])
64+
i += 1
65+
return "\n".join(r)
66+
67+
68+
def convert(src: str) -> str:
69+
h = src
70+
71+
# Replace < and >.
72+
h = re.sub(r"<", "&lt;", h)
73+
h = re.sub(r">", "&gt;", h)
74+
75+
# Title
76+
h = re.sub(r"^## (Mypy [0-9.]+)", r"<h1>\1 Released</h1>", h, flags=re.MULTILINE)
77+
78+
# Subheadings
79+
h = re.sub(r"\n#### ([A-Z`].*)\n", r"\n<h2>\1</h2>\n", h)
80+
81+
# Sub-subheadings
82+
h = re.sub(r"\n\*\*([A-Z_`].*)\*\*\n", r"\n<h3>\1</h3>\n", h)
83+
h = re.sub(r"\n`\*\*([A-Z_`].*)\*\*\n", r"\n<h3>`\1</h3>\n", h)
84+
85+
# Translate `**`
86+
h = re.sub(r"`\*\*`", "<tt>**</tt>", h)
87+
88+
# Paragraphs
89+
h = re.sub(r"\n([A-Z])", r"\n<p>\1", h)
90+
91+
# Bullet lists
92+
h = format_lists(h)
93+
94+
# Code blocks
95+
h = format_code(h)
96+
97+
# Code fragments
98+
h = re.sub(r"`([^`]+)`", r"<tt>\1</tt>", h)
99+
100+
# Remove **** noise
101+
h = re.sub(r"\*\*\*\*", "", h)
102+
103+
# Bold text
104+
h = re.sub(r"\*\*([A-Za-z].*?)\*\*", r" <b>\1</b>", h)
105+
106+
# Emphasized text
107+
h = re.sub(r" \*([A-Za-z].*?)\*", r" <i>\1</i>", h)
108+
109+
# Remove redundant PR links to avoid double links (they will be generated below)
110+
h = re.sub(r"\[(#[0-9]+)\]\(https://github.com/python/mypy/pull/[0-9]+/?\)", r"\1", h)
111+
112+
# Issue and PR links
113+
h = re.sub(r"\((#[0-9]+)\) +\(([^)]+)\)", r"(\2, \1)", h)
114+
h = re.sub(
115+
r"fixes #([0-9]+)",
116+
r'fixes issue <a href="https://github.com/python/mypy/issues/\1">\1</a>',
117+
h,
118+
)
119+
h = re.sub(r"#([0-9]+)", r'PR <a href="https://github.com/python/mypy/pull/\1">\1</a>', h)
120+
h = re.sub(r"\) \(PR", ", PR", h)
121+
122+
# Markdown links
123+
h = re.sub(r"\[([^]]*)\]\(([^)]*)\)", r'<a href="\2">\1</a>', h)
124+
125+
# Add random links in case they are missing
126+
h = re.sub(
127+
r"contributors to typeshed:",
128+
'contributors to <a href="https://github.com/python/typeshed">typeshed</a>:',
129+
h,
130+
)
131+
132+
# Add missing top-level HTML tags
133+
h = '<html>\n<meta charset="utf-8" />\n<body>\n' + h + "</body>\n</html>"
134+
135+
return h
136+
137+
138+
def extract_version(src: str, version: str) -> str:
139+
a = src.splitlines()
140+
i = 0
141+
heading = f"## Mypy {version}"
142+
while i < len(a):
143+
if a[i].strip() == heading:
144+
break
145+
i += 1
146+
else:
147+
raise RuntimeError(f"Can't find heading {heading!r}")
148+
j = i + 1
149+
while not a[j].startswith("## "):
150+
j += 1
151+
return "\n".join(a[i:j])
152+
153+
154+
def main() -> None:
155+
parser = argparse.ArgumentParser(
156+
description="Generate HTML release blog post based on CHANGELOG.md and write to stdout."
157+
)
158+
parser.add_argument("version", help="mypy version, in form X.Y or X.Y.Z")
159+
args = parser.parse_args()
160+
version: str = args.version
161+
if not re.match(r"[0-9]+(\.[0-9]+)+$", version):
162+
sys.exit(f"error: Version must be of form X.Y or X.Y.Z, not {version!r}")
163+
changelog_path = os.path.join(os.path.dirname(__file__), os.path.pardir, "CHANGELOG.md")
164+
src = open(changelog_path).read()
165+
src = extract_version(src, version)
166+
dst = convert(src)
167+
sys.stdout.write(dst)
168+
169+
170+
if __name__ == "__main__":
171+
main()

0 commit comments

Comments
 (0)