Skip to content

bpo-39684: Combine two if/thens #18557

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 5 commits into from
Closed
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
3 changes: 0 additions & 3 deletions Doc/library/functions.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1829,9 +1829,6 @@ are always available. They are listed here in alphabetical order.
Negative values for *level* are no longer supported (which also changes
the default value to 0).

.. versionchanged:: 3.9
When the command line options :option:`-E` or :option:`-I` are being used,
the environment variable :envvar:`PYTHONCASEOK` is now ignored.

.. rubric:: Footnotes

Expand Down
9 changes: 9 additions & 0 deletions Doc/library/math.rst
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,15 @@ Number-theoretic and representation functions
.. versionadded:: 3.5


.. function:: lcm(a, b)

Return the least common multiple of integers *a* and *b*. The value of
``lcm(a, b)`` is the smallest nonnegative integer that is a multiple of
both *a* and *b*. If either *a* or *b* is zero then ``lcm(a, b)`` is zero.

.. versionadded:: 3.9


.. function:: isclose(a, b, *, rel_tol=1e-09, abs_tol=0.0)

Return ``True`` if the values *a* and *b* are close to each other and
Expand Down
16 changes: 14 additions & 2 deletions Doc/library/typing.rst
Original file line number Diff line number Diff line change
Expand Up @@ -996,8 +996,20 @@ The module defines the following classes, functions and decorators:
Point2D = TypedDict('Point2D', x=int, y=int, label=str)
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})

See :pep:`589` for more examples and detailed rules of using ``TypedDict``
with type checkers.
By default, all keys must be present in a TypedDict. It is possible
to override this by specifying totality.
Usage::

class point2D(TypedDict, total=False):
x: int
y: int

This means that a point2D TypedDict can have any of the keys omitted.A type
checker is only expected to support a literal False or True as the value of
the total argument. True is the default, and makes all items defined in the
class body be required.

See :pep:`589` for more examples and detailed rules of using ``TypedDict``.

.. versionadded:: 3.8

Expand Down
6 changes: 3 additions & 3 deletions Doc/whatsnew/3.9.rst
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,9 @@ import attempts.
math
----

Add :func:`math.lcm`: return the least common multiple of *a* and *b*.
(Contributed by Ananthakrishnan in :issue:`39479`.)

Add :func:`math.nextafter`: return the next floating-point value after *x*
towards *y*.
(Contributed by Victor Stinner in :issue:`39288`.)
Expand Down Expand Up @@ -584,9 +587,6 @@ Changes in the Python API
since the *buffering* parameter has been removed.
(Contributed by Victor Stinner in :issue:`39357`.)

* The :mod:`importlib` module now ignores the :envvar:`PYTHONCASEOK`
environment variable when the :option:`-E` or :option:`-I` command line
options are being used.

CPython bytecode changes
------------------------
Expand Down
2 changes: 1 addition & 1 deletion Lib/importlib/_bootstrap_external.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def _make_relax_case():

def _relax_case():
"""True if filenames must be checked case-insensitively."""
return not sys.flags.ignore_environment and key in _os.environ
return key in _os.environ
else:
def _relax_case():
"""True if filenames must be checked case-insensitively."""
Expand Down
35 changes: 35 additions & 0 deletions Lib/test/test_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -974,6 +974,41 @@ def __index__(self):
with self.assertRaises(TypeError):
math.isqrt(value)

def test_lcm(self):
lcm = math.lcm
self.assertEqual(lcm(0, 0), 0)
self.assertEqual(lcm(1, 0), 0)
self.assertEqual(lcm(-1, 0), 0)
self.assertEqual(lcm(0, 1), 0)
self.assertEqual(lcm(0, -1), 0)
self.assertEqual(lcm(7, 1), 7)
self.assertEqual(lcm(7, -1), 7)
self.assertEqual(lcm(-23, 15), 345)
self.assertEqual(lcm(120, 84), 840)
self.assertEqual(lcm(84, -120), 840)
self.assertEqual(lcm(1216342683557601535506311712,
436522681849110124616458784),
16592536571065866494401400422922201534178938447014944)
x = 43461045657039990237
y = 10645022458251153277

for c in (652560,
57655923087165495981):
a = x * c
b = y * c
d = x * y * c
self.assertEqual(lcm(a, b), d)
self.assertEqual(lcm(b, a), d)
self.assertEqual(lcm(-a, b), d)
self.assertEqual(lcm(b, -a), d)
self.assertEqual(lcm(a, -b), d)
self.assertEqual(lcm(-b, a), d)
self.assertEqual(lcm(-a, -b), d)
self.assertEqual(lcm(-b, -a), d)
self.assertEqual(lcm(MyIndexable(120), MyIndexable(84)), 840)
self.assertRaises(TypeError, lcm, 120.0, 84)
self.assertRaises(TypeError, lcm, 120, 84.0)

def testLdexp(self):
self.assertRaises(TypeError, math.ldexp)
self.ftest('ldexp(0,1)', math.ldexp(0,1), 0)
Expand Down
15 changes: 14 additions & 1 deletion Lib/typing.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
* Public helper functions: get_type_hints, overload, cast, no_type_check,
no_type_check_decorator.
* Generic aliases for collections.abc ABCs and few additional protocols.
* Special types: NewType, NamedTuple, TypedDict (may be added soon).
* Special types: NewType, NamedTuple, TypedDict.
* Wrapper submodules for re and io related types.
"""

Expand Down Expand Up @@ -1885,6 +1885,19 @@ class Point2D(TypedDict):
Point2D = TypedDict('Point2D', x=int, y=int, label=str)
Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str})

By default, all keys must be present in a TypedDict. It is possible
to override this by specifying totality.
Usage::

class point2D(TypedDict, total=False):
x: int
y: int

This means that a point2D TypedDict can have any of the keys omitted.A type
checker is only expected to support a literal False or True as the value of
the total argument. True is the default, and makes all items defined in the
class body be required.

The class syntax is only supported in Python 3.6+, while two other
syntax forms work for Python 2.7 and 3.2+
"""
Expand Down
1 change: 1 addition & 0 deletions Misc/ACKS
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ Rose Ames
A. Amoroso
Mark Anacker
Shashwat Anand
Ananthakrishnan
Anders Andersen
Tycho Andersen
John Anderson
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Updated documentation of ``total`` flag of TypeDict.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add :func:`math.lcm` function: least common multiple.
32 changes: 31 additions & 1 deletion Modules/clinic/mathmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions Modules/mathmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -2017,6 +2017,59 @@ math_factorial(PyObject *module, PyObject *arg)
}


/*[clinic input]
math.lcm
x as a: object
y as b: object
/
least common multiple of x and y
[clinic start generated code]*/

static PyObject *
math_lcm_impl(PyObject *module, PyObject *a, PyObject *b)
/*[clinic end generated code: output=6f83fb6d671074ba input=efb3d7b7334b7118]*/
{
PyObject *g, *m, *f, *ab;

a = PyNumber_Index(a);
if (a == NULL) {
return NULL;
}
b = PyNumber_Index(b);
if (b == NULL) {
Py_DECREF(a);
return NULL;
}
if (_PyLong_Sign(a) == 0 || _PyLong_Sign(b) == 0) {
Py_DECREF(a);
Py_DECREF(b);
return PyLong_FromLong(0);
}
g = _PyLong_GCD(a, b);
if (g == NULL) {
Py_DECREF(a);
Py_DECREF(b);
return NULL;
}
f = PyNumber_FloorDivide(a, g);
Py_DECREF(g);
Py_DECREF(a);
if (f == NULL) {
Py_DECREF(b);
return NULL;
}
m = PyNumber_Multiply(f, b);
Py_DECREF(f);
Py_DECREF(b);
if (m == NULL) {
return NULL;
}
ab = PyNumber_Absolute(m);
Py_DECREF(m);
return ab;
}


/*[clinic input]
math.trunc

Expand Down Expand Up @@ -3362,6 +3415,7 @@ static PyMethodDef math_methods[] = {
MATH_ISINF_METHODDEF
MATH_ISNAN_METHODDEF
MATH_ISQRT_METHODDEF
MATH_LCM_METHODDEF
MATH_LDEXP_METHODDEF
{"lgamma", math_lgamma, METH_O, math_lgamma_doc},
MATH_LOG_METHODDEF
Expand Down
11 changes: 3 additions & 8 deletions Objects/unicodeobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -12209,20 +12209,15 @@ PyUnicode_IsIdentifier(PyObject *self)

int kind = 0;
void *data = NULL;
wchar_t *wstr;
const wchar_t *wstr = NULL;
Py_UCS4 ch;
if (ready) {
kind = PyUnicode_KIND(self);
data = PyUnicode_DATA(self);
}
else {
wstr = _PyUnicode_WSTR(self);
}

Py_UCS4 ch;
if (ready) {
ch = PyUnicode_READ(kind, data, 0);
}
else {
wstr = _PyUnicode_WSTR(self);
ch = wstr[0];
}
/* PEP 3131 says that the first character must be in
Expand Down
Loading