Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
hugovk committed Nov 5, 2023
2 parents 18552d1 + ba8aa1f commit 449101a
Show file tree
Hide file tree
Showing 19 changed files with 702 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Doc/bugs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ though it may take a while to be processed.
`Helping with Documentation <https://devguide.python.org/docquality/#helping-with-documentation>`_
Comprehensive guide for individuals that are interested in contributing to Python documentation.

`Documentation Translations <https://devguide.python.org/documenting/#translating>`_
`Documentation Translations <https://devguide.python.org/documentation/translating/>`_
A list of GitHub pages for documentation translation and their primary contacts.


Expand Down
7 changes: 7 additions & 0 deletions Doc/library/ipaddress.rst
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,13 @@ write code that handles both IP versions correctly. Address objects are
``True`` if the address is reserved for link-local usage. See
:RFC:`3927`.

.. attribute:: ipv6_mapped

:class:`IPv4Address` object representing the IPv4-mapped IPv6 address. See :RFC:`4291`.

.. versionadded:: 3.13


.. _iana-ipv4-special-registry: https://www.iana.org/assignments/iana-ipv4-special-registry/iana-ipv4-special-registry.xhtml
.. _iana-ipv6-special-registry: https://www.iana.org/assignments/iana-ipv6-special-registry/iana-ipv6-special-registry.xhtml

Expand Down
2 changes: 1 addition & 1 deletion Doc/library/pdb.rst
Original file line number Diff line number Diff line change
Expand Up @@ -580,7 +580,7 @@ can be overridden by the local file.

Create an alias called *name* that executes *command*. The *command* must
*not* be enclosed in quotes. Replaceable parameters can be indicated by
``%1``, ``%2``, and so on, while ``%*`` is replaced by all the parameters.
``%1``, ``%2``, ... and ``%9``, while ``%*`` is replaced by all the parameters.
If *command* is omitted, the current alias for *name* is shown. If no
arguments are given, all aliases are listed.

Expand Down
6 changes: 6 additions & 0 deletions Doc/whatsnew/3.13.rst
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,12 @@ and only logged in :ref:`Python Development Mode <devmode>` or on :ref:`Python
built on debug mode <debug-build>`.
(Contributed by Victor Stinner in :gh:`62948`.)

ipaddress
---------

* Add the :attr:`ipaddress.IPv4Address.ipv6_mapped` property, which returns the IPv4-mapped IPv6 address.
(Contributed by Charles Machalow in :gh:`109466`.)

opcode
------

Expand Down
7 changes: 7 additions & 0 deletions Lib/bdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ def __init__(self, skip=None):
self.skip = set(skip) if skip else None
self.breaks = {}
self.fncache = {}
self.frame_trace_lines = {}
self.frame_returning = None

self._load_breaks()
Expand Down Expand Up @@ -331,6 +332,9 @@ def set_trace(self, frame=None):
while frame:
frame.f_trace = self.trace_dispatch
self.botframe = frame
# We need f_trace_liens == True for the debugger to work
self.frame_trace_lines[frame] = frame.f_trace_lines
frame.f_trace_lines = True
frame = frame.f_back
self.set_step()
sys.settrace(self.trace_dispatch)
Expand All @@ -349,6 +353,9 @@ def set_continue(self):
while frame and frame is not self.botframe:
del frame.f_trace
frame = frame.f_back
for frame, prev_trace_lines in self.frame_trace_lines.items():
frame.f_trace_lines = prev_trace_lines
self.frame_trace_lines = {}

def set_quit(self):
"""Set quitting attribute to True.
Expand Down
10 changes: 10 additions & 0 deletions Lib/ipaddress.py
Original file line number Diff line number Diff line change
Expand Up @@ -1389,6 +1389,16 @@ def is_link_local(self):
"""
return self in self._constants._linklocal_network

@property
def ipv6_mapped(self):
"""Return the IPv4-mapped IPv6 address.
Returns:
The IPv4-mapped IPv6 address per RFC 4291.
"""
return IPv6Address(f'::ffff:{self}')


class IPv4Interface(IPv4Address):

Expand Down
33 changes: 27 additions & 6 deletions Lib/pdb.py
Original file line number Diff line number Diff line change
Expand Up @@ -597,11 +597,20 @@ def precmd(self, line):
args = line.split()
while args[0] in self.aliases:
line = self.aliases[args[0]]
ii = 1
for tmpArg in args[1:]:
line = line.replace("%" + str(ii),
tmpArg)
ii += 1
for idx in range(1, 10):
if f'%{idx}' in line:
if idx >= len(args):
self.error(f"Not enough arguments for alias '{args[0]}'")
# This is a no-op
return "!"
line = line.replace(f'%{idx}', args[idx])
elif '%*' not in line:
if idx < len(args):
self.error(f"Too many arguments for alias '{args[0]}'")
# This is a no-op
return "!"
break

line = line.replace("%*", ' '.join(args[1:]))
args = line.split()
# split into ';;' separated commands
Expand All @@ -616,6 +625,7 @@ def precmd(self, line):

# Replace all the convenience variables
line = re.sub(r'\$([a-zA-Z_][a-zA-Z0-9_]*)', r'__pdb_convenience_variables["\1"]', line)

return line

def onecmd(self, line):
Expand Down Expand Up @@ -1797,7 +1807,18 @@ def do_alias(self, arg):
else:
self.error(f"Unknown alias '{args[0]}'")
else:
self.aliases[args[0]] = ' '.join(args[1:])
# Do a validation check to make sure no replaceable parameters
# are skipped if %* is not used.
alias = ' '.join(args[1:])
if '%*' not in alias:
consecutive = True
for idx in range(1, 10):
if f'%{idx}' not in alias:
consecutive = False
if f'%{idx}' in alias and not consecutive:
self.error("Replaceable parameters must be consecutive")
return
self.aliases[args[0]] = alias

def do_unalias(self, arg):
"""unalias name
Expand Down
146 changes: 146 additions & 0 deletions Lib/test/test_capi/test_complex.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
import unittest
import warnings

from test.test_capi.test_getargs import (BadComplex, BadComplex2, Complex,
FloatSubclass, Float, BadFloat,
BadFloat2, ComplexSubclass)
from test.support import import_helper


_testcapi = import_helper.import_module('_testcapi')

NULL = None

class BadComplex3:
def __complex__(self):
raise RuntimeError


class CAPIComplexTest(unittest.TestCase):
def test_check(self):
# Test PyComplex_Check()
check = _testcapi.complex_check

self.assertTrue(check(1+2j))
self.assertTrue(check(ComplexSubclass(1+2j)))
self.assertFalse(check(Complex()))
self.assertFalse(check(3))
self.assertFalse(check(3.0))
self.assertFalse(check(object()))

# CRASHES check(NULL)

def test_checkexact(self):
# PyComplex_CheckExact()
checkexact = _testcapi.complex_checkexact

self.assertTrue(checkexact(1+2j))
self.assertFalse(checkexact(ComplexSubclass(1+2j)))
self.assertFalse(checkexact(Complex()))
self.assertFalse(checkexact(3))
self.assertFalse(checkexact(3.0))
self.assertFalse(checkexact(object()))

# CRASHES checkexact(NULL)

def test_fromccomplex(self):
# Test PyComplex_FromCComplex()
fromccomplex = _testcapi.complex_fromccomplex

self.assertEqual(fromccomplex(1+2j), 1.0+2.0j)

def test_fromdoubles(self):
# Test PyComplex_FromDoubles()
fromdoubles = _testcapi.complex_fromdoubles

self.assertEqual(fromdoubles(1.0, 2.0), 1.0+2.0j)

def test_realasdouble(self):
# Test PyComplex_RealAsDouble()
realasdouble = _testcapi.complex_realasdouble

self.assertEqual(realasdouble(1+2j), 1.0)
self.assertEqual(realasdouble(-1+0j), -1.0)
self.assertEqual(realasdouble(4.25), 4.25)
self.assertEqual(realasdouble(-1.0), -1.0)
self.assertEqual(realasdouble(42), 42.)
self.assertEqual(realasdouble(-1), -1.0)

# Test subclasses of complex/float
self.assertEqual(realasdouble(ComplexSubclass(1+2j)), 1.0)
self.assertEqual(realasdouble(FloatSubclass(4.25)), 4.25)

# Test types with __complex__ dunder method
# Function doesn't support classes with __complex__ dunder, see #109598
self.assertRaises(TypeError, realasdouble, Complex())

# Test types with __float__ dunder method
self.assertEqual(realasdouble(Float()), 4.25)
self.assertRaises(TypeError, realasdouble, BadFloat())
with self.assertWarns(DeprecationWarning):
self.assertEqual(realasdouble(BadFloat2()), 4.25)

self.assertRaises(TypeError, realasdouble, object())

# CRASHES realasdouble(NULL)

def test_imagasdouble(self):
# Test PyComplex_ImagAsDouble()
imagasdouble = _testcapi.complex_imagasdouble

self.assertEqual(imagasdouble(1+2j), 2.0)
self.assertEqual(imagasdouble(1-1j), -1.0)
self.assertEqual(imagasdouble(4.25), 0.0)
self.assertEqual(imagasdouble(42), 0.0)

# Test subclasses of complex/float
self.assertEqual(imagasdouble(ComplexSubclass(1+2j)), 2.0)
self.assertEqual(imagasdouble(FloatSubclass(4.25)), 0.0)

# Test types with __complex__ dunder method
# Function doesn't support classes with __complex__ dunder, see #109598
self.assertEqual(imagasdouble(Complex()), 0.0)

# Function returns 0.0 anyway, see #109598
self.assertEqual(imagasdouble(object()), 0.0)

# CRASHES imagasdouble(NULL)

def test_asccomplex(self):
# Test PyComplex_AsCComplex()
asccomplex = _testcapi.complex_asccomplex

self.assertEqual(asccomplex(1+2j), 1.0+2.0j)
self.assertEqual(asccomplex(-1+2j), -1.0+2.0j)
self.assertEqual(asccomplex(4.25), 4.25+0.0j)
self.assertEqual(asccomplex(-1.0), -1.0+0.0j)
self.assertEqual(asccomplex(42), 42+0j)
self.assertEqual(asccomplex(-1), -1.0+0.0j)

# Test subclasses of complex/float
self.assertEqual(asccomplex(ComplexSubclass(1+2j)), 1.0+2.0j)
self.assertEqual(asccomplex(FloatSubclass(4.25)), 4.25+0.0j)

# Test types with __complex__ dunder method
self.assertEqual(asccomplex(Complex()), 4.25+0.5j)
self.assertRaises(TypeError, asccomplex, BadComplex())
with self.assertWarns(DeprecationWarning):
self.assertEqual(asccomplex(BadComplex2()), 4.25+0.5j)
with warnings.catch_warnings():
warnings.simplefilter("error", DeprecationWarning)
self.assertRaises(DeprecationWarning, asccomplex, BadComplex2())
self.assertRaises(RuntimeError, asccomplex, BadComplex3())

# Test types with __float__ dunder method
self.assertEqual(asccomplex(Float()), 4.25+0.0j)
self.assertRaises(TypeError, asccomplex, BadFloat())
with self.assertWarns(DeprecationWarning):
self.assertEqual(asccomplex(BadFloat2()), 4.25+0.0j)

self.assertRaises(TypeError, asccomplex, object())

# CRASHES asccomplex(NULL)


if __name__ == "__main__":
unittest.main()
Loading

0 comments on commit 449101a

Please sign in to comment.