diff options
| author | Alexander Smirnov <[email protected]> | 2024-03-13 10:33:47 +0000 |
|---|---|---|
| committer | Alexander Smirnov <[email protected]> | 2024-03-13 10:33:47 +0000 |
| commit | 1df54be5538361db7f33afc618d1597272414294 (patch) | |
| tree | bb39e4b75db0b0a9722468eacef91ffd1388eb8d /contrib/python | |
| parent | 7a673cf01feefbe95bf5e7396d9179a5f283aeba (diff) | |
| parent | 01aef806626b16e9817e07f718f10e151f52e400 (diff) | |
Merge branch 'rightlib' into mergelibs-240313-1032
Diffstat (limited to 'contrib/python')
72 files changed, 962 insertions, 445 deletions
diff --git a/contrib/python/cachetools/py3/.dist-info/METADATA b/contrib/python/cachetools/py3/.dist-info/METADATA index 9504a9426b2..5846ebf1676 100644 --- a/contrib/python/cachetools/py3/.dist-info/METADATA +++ b/contrib/python/cachetools/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: cachetools -Version: 5.3.2 +Version: 5.3.3 Summary: Extensible memoizing collections and decorators Home-page: https://github.com/tkem/cachetools/ Author: Thomas Kemmer @@ -116,15 +116,16 @@ Related Projects ------------------------------------------------------------------------ - asyncache_: Helpers to use cachetools with async functions +- cacheing_: Pure Python Cacheing Library - CacheToolsUtils_: Cachetools Utilities -- `kids.cache`_: Kids caching library +- kids.cache_: Kids caching library - shelved-cache_: Persistent cache for Python cachetools License ------------------------------------------------------------------------ -Copyright (c) 2014-2023 Thomas Kemmer. +Copyright (c) 2014-2024 Thomas Kemmer. Licensed under the `MIT License`_. @@ -143,6 +144,7 @@ Licensed under the `MIT License`_. .. _MIT License: https://raw.github.com/tkem/cachetools/master/LICENSE .. _asyncache: https://pypi.org/project/asyncache/ +.. _cacheing: https://github.com/breid48/cacheing .. _CacheToolsUtils: https://pypi.org/project/CacheToolsUtils/ .. _kids.cache: https://pypi.org/project/kids.cache/ .. _shelved-cache: https://pypi.org/project/shelved-cache/ diff --git a/contrib/python/cachetools/py3/LICENSE b/contrib/python/cachetools/py3/LICENSE index bd185ce7ac6..67da58ecd7a 100644 --- a/contrib/python/cachetools/py3/LICENSE +++ b/contrib/python/cachetools/py3/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2014-2022 Thomas Kemmer +Copyright (c) 2014-2024 Thomas Kemmer Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in diff --git a/contrib/python/cachetools/py3/README.rst b/contrib/python/cachetools/py3/README.rst index 42662c5a35c..a5627cc114a 100644 --- a/contrib/python/cachetools/py3/README.rst +++ b/contrib/python/cachetools/py3/README.rst @@ -91,15 +91,16 @@ Related Projects ------------------------------------------------------------------------ - asyncache_: Helpers to use cachetools with async functions +- cacheing_: Pure Python Cacheing Library - CacheToolsUtils_: Cachetools Utilities -- `kids.cache`_: Kids caching library +- kids.cache_: Kids caching library - shelved-cache_: Persistent cache for Python cachetools License ------------------------------------------------------------------------ -Copyright (c) 2014-2023 Thomas Kemmer. +Copyright (c) 2014-2024 Thomas Kemmer. Licensed under the `MIT License`_. @@ -118,6 +119,7 @@ Licensed under the `MIT License`_. .. _MIT License: https://raw.github.com/tkem/cachetools/master/LICENSE .. _asyncache: https://pypi.org/project/asyncache/ +.. _cacheing: https://github.com/breid48/cacheing .. _CacheToolsUtils: https://pypi.org/project/CacheToolsUtils/ .. _kids.cache: https://pypi.org/project/kids.cache/ .. _shelved-cache: https://pypi.org/project/shelved-cache/ diff --git a/contrib/python/cachetools/py3/cachetools/__init__.py b/contrib/python/cachetools/py3/cachetools/__init__.py index 61c12bef47f..341c1c7ff09 100644 --- a/contrib/python/cachetools/py3/cachetools/__init__.py +++ b/contrib/python/cachetools/py3/cachetools/__init__.py @@ -13,7 +13,7 @@ __all__ = ( "cachedmethod", ) -__version__ = "5.3.2" +__version__ = "5.3.3" import collections import collections.abc diff --git a/contrib/python/cachetools/py3/ya.make b/contrib/python/cachetools/py3/ya.make index 25d5ac4cdf4..71b6f19603e 100644 --- a/contrib/python/cachetools/py3/ya.make +++ b/contrib/python/cachetools/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(5.3.2) +VERSION(5.3.3) LICENSE(MIT) diff --git a/contrib/python/future/py3/.dist-info/METADATA b/contrib/python/future/py3/.dist-info/METADATA index 124bf500d0b..3d0e5512c62 100644 --- a/contrib/python/future/py3/.dist-info/METADATA +++ b/contrib/python/future/py3/.dist-info/METADATA @@ -1,13 +1,13 @@ Metadata-Version: 2.1 Name: future -Version: 0.18.3 +Version: 1.0.0 Summary: Clean single-source support for Python 3 and 2 Home-page: https://python-future.org Author: Ed Schofield Author-email: [email protected] License: MIT +Project-URL: Source, https://github.com/PythonCharmers/python-future Keywords: future past python3 migration futurize backport six 2to3 modernize pasteurize 3to2 -Platform: UNKNOWN Classifier: Programming Language :: Python Classifier: Programming Language :: Python :: 2 Classifier: Programming Language :: Python :: 2.6 @@ -18,11 +18,17 @@ Classifier: Programming Language :: Python :: 3.4 Classifier: Programming Language :: Python :: 3.5 Classifier: Programming Language :: Python :: 3.6 Classifier: Programming Language :: Python :: 3.7 +Classifier: Programming Language :: Python :: 3.8 +Classifier: Programming Language :: Python :: 3.9 +Classifier: Programming Language :: Python :: 3.10 +Classifier: Programming Language :: Python :: 3.11 +Classifier: Programming Language :: Python :: 3.12 Classifier: License :: OSI Approved Classifier: License :: OSI Approved :: MIT License -Classifier: Development Status :: 4 - Beta +Classifier: Development Status :: 6 - Mature Classifier: Intended Audience :: Developers Requires-Python: >=2.6, !=3.0.*, !=3.1.*, !=3.2.* +License-File: LICENSE.txt future: Easy, safe support for Python 2/3 compatibility @@ -78,7 +84,7 @@ Automatic conversion -------------------- An included script called `futurize -<http://python-future.org/automatic_conversion.html>`_ aids in converting +<https://python-future.org/automatic_conversion.html>`_ aids in converting code (from either Python 2 or Python 3) to code compatible with both platforms. It is similar to ``python-modernize`` but goes further in providing Python 3 compatibility through the use of the backported types @@ -88,22 +94,19 @@ and builtin functions in ``future``. Documentation ------------- -See: http://python-future.org +See: https://python-future.org Credits ------- :Author: Ed Schofield, Jordan M. Adler, et al -:Sponsor: Python Charmers Pty Ltd, Australia, and Python Charmers Pte - Ltd, Singapore. http://pythoncharmers.com -:Others: See docs/credits.rst or http://python-future.org/credits.html +:Sponsor: Python Charmers: https://pythoncharmers.com +:Others: See docs/credits.rst or https://python-future.org/credits.html Licensing --------- -Copyright 2013-2019 Python Charmers Pty Ltd, Australia. +Copyright 2013-2024 Python Charmers, Australia. The software is distributed under an MIT licence. See LICENSE.txt. - - diff --git a/contrib/python/future/py3/.dist-info/entry_points.txt b/contrib/python/future/py3/.dist-info/entry_points.txt index 45d1a880fbd..74aec276c83 100644 --- a/contrib/python/future/py3/.dist-info/entry_points.txt +++ b/contrib/python/future/py3/.dist-info/entry_points.txt @@ -1,4 +1,3 @@ [console_scripts] futurize = libfuturize.main:main pasteurize = libpasteurize.main:main - diff --git a/contrib/python/future/py3/LICENSE.txt b/contrib/python/future/py3/LICENSE.txt index 4c904dba8fe..275cafd3036 100644 --- a/contrib/python/future/py3/LICENSE.txt +++ b/contrib/python/future/py3/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2013-2019 Python Charmers Pty Ltd, Australia +Copyright (c) 2013-2024 Python Charmers, Australia Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/contrib/python/future/py3/README.rst b/contrib/python/future/py3/README.rst index 1ab43e53d7a..a3aceb7d4a0 100644 --- a/contrib/python/future/py3/README.rst +++ b/contrib/python/future/py3/README.rst @@ -3,11 +3,8 @@ Overview: Easy, clean, reliable Python 2/3 compatibility ======================================================== -.. image:: https://travis-ci.org/PythonCharmers/python-future.svg?branch=master - :target: https://travis-ci.org/PythonCharmers/python-future - -.. image:: https://readthedocs.org/projects/python-future/badge/?version=latest - :target: https://python-future.readthedocs.io/en/latest/?badge=latest +.. image:: https://github.com/PythonCharmers/python-future/actions/workflows/ci.yml/badge.svg?branch=master + :target: https://github.com/PythonCharmers/python-future/actions/workflows/ci.yml?query=branch%3Amaster ``python-future`` is the missing compatibility layer between Python 2 and Python 3. It allows you to use a single, clean Python 3.x-compatible @@ -19,9 +16,21 @@ ports of features from Python 3 and 2. It also comes with ``futurize`` and either Py2 or Py3 code easily to support both Python 2 and 3 in a single clean Py3-style codebase, module by module. -Notable projects that use ``python-future`` for Python 2/3 compatibility -are `Mezzanine <http://mezzanine.jupo.org/>`_ and `ObsPy -<http://obspy.org>`_. +The ``python-future`` project has been downloaded over 1.7 billion times. + +.. _status + +Status +------ + +The ``python-future`` project was created in 2013 to attempt to save Python from +the schism of version incompatibility that was threatening to tear apart the +language (as Perl 6 contributed to the death of Perl). + +That time is now past. Thanks to a huge porting effort across the Python +community, Python 3 eventually thrived. Python 2 reached its end of life in +2020 and the ``python-future`` package should no longer be necessary. Use it to +help with porting legacy code to Python 3 but don't depend on it for new code. .. _features: @@ -223,11 +232,14 @@ into this code which runs on both Py2 and Py3: name = input() greet(name) +The first four lines have no effect under Python 3 and can be removed from +the codebase when Python 2 compatibility is no longer required. + See :ref:`forwards-conversion` and :ref:`backwards-conversion` for more details. Automatic translation ---------------------- +~~~~~~~~~~~~~~~~~~~~~ The ``past`` package can automatically translate some simple Python 2 modules to Python 3 upon import. The goal is to support the "long tail" of @@ -264,10 +276,9 @@ properly to a Python 2/3 compatible codebase using a tool like Note: the auto-translation feature is still in alpha; it needs more testing and development, and will likely never be perfect. -For more info, see :ref:`translation`. Pre-commit hooks ----------------- +~~~~~~~~~~~~~~~~ `Pre-commit <https://pre-commit.com/>`_ is a framework for managing and maintaining multi-language pre-commit hooks. @@ -304,23 +315,25 @@ Licensing :Author: Ed Schofield, Jordan M. Adler, et al -:Copyright: 2013-2019 Python Charmers Pty Ltd, Australia. +:Copyright: 2013-2024 Python Charmers, Australia. -:Sponsors: Python Charmers Pty Ltd, Australia, and Python Charmers Pte - Ltd, Singapore. http://pythoncharmers.com +:Sponsors: Python Charmers: https://pythoncharmers.com - Pinterest https://opensource.pinterest.com/ + Pinterest https://opensource.pinterest.com -:Licence: MIT. See ``LICENSE.txt`` or `here <http://python-future.org/credits.html>`_. +:Licence: MIT. See ``LICENSE.txt`` or `here <https://python-future.org/credits.html>`_. -:Other credits: See `here <http://python-future.org/credits.html>`_. +:Other credits: See `here <https://python-future.org/credits.html>`_. +Docs +---- +See the docs `here <https://python-future.org>`_. Next steps ---------- If you are new to Python-Future, check out the `Quickstart Guide -<http://python-future.org/quickstart.html>`_. +<https://python-future.org/quickstart.html>`_. For an update on changes in the latest version, see the `What's New -<http://python-future.org/whatsnew.html>`_ page. +<https://python-future.org/whatsnew.html>`_ page. diff --git a/contrib/python/future/py3/future/__init__.py b/contrib/python/future/py3/future/__init__.py index b609299a7a2..b097fd81eb6 100644 --- a/contrib/python/future/py3/future/__init__.py +++ b/contrib/python/future/py3/future/__init__.py @@ -52,7 +52,7 @@ Automatic conversion -------------------- An included script called `futurize -<http://python-future.org/automatic_conversion.html>`_ aids in converting +<https://python-future.org/automatic_conversion.html>`_ aids in converting code (from either Python 2 or Python 3) to code compatible with both platforms. It is similar to ``python-modernize`` but goes further in providing Python 3 compatibility through the use of the backported types @@ -62,21 +62,20 @@ and builtin functions in ``future``. Documentation ------------- -See: http://python-future.org +See: https://python-future.org Credits ------- :Author: Ed Schofield, Jordan M. Adler, et al -:Sponsor: Python Charmers Pty Ltd, Australia, and Python Charmers Pte - Ltd, Singapore. http://pythoncharmers.com -:Others: See docs/credits.rst or http://python-future.org/credits.html +:Sponsor: Python Charmers: https://pythoncharmers.com +:Others: See docs/credits.rst or https://python-future.org/credits.html Licensing --------- -Copyright 2013-2019 Python Charmers Pty Ltd, Australia. +Copyright 2013-2024 Python Charmers, Australia. The software is distributed under an MIT licence. See LICENSE.txt. """ @@ -84,10 +83,10 @@ The software is distributed under an MIT licence. See LICENSE.txt. __title__ = 'future' __author__ = 'Ed Schofield' __license__ = 'MIT' -__copyright__ = 'Copyright 2013-2019 Python Charmers Pty Ltd' -__ver_major__ = 0 -__ver_minor__ = 18 -__ver_patch__ = 3 +__copyright__ = 'Copyright 2013-2024 Python Charmers (https://pythoncharmers.com)' +__ver_major__ = 1 +__ver_minor__ = 0 +__ver_patch__ = 0 __ver_sub__ = '' __version__ = "%d.%d.%d%s" % (__ver_major__, __ver_minor__, __ver_patch__, __ver_sub__) diff --git a/contrib/python/future/py3/future/backports/datetime.py b/contrib/python/future/py3/future/backports/datetime.py index 3261014e056..8cd62ddfa5c 100644 --- a/contrib/python/future/py3/future/backports/datetime.py +++ b/contrib/python/future/py3/future/backports/datetime.py @@ -689,7 +689,7 @@ class date(object): @classmethod def fromordinal(cls, n): - """Contruct a date from a proleptic Gregorian ordinal. + """Construct a date from a proleptic Gregorian ordinal. January 1 of year 1 is day 1. Only the year, month and day are non-zero in the result. diff --git a/contrib/python/future/py3/future/backports/email/_header_value_parser.py b/contrib/python/future/py3/future/backports/email/_header_value_parser.py index 43957edc12f..59b1b318f38 100644 --- a/contrib/python/future/py3/future/backports/email/_header_value_parser.py +++ b/contrib/python/future/py3/future/backports/email/_header_value_parser.py @@ -2867,7 +2867,7 @@ def parse_content_type_header(value): _find_mime_parameters(ctype, value) return ctype ctype.append(token) - # XXX: If we really want to follow the formal grammer we should make + # XXX: If we really want to follow the formal grammar we should make # mantype and subtype specialized TokenLists here. Probably not worth it. if not value or value[0] != '/': ctype.defects.append(errors.InvalidHeaderDefect( diff --git a/contrib/python/future/py3/future/backports/email/parser.py b/contrib/python/future/py3/future/backports/email/parser.py index df1c6e28689..79f0e5a33eb 100644 --- a/contrib/python/future/py3/future/backports/email/parser.py +++ b/contrib/python/future/py3/future/backports/email/parser.py @@ -26,7 +26,7 @@ class Parser(object): textual representation of the message. The string must be formatted as a block of RFC 2822 headers and header - continuation lines, optionally preceeded by a `Unix-from' header. The + continuation lines, optionally preceded by a `Unix-from' header. The header block is terminated either by the end of the string or by a blank line. @@ -92,7 +92,7 @@ class BytesParser(object): textual representation of the message. The input must be formatted as a block of RFC 2822 headers and header - continuation lines, optionally preceeded by a `Unix-from' header. The + continuation lines, optionally preceded by a `Unix-from' header. The header block is terminated either by the end of the input or by a blank line. diff --git a/contrib/python/future/py3/future/backports/http/cookiejar.py b/contrib/python/future/py3/future/backports/http/cookiejar.py index 0ad80a0258a..a39242c0827 100644 --- a/contrib/python/future/py3/future/backports/http/cookiejar.py +++ b/contrib/python/future/py3/future/backports/http/cookiejar.py @@ -1851,7 +1851,7 @@ def lwp_cookie_str(cookie): class LWPCookieJar(FileCookieJar): """ The LWPCookieJar saves a sequence of "Set-Cookie3" lines. - "Set-Cookie3" is the format used by the libwww-perl libary, not known + "Set-Cookie3" is the format used by the libwww-perl library, not known to be compatible with any browser, but which is easy to read and doesn't lose information about RFC 2965 cookies. diff --git a/contrib/python/future/py3/future/backports/xmlrpc/client.py b/contrib/python/future/py3/future/backports/xmlrpc/client.py index 3f0cae9b00f..5c2cee0958c 100644 --- a/contrib/python/future/py3/future/backports/xmlrpc/client.py +++ b/contrib/python/future/py3/future/backports/xmlrpc/client.py @@ -133,9 +133,9 @@ from __future__ import (absolute_import, division, print_function, unicode_literals) from future.builtins import bytes, dict, int, range, str -import sys import base64 -if sys.version_info[0] < 3: +import sys +if sys.version_info < (3, 9): # Py2.7 compatibility hack base64.encodebytes = base64.encodestring base64.decodebytes = base64.decodestring @@ -1255,7 +1255,7 @@ class Transport(object): # Send HTTP request. # # @param host Host descriptor (URL or (URL, x509 info) tuple). - # @param handler Targer RPC handler (a path relative to host) + # @param handler Target RPC handler (a path relative to host) # @param request_body The XML-RPC request body # @param debug Enable debugging if debug is true. # @return An HTTPConnection. diff --git a/contrib/python/future/py3/future/builtins/__init__.py b/contrib/python/future/py3/future/builtins/__init__.py index 8bc1649d2fd..1734cd45fe3 100644 --- a/contrib/python/future/py3/future/builtins/__init__.py +++ b/contrib/python/future/py3/future/builtins/__init__.py @@ -2,7 +2,7 @@ A module that brings in equivalents of the new and modified Python 3 builtins into Py2. Has no effect on Py3. -See the docs `here <http://python-future.org/what-else.html>`_ +See the docs `here <https://python-future.org/what-else.html>`_ (``docs/what-else.rst``) for more information. """ diff --git a/contrib/python/future/py3/future/moves/_dummy_thread.py b/contrib/python/future/py3/future/moves/_dummy_thread.py index e5dca348fbd..6633f42e0cb 100644 --- a/contrib/python/future/py3/future/moves/_dummy_thread.py +++ b/contrib/python/future/py3/future/moves/_dummy_thread.py @@ -1,11 +1,13 @@ from __future__ import absolute_import -from future.utils import PY3 +from future.utils import PY3, PY39_PLUS -if PY3: - try: + +if PY39_PLUS: + # _dummy_thread and dummy_threading modules were both deprecated in + # Python 3.7 and removed in Python 3.9 + from _thread import * +elif PY3: from _dummy_thread import * - except ImportError: - from _thread import * else: __future_module__ = True from dummy_thread import * diff --git a/contrib/python/future/py3/future/moves/multiprocessing.py b/contrib/python/future/py3/future/moves/multiprocessing.py new file mode 100644 index 00000000000..a871b676f46 --- /dev/null +++ b/contrib/python/future/py3/future/moves/multiprocessing.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import +from future.utils import PY3 + +from multiprocessing import * +if not PY3: + __future_module__ = True + from multiprocessing.queues import SimpleQueue diff --git a/contrib/python/future/py3/future/standard_library/__init__.py b/contrib/python/future/py3/future/standard_library/__init__.py index cf870ad0ced..d467aaf492c 100644 --- a/contrib/python/future/py3/future/standard_library/__init__.py +++ b/contrib/python/future/py3/future/standard_library/__init__.py @@ -17,7 +17,7 @@ And then these normal Py3 imports work on both Py3 and Py2:: import socketserver import winreg # on Windows only import test.support - import html, html.parser, html.entites + import html, html.parser, html.entities import http, http.client, http.server import http.cookies, http.cookiejar import urllib.parse, urllib.request, urllib.response, urllib.error, urllib.robotparser @@ -33,6 +33,7 @@ And then these normal Py3 imports work on both Py3 and Py2:: from collections import OrderedDict, Counter, ChainMap # even on Py2.6 from subprocess import getoutput, getstatusoutput from subprocess import check_output # even on Py2.6 + from multiprocessing import SimpleQueue (The renamed modules and functions are still available under their old names on Python 2.) @@ -62,9 +63,12 @@ from __future__ import absolute_import, division, print_function import sys import logging -import importlib +# imp was deprecated in python 3.6 +if sys.version_info >= (3, 6): + import importlib as imp +else: + import imp import contextlib -import types import copy import os @@ -108,6 +112,7 @@ RENAMES = { 'future.moves.socketserver': 'socketserver', 'ConfigParser': 'configparser', 'repr': 'reprlib', + 'multiprocessing.queues': 'multiprocessing', # 'FileDialog': 'tkinter.filedialog', # 'tkFileDialog': 'tkinter.filedialog', # 'SimpleDialog': 'tkinter.simpledialog', @@ -184,6 +189,7 @@ MOVES = [('collections', 'UserList', 'UserList', 'UserList'), ('itertools', 'filterfalse','itertools', 'ifilterfalse'), ('itertools', 'zip_longest','itertools', 'izip_longest'), ('sys', 'intern','__builtin__', 'intern'), + ('multiprocessing', 'SimpleQueue', 'multiprocessing.queues', 'SimpleQueue'), # The re module has no ASCII flag in Py2, but this is the default. # Set re.ASCII to a zero constant. stat.ST_MODE just happens to be one # (and it exists on Py2.6+). @@ -297,7 +303,8 @@ class RenameImport(object): flog.debug('What to do here?') name = bits[0] - return importlib.import_module(name, path) + module_info = imp.find_module(name, path) + return imp.load_module(name, *module_info) class hooks(object): diff --git a/contrib/python/future/py3/future/types/newint.py b/contrib/python/future/py3/future/types/newint.py index 04a411e9331..ebc5715e2b6 100644 --- a/contrib/python/future/py3/future/types/newint.py +++ b/contrib/python/future/py3/future/types/newint.py @@ -223,9 +223,11 @@ class newint(with_metaclass(BaseNewInt, long)): def __rpow__(self, other): value = super(newint, self).__rpow__(other) - if value is NotImplemented: + if isint(value): + return newint(value) + elif value is NotImplemented: return other ** long(self) - return newint(value) + return value def __lshift__(self, other): if not isint(other): @@ -318,7 +320,7 @@ class newint(with_metaclass(BaseNewInt, long)): bits = length * 8 num = (2**bits) + self if num <= 0: - raise OverflowError("int too smal to convert") + raise OverflowError("int too small to convert") else: if self < 0: raise OverflowError("can't convert negative int to unsigned") diff --git a/contrib/python/future/py3/future/types/newrange.py b/contrib/python/future/py3/future/types/newrange.py index 6d4ebe2f8f6..dc5eb80222b 100644 --- a/contrib/python/future/py3/future/types/newrange.py +++ b/contrib/python/future/py3/future/types/newrange.py @@ -105,7 +105,7 @@ class newrange(Sequence): raise ValueError('%r is not in range' % value) def count(self, value): - """Return the number of ocurrences of integer `value` + """Return the number of occurrences of integer `value` in the sequence this range represents.""" # a value can occur exactly zero or one times return int(value in self) diff --git a/contrib/python/future/py3/past/__init__.py b/contrib/python/future/py3/past/__init__.py index 14713039332..54619e0a608 100644 --- a/contrib/python/future/py3/past/__init__.py +++ b/contrib/python/future/py3/past/__init__.py @@ -75,12 +75,12 @@ Credits ------- :Author: Ed Schofield, Jordan M. Adler, et al -:Sponsor: Python Charmers Pty Ltd, Australia: http://pythoncharmers.com +:Sponsor: Python Charmers: https://pythoncharmers.com Licensing --------- -Copyright 2013-2019 Python Charmers Pty Ltd, Australia. +Copyright 2013-2024 Python Charmers, Australia. The software is distributed under an MIT licence. See LICENSE.txt. """ diff --git a/contrib/python/future/py3/past/builtins/misc.py b/contrib/python/future/py3/past/builtins/misc.py index 3600695c0aa..0b8e6a986c7 100644 --- a/contrib/python/future/py3/past/builtins/misc.py +++ b/contrib/python/future/py3/past/builtins/misc.py @@ -1,11 +1,13 @@ from __future__ import unicode_literals import inspect +import sys import math import numbers from future.utils import PY2, PY3, exec_ + if PY2: from collections import Mapping else: @@ -103,13 +105,12 @@ if PY3: return '0' + builtins.oct(number)[2:] raw_input = input - - try: + # imp was deprecated in python 3.6 + if sys.version_info >= (3, 6): from importlib import reload - except ImportError: + else: # for python2, python3 <= 3.4 from imp import reload - unicode = str unichr = chr xrange = range diff --git a/contrib/python/future/py3/ya.make b/contrib/python/future/py3/ya.make index de25d7e8d10..a219deb6051 100644 --- a/contrib/python/future/py3/ya.make +++ b/contrib/python/future/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(0.18.3) +VERSION(1.0.0) LICENSE(MIT) @@ -100,6 +100,7 @@ PY_SRCS( future/moves/http/cookies.py future/moves/http/server.py future/moves/itertools.py + future/moves/multiprocessing.py future/moves/pickle.py future/moves/queue.py future/moves/reprlib.py diff --git a/contrib/python/hypothesis/py3/.dist-info/METADATA b/contrib/python/hypothesis/py3/.dist-info/METADATA index 171a09eebbc..717ae021d6c 100644 --- a/contrib/python/hypothesis/py3/.dist-info/METADATA +++ b/contrib/python/hypothesis/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: hypothesis -Version: 6.98.10 +Version: 6.98.12 Summary: A library for property-based testing Home-page: https://hypothesis.works Author: David R. MacIver and Zac Hatfield-Dodds diff --git a/contrib/python/hypothesis/py3/hypothesis/extra/ghostwriter.py b/contrib/python/hypothesis/py3/hypothesis/extra/ghostwriter.py index 8917d5bd870..2854b48c299 100644 --- a/contrib/python/hypothesis/py3/hypothesis/extra/ghostwriter.py +++ b/contrib/python/hypothesis/py3/hypothesis/extra/ghostwriter.py @@ -122,7 +122,7 @@ from hypothesis.strategies._internal.flatmapped import FlatMapStrategy from hypothesis.strategies._internal.lazy import LazyStrategy, unwrap_strategies from hypothesis.strategies._internal.strategies import ( FilteredStrategy, - MappedSearchStrategy, + MappedStrategy, OneOfStrategy, SampledFromStrategy, ) @@ -627,7 +627,7 @@ def _imports_for_strategy(strategy): strategy = unwrap_strategies(strategy) # Get imports for s.map(f), s.filter(f), s.flatmap(f), including both s and f - if isinstance(strategy, MappedSearchStrategy): + if isinstance(strategy, MappedStrategy): imports |= _imports_for_strategy(strategy.mapped_strategy) imports |= _imports_for_object(strategy.pack) if isinstance(strategy, FilteredStrategy): diff --git a/contrib/python/hypothesis/py3/hypothesis/extra/numpy.py b/contrib/python/hypothesis/py3/hypothesis/extra/numpy.py index 29d73f76be4..4cfb1ca8d8e 100644 --- a/contrib/python/hypothesis/py3/hypothesis/extra/numpy.py +++ b/contrib/python/hypothesis/py3/hypothesis/extra/numpy.py @@ -50,7 +50,7 @@ from hypothesis.strategies._internal.lazy import unwrap_strategies from hypothesis.strategies._internal.numbers import Real from hypothesis.strategies._internal.strategies import ( Ex, - MappedSearchStrategy, + MappedStrategy, T, check_strategy, ) @@ -516,7 +516,7 @@ def arrays( # If there's a redundant cast to the requested dtype, remove it. This unlocks # optimizations such as fast unique sampled_from, and saves some time directly too. unwrapped = unwrap_strategies(elements) - if isinstance(unwrapped, MappedSearchStrategy) and unwrapped.pack == dtype.type: + if isinstance(unwrapped, MappedStrategy) and unwrapped.pack == dtype.type: elements = unwrapped.mapped_strategy if isinstance(shape, int): shape = (shape,) diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py index cdce1afacf8..b84db4df852 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/data.py @@ -62,11 +62,14 @@ from hypothesis.internal.floats import ( from hypothesis.internal.intervalsets import IntervalSet if TYPE_CHECKING: + from typing import TypeAlias + from typing_extensions import dataclass_transform from hypothesis.strategies import SearchStrategy from hypothesis.strategies._internal.strategies import Ex else: + TypeAlias = object def dataclass_transform(): def wrapper(tp): @@ -94,6 +97,41 @@ TargetObservations = Dict[Optional[str], Union[int, float]] T = TypeVar("T") +class IntegerKWargs(TypedDict): + min_value: Optional[int] + max_value: Optional[int] + weights: Optional[Sequence[float]] + shrink_towards: int + + +class FloatKWargs(TypedDict): + min_value: float + max_value: float + allow_nan: bool + smallest_nonzero_magnitude: float + + +class StringKWargs(TypedDict): + intervals: IntervalSet + min_size: int + max_size: Optional[int] + + +class BytesKWargs(TypedDict): + size: int + + +class BooleanKWargs(TypedDict): + p: float + + +IRType: TypeAlias = Union[int, str, bool, float, bytes] +IRKWargsType: TypeAlias = Union[ + IntegerKWargs, FloatKWargs, StringKWargs, BytesKWargs, BooleanKWargs +] +IRTypeName: TypeAlias = Literal["integer", "string", "boolean", "float", "bytes"] + + class ExtraInformation: """A class for holding shared state on a ``ConjectureData`` that should be added to the final ``ConjectureResult``.""" @@ -798,34 +836,6 @@ global_test_counter = 0 MAX_DEPTH = 100 -class IntegerKWargs(TypedDict): - min_value: Optional[int] - max_value: Optional[int] - weights: Optional[Sequence[float]] - shrink_towards: int - - -class FloatKWargs(TypedDict): - min_value: float - max_value: float - allow_nan: bool - smallest_nonzero_magnitude: float - - -class StringKWargs(TypedDict): - intervals: IntervalSet - min_size: int - max_size: Optional[int] - - -class BytesKWargs(TypedDict): - size: int - - -class BooleanKWargs(TypedDict): - p: float - - class DataObserver: """Observer class for recording the behaviour of a ConjectureData object, primarily used for tracking diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/datatree.py b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/datatree.py index a9a6e5b196d..c8e5d70aa7a 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/datatree.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/conjecture/datatree.py @@ -10,7 +10,7 @@ import itertools import math -from typing import TYPE_CHECKING, List, Literal, Optional, Union +from typing import List, Optional, Union import attr @@ -24,23 +24,14 @@ from hypothesis.internal.conjecture.data import ( DataObserver, FloatKWargs, IntegerKWargs, + IRKWargsType, + IRType, + IRTypeName, Status, StringKWargs, ) from hypothesis.internal.floats import count_between_floats, float_to_int, int_to_float -if TYPE_CHECKING: - from typing import TypeAlias -else: - TypeAlias = object - -IRType: TypeAlias = Union[int, str, bool, float, bytes] -IRKWargsType: TypeAlias = Union[ - IntegerKWargs, FloatKWargs, StringKWargs, BytesKWargs, BooleanKWargs -] -# this would be "IRTypeType", but that's just confusing. -IRLiteralType: TypeAlias = Literal["integer", "string", "boolean", "float", "bytes"] - class PreviouslyUnseenBehaviour(HypothesisException): pass @@ -336,7 +327,7 @@ class TreeNode: # have the same length. The values at index i belong to node i. kwargs: List[IRKWargsType] = attr.ib(factory=list) values: List[IRType] = attr.ib(factory=list) - ir_types: List[IRLiteralType] = attr.ib(factory=list) + ir_types: List[IRTypeName] = attr.ib(factory=list) # The indices of nodes which had forced values. # @@ -885,7 +876,7 @@ class TreeRecordingObserver(DataObserver): def draw_value( self, - ir_type: IRLiteralType, + ir_type: IRTypeName, value: IRType, *, was_forced: bool, diff --git a/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py b/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py index 4ba92b1da85..f352e9cb6d0 100644 --- a/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py +++ b/contrib/python/hypothesis/py3/hypothesis/internal/filtering.py @@ -33,7 +33,10 @@ from typing import Any, Callable, Collection, Dict, NamedTuple, Optional, TypeVa from hypothesis.internal.compat import ceil, floor from hypothesis.internal.floats import next_down, next_up -from hypothesis.internal.reflection import extract_lambda_source +from hypothesis.internal.reflection import ( + extract_lambda_source, + get_pretty_function_description, +) Ex = TypeVar("Ex") Predicate = Callable[[Ex], bool] @@ -64,6 +67,10 @@ class ConstructivePredicate(NamedTuple): def unchanged(cls, predicate: Predicate) -> "ConstructivePredicate": return cls({}, predicate) + def __repr__(self) -> str: + fn = get_pretty_function_description(self.predicate) + return f"{self.__class__.__name__}(kwargs={self.kwargs!r}, predicate={fn})" + ARG = object() @@ -147,8 +154,8 @@ def merge_preds(*con_predicates: ConstructivePredicate) -> ConstructivePredicate elif kw["max_value"] == base["max_value"]: base["exclude_max"] |= kw.get("exclude_max", False) - has_len = {"len" in kw for kw, _ in con_predicates} - assert len(has_len) == 1, "can't mix numeric with length constraints" + has_len = {"len" in kw for kw, _ in con_predicates if kw} + assert len(has_len) <= 1, "can't mix numeric with length constraints" if has_len == {True}: base["len"] = True diff --git a/contrib/python/hypothesis/py3/hypothesis/stateful.py b/contrib/python/hypothesis/py3/hypothesis/stateful.py index 2ab7ef13d52..60cd92721c2 100644 --- a/contrib/python/hypothesis/py3/hypothesis/stateful.py +++ b/contrib/python/hypothesis/py3/hypothesis/stateful.py @@ -358,7 +358,6 @@ class RuleBasedStateMachine(metaclass=StateMachineMeta): return cls._invariants_per_class[cls] def _repr_step(self, rule, data, result): - self.step_count = getattr(self, "step_count", 0) + 1 output_assignment = "" if rule.targets: if isinstance(result, MultipleResults): @@ -431,7 +430,7 @@ class RuleBasedStateMachine(metaclass=StateMachineMeta): return StateMachineTestCase [email protected](repr=False) class Rule: targets = attr.ib() function = attr.ib(repr=get_pretty_function_description) @@ -451,6 +450,11 @@ class Rule: self.arguments_strategies[k] = v self.bundles = tuple(bundles) + def __repr__(self) -> str: + rep = get_pretty_function_description + bits = [f"{k}={rep(v)}" for k, v in attr.asdict(self).items() if v] + return f"{self.__class__.__name__}({', '.join(bits)})" + self_strategy = st.runner() @@ -937,7 +941,8 @@ class RuleStrategy(SearchStrategy): self.rules = list(machine.rules()) self.enabled_rules_strategy = st.shared( - FeatureStrategy(), key=("enabled rules", machine) + FeatureStrategy(at_least_one_of={r.function.__name__ for r in self.rules}), + key=("enabled rules", machine), ) # The order is a bit arbitrary. Primarily we're trying to group rules @@ -965,17 +970,16 @@ class RuleStrategy(SearchStrategy): feature_flags = data.draw(self.enabled_rules_strategy) - # Note: The order of the filters here is actually quite important, - # because checking is_enabled makes choices, so increases the size of - # the choice sequence. This means that if we are in a case where many - # rules are invalid we will make a lot more choices if we ask if they - # are enabled before we ask if they are valid, so our test cases will - # be artificially large. - rule = data.draw( - st.sampled_from(self.rules) - .filter(self.is_valid) - .filter(lambda r: feature_flags.is_enabled(r.function.__name__)) - ) + def rule_is_enabled(r): + # Note: The order of the filters here is actually quite important, + # because checking is_enabled makes choices, so increases the size of + # the choice sequence. This means that if we are in a case where many + # rules are invalid we would make a lot more choices if we ask if they + # are enabled before we ask if they are valid, so our test cases would + # be artificially large. + return self.is_valid(r) and feature_flags.is_enabled(r.function.__name__) + + rule = data.draw(st.sampled_from(self.rules).filter(rule_is_enabled)) arguments = {} for k, strat in rule.arguments_strategies.items(): diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py index 1f86f37a42e..75de4a82ecb 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/collections.py @@ -13,6 +13,7 @@ from typing import Any, Iterable, Tuple, overload from hypothesis.errors import InvalidArgument from hypothesis.internal.conjecture import utils as cu +from hypothesis.internal.conjecture.engine import BUFFER_SIZE from hypothesis.internal.conjecture.junkdrawer import LazySequenceCopy from hypothesis.internal.conjecture.utils import combine_labels from hypothesis.internal.filtering import get_integer_predicate_bounds @@ -22,7 +23,7 @@ from hypothesis.strategies._internal.strategies import ( T4, T5, Ex, - MappedSearchStrategy, + MappedStrategy, SearchStrategy, T, check_strategy, @@ -142,6 +143,10 @@ class ListStrategy(SearchStrategy): self.min_size = min_size or 0 self.max_size = max_size if max_size is not None else float("inf") assert 0 <= self.min_size <= self.max_size + if min_size > BUFFER_SIZE: + raise InvalidArgument( + f"min_size={min_size:_d} is larger than Hypothesis is designed to handle" + ) self.average_size = min( max(self.min_size * 2, self.min_size + 5), 0.5 * (self.min_size + self.max_size), @@ -206,6 +211,9 @@ class ListStrategy(SearchStrategy): new = copy.copy(self) new.min_size = max(self.min_size, kwargs.get("min_value", self.min_size)) new.max_size = min(self.max_size, kwargs.get("max_value", self.max_size)) + # Unsatisfiable filters are easiest to understand without rewriting. + if new.min_size > new.max_size: + return SearchStrategy.filter(self, condition) # Recompute average size; this is cheaper than making it into a property. new.average_size = min( max(new.min_size * 2, new.min_size + 5), @@ -297,7 +305,7 @@ class UniqueSampledListStrategy(UniqueListStrategy): return result -class FixedKeysDictStrategy(MappedSearchStrategy): +class FixedKeysDictStrategy(MappedStrategy): """A strategy which produces dicts with a fixed set of keys, given a strategy for each of their equivalent values. @@ -306,9 +314,12 @@ class FixedKeysDictStrategy(MappedSearchStrategy): """ def __init__(self, strategy_dict): - self.dict_type = type(strategy_dict) + dict_type = type(strategy_dict) self.keys = tuple(strategy_dict.keys()) - super().__init__(strategy=TupleStrategy(strategy_dict[k] for k in self.keys)) + super().__init__( + strategy=TupleStrategy(strategy_dict[k] for k in self.keys), + pack=lambda value: dict_type(zip(self.keys, value)), + ) def calc_is_empty(self, recur): return recur(self.mapped_strategy) @@ -316,9 +327,6 @@ class FixedKeysDictStrategy(MappedSearchStrategy): def __repr__(self): return f"FixedKeysDictStrategy({self.keys!r}, {self.mapped_strategy!r})" - def pack(self, value): - return self.dict_type(zip(self.keys, value)) - class FixedAndOptionalKeysDictStrategy(SearchStrategy): """A strategy which produces dicts with a fixed set of keys, given a diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/featureflags.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/featureflags.py index cf72b5c10bf..98af8f087a3 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/featureflags.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/featureflags.py @@ -31,7 +31,7 @@ class FeatureFlags: required disabled features. """ - def __init__(self, data=None, enabled=(), disabled=()): + def __init__(self, data=None, enabled=(), disabled=(), at_least_one_of=()): self.__data = data self.__is_disabled = {} @@ -52,13 +52,18 @@ class FeatureFlags: # features will be enabled. This is so that we shrink in the direction # of more features being enabled. if self.__data is not None: - self.__p_disabled = data.draw_integer(0, 255) / 255.0 + self.__p_disabled = data.draw_integer(0, 254) / 255 else: # If data is None we're in example mode so all that matters is the # enabled/disabled lists above. We set this up so that everything # else is enabled by default. self.__p_disabled = 0.0 + # The naive approach can lead to disabling e.g. every single rule on a + # RuleBasedStateMachine, which aborts the test as unable to make progress. + # Track the set of possible names, and ensure that at least one is enabled. + self.__at_least_one_of = set(at_least_one_of) + def is_enabled(self, name): """Tests whether the feature named ``name`` should be enabled on this test run.""" @@ -81,10 +86,19 @@ class FeatureFlags: # of the test case where we originally decided, the next point at # which we make this decision just makes the decision it previously # made. + oneof = self.__at_least_one_of is_disabled = self.__data.draw_boolean( - self.__p_disabled, forced=self.__is_disabled.get(name) + self.__p_disabled, + forced=( + False + if len(oneof) == 1 and name in oneof + else self.__is_disabled.get(name) + ), ) self.__is_disabled[name] = is_disabled + if name in oneof and not is_disabled: + oneof.clear() + oneof.discard(name) data.stop_example() return not is_disabled @@ -100,5 +114,9 @@ class FeatureFlags: class FeatureStrategy(SearchStrategy): + def __init__(self, at_least_one_of=()): + super().__init__() + self._at_least_one_of = frozenset(at_least_one_of) + def do_draw(self, data): - return FeatureFlags(data) + return FeatureFlags(data, at_least_one_of=self._at_least_one_of) diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/lazy.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/lazy.py index d6bb13c7c13..8f887293e62 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/lazy.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/lazy.py @@ -61,10 +61,6 @@ def unwrap_strategies(s): assert unwrap_depth >= 0 -def _repr_filter(condition): - return f".filter({get_pretty_function_description(condition)})" - - class LazyStrategy(SearchStrategy): """A strategy which is defined purely by conversion to and from another strategy. @@ -72,14 +68,14 @@ class LazyStrategy(SearchStrategy): Its parameter and distribution come from that other strategy. """ - def __init__(self, function, args, kwargs, filters=(), *, force_repr=None): + def __init__(self, function, args, kwargs, *, transforms=(), force_repr=None): super().__init__() self.__wrapped_strategy = None self.__representation = force_repr self.function = function self.__args = args self.__kwargs = kwargs - self.__filters = filters + self._transformations = transforms @property def supports_find(self): @@ -115,23 +111,28 @@ class LazyStrategy(SearchStrategy): self.__wrapped_strategy = self.function( *unwrapped_args, **unwrapped_kwargs ) - for f in self.__filters: - self.__wrapped_strategy = self.__wrapped_strategy.filter(f) + for method, fn in self._transformations: + self.__wrapped_strategy = getattr(self.__wrapped_strategy, method)(fn) return self.__wrapped_strategy - def filter(self, condition): - try: - repr_ = f"{self!r}{_repr_filter(condition)}" - except Exception: - repr_ = None - return LazyStrategy( + def __with_transform(self, method, fn): + repr_ = self.__representation + if repr_: + repr_ = f"{repr_}.{method}({get_pretty_function_description(fn)})" + return type(self)( self.function, self.__args, self.__kwargs, - (*self.__filters, condition), + transforms=(*self._transformations, (method, fn)), force_repr=repr_, ) + def map(self, pack): + return self.__with_transform("map", pack) + + def filter(self, condition): + return self.__with_transform("filter", condition) + def do_validate(self): w = self.wrapped_strategy assert isinstance(w, SearchStrategy), f"{self!r} returned non-strategy {w!r}" @@ -156,7 +157,10 @@ class LazyStrategy(SearchStrategy): } self.__representation = repr_call( self.function, _args, kwargs_for_repr, reorder=False - ) + "".join(map(_repr_filter, self.__filters)) + ) + "".join( + f".{method}({get_pretty_function_description(fn)})" + for method, fn in self._transformations + ) return self.__representation def do_draw(self, data): diff --git a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py index af2fa729370..46d4005cdbe 100644 --- a/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py +++ b/contrib/python/hypothesis/py3/hypothesis/strategies/_internal/strategies.py @@ -11,6 +11,7 @@ import sys import warnings from collections import abc, defaultdict +from functools import lru_cache from random import shuffle from typing import ( Any, @@ -60,7 +61,7 @@ T5 = TypeVar("T5") calculating = UniqueIdentifier("calculating") MAPPED_SEARCH_STRATEGY_DO_DRAW_LABEL = calc_label_from_name( - "another attempted draw in MappedSearchStrategy" + "another attempted draw in MappedStrategy" ) FILTERED_SEARCH_STRATEGY_DO_DRAW_LABEL = calc_label_from_name( @@ -346,7 +347,7 @@ class SearchStrategy(Generic[Ex]): """ if is_identity_function(pack): return self # type: ignore # Mypy has no way to know that `Ex == T` - return MappedSearchStrategy(pack=pack, strategy=self) + return MappedStrategy(self, pack=pack) def flatmap( self, expand: Callable[[Ex], "SearchStrategy[T]"] @@ -468,9 +469,6 @@ class SampledFromStrategy(SearchStrategy): """A strategy which samples from a set of elements. This is essentially equivalent to using a OneOfStrategy over Just strategies but may be more efficient and convenient. - - The conditional distribution chooses uniformly at random from some - non-empty subset of the elements. """ _MAX_FILTER_CALLS = 10_000 @@ -521,7 +519,10 @@ class SampledFromStrategy(SearchStrategy): # Used in UniqueSampledListStrategy for name, f in self._transformations: if name == "map": - element = f(element) + result = f(element) + if build_context := _current_build_context.value: + build_context.record_call(result, f, [element], {}) + element = result else: assert name == "filter" if not f(element): @@ -794,18 +795,17 @@ def one_of( return OneOfStrategy(args) -class MappedSearchStrategy(SearchStrategy[Ex]): +class MappedStrategy(SearchStrategy[Ex]): """A strategy which is defined purely by conversion to and from another strategy. Its parameter and distribution come from that other strategy. """ - def __init__(self, strategy, pack=None): + def __init__(self, strategy, pack): super().__init__() self.mapped_strategy = strategy - if pack is not None: - self.pack = pack + self.pack = pack def calc_is_empty(self, recur): return recur(self.mapped_strategy) @@ -821,11 +821,6 @@ class MappedSearchStrategy(SearchStrategy[Ex]): def do_validate(self): self.mapped_strategy.validate() - def pack(self, x): - """Take a value produced by the underlying mapped_strategy and turn it - into a value suitable for outputting from this strategy.""" - raise NotImplementedError(f"{self.__class__.__name__}.pack()") - def do_draw(self, data: ConjectureData) -> Any: with warnings.catch_warnings(): if isinstance(self.pack, type) and issubclass( @@ -847,10 +842,67 @@ class MappedSearchStrategy(SearchStrategy[Ex]): @property def branches(self) -> List[SearchStrategy[Ex]]: return [ - MappedSearchStrategy(pack=self.pack, strategy=strategy) + MappedStrategy(strategy, pack=self.pack) for strategy in self.mapped_strategy.branches ] + def filter(self, condition: Callable[[Ex], Any]) -> "SearchStrategy[Ex]": + # Includes a special case so that we can rewrite filters on collection + # lengths, when most collections are `st.lists(...).map(the_type)`. + ListStrategy = _list_strategy_type() + if not isinstance(self.mapped_strategy, ListStrategy) or not ( + (isinstance(self.pack, type) and issubclass(self.pack, abc.Collection)) + or self.pack in _collection_ish_functions() + ): + return super().filter(condition) + + # Check whether our inner list strategy can rewrite this filter condition. + # If not, discard the result and _only_ apply a new outer filter. + new = ListStrategy.filter(self.mapped_strategy, condition) + if getattr(new, "filtered_strategy", None) is self.mapped_strategy: + return super().filter(condition) # didn't rewrite + + # Apply a new outer filter even though we rewrote the inner strategy, + # because some collections can change the list length (dict, set, etc). + return FilteredStrategy(type(self)(new, self.pack), conditions=(condition,)) + + +@lru_cache +def _list_strategy_type(): + from hypothesis.strategies._internal.collections import ListStrategy + + return ListStrategy + + +def _collection_ish_functions(): + funcs = [sorted] + if np := sys.modules.get("numpy"): + # c.f. https://numpy.org/doc/stable/reference/routines.array-creation.html + # Probably only `np.array` and `np.asarray` will be used in practice, + # but why should that stop us when we've already gone this far? + funcs += [ + np.empty_like, + np.eye, + np.identity, + np.ones_like, + np.zeros_like, + np.array, + np.asarray, + np.asanyarray, + np.ascontiguousarray, + np.asmatrix, + np.copy, + np.rec.array, + np.rec.fromarrays, + np.rec.fromrecords, + np.diag, + # bonus undocumented functions from tab-completion: + np.asarray_chkfinite, + np.asfarray, + np.asfortranarray, + ] + return funcs + filter_not_satisfied = UniqueIdentifier("filter not satisfied") diff --git a/contrib/python/hypothesis/py3/hypothesis/version.py b/contrib/python/hypothesis/py3/hypothesis/version.py index ce617c47e9f..e9862410372 100644 --- a/contrib/python/hypothesis/py3/hypothesis/version.py +++ b/contrib/python/hypothesis/py3/hypothesis/version.py @@ -8,5 +8,5 @@ # v. 2.0. If a copy of the MPL was not distributed with this file, You can # obtain one at https://mozilla.org/MPL/2.0/. -__version_info__ = (6, 98, 10) +__version_info__ = (6, 98, 12) __version__ = ".".join(map(str, __version_info__)) diff --git a/contrib/python/hypothesis/py3/ya.make b/contrib/python/hypothesis/py3/ya.make index 4c7de0c00e3..33c8057a991 100644 --- a/contrib/python/hypothesis/py3/ya.make +++ b/contrib/python/hypothesis/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(6.98.10) +VERSION(6.98.12) LICENSE(MPL-2.0) diff --git a/contrib/python/ipython/py3/.dist-info/METADATA b/contrib/python/ipython/py3/.dist-info/METADATA index 5efeded1e1d..11836decd6e 100644 --- a/contrib/python/ipython/py3/.dist-info/METADATA +++ b/contrib/python/ipython/py3/.dist-info/METADATA @@ -1,11 +1,11 @@ Metadata-Version: 2.1 Name: ipython -Version: 8.21.0 +Version: 8.22.2 Summary: IPython: Productive Interactive Computing -Home-page: https://ipython.org Author: The IPython Development Team Author-email: [email protected] License: BSD-3-Clause +Project-URL: Homepage, https://ipython.org Project-URL: Documentation, https://ipython.readthedocs.io/ Project-URL: Funding, https://numfocus.org/ Project-URL: Source, https://github.com/ipython/ipython @@ -32,37 +32,14 @@ Requires-Dist: matplotlib-inline Requires-Dist: prompt-toolkit <3.1.0,>=3.0.41 Requires-Dist: pygments >=2.4.0 Requires-Dist: stack-data -Requires-Dist: traitlets >=5 +Requires-Dist: traitlets >=5.13.0 Requires-Dist: typing-extensions ; python_version < "3.10" Requires-Dist: exceptiongroup ; python_version < "3.11" -Requires-Dist: pexpect >4.3 ; sys_platform != "win32" +Requires-Dist: pexpect >4.3 ; sys_platform != "win32" and sys_platform != "emscripten" Requires-Dist: colorama ; sys_platform == "win32" Provides-Extra: all -Requires-Dist: black ; extra == 'all' -Requires-Dist: ipykernel ; extra == 'all' -Requires-Dist: setuptools >=18.5 ; extra == 'all' -Requires-Dist: sphinx >=1.3 ; extra == 'all' -Requires-Dist: sphinx-rtd-theme ; extra == 'all' -Requires-Dist: docrepr ; extra == 'all' -Requires-Dist: matplotlib ; extra == 'all' -Requires-Dist: stack-data ; extra == 'all' -Requires-Dist: typing-extensions ; extra == 'all' -Requires-Dist: exceptiongroup ; extra == 'all' -Requires-Dist: pytest <8 ; extra == 'all' -Requires-Dist: pytest-asyncio <0.22 ; extra == 'all' -Requires-Dist: testpath ; extra == 'all' -Requires-Dist: pickleshare ; extra == 'all' -Requires-Dist: nbconvert ; extra == 'all' -Requires-Dist: nbformat ; extra == 'all' -Requires-Dist: ipywidgets ; extra == 'all' -Requires-Dist: notebook ; extra == 'all' -Requires-Dist: ipyparallel ; extra == 'all' -Requires-Dist: qtconsole ; extra == 'all' -Requires-Dist: curio ; extra == 'all' -Requires-Dist: matplotlib !=3.2.0 ; extra == 'all' -Requires-Dist: numpy >=1.23 ; extra == 'all' -Requires-Dist: pandas ; extra == 'all' -Requires-Dist: trio ; extra == 'all' +Requires-Dist: ipython[black,doc,kernel,nbconvert,nbformat,notebook,parallel,qtconsole,terminal] ; extra == 'all' +Requires-Dist: ipython[test,test_extra] ; extra == 'all' Provides-Extra: black Requires-Dist: black ; extra == 'black' Provides-Extra: doc @@ -70,15 +47,13 @@ Requires-Dist: ipykernel ; extra == 'doc' Requires-Dist: setuptools >=18.5 ; extra == 'doc' Requires-Dist: sphinx >=1.3 ; extra == 'doc' Requires-Dist: sphinx-rtd-theme ; extra == 'doc' +Requires-Dist: sphinxcontrib-jquery ; extra == 'doc' Requires-Dist: docrepr ; extra == 'doc' Requires-Dist: matplotlib ; extra == 'doc' Requires-Dist: stack-data ; extra == 'doc' Requires-Dist: typing-extensions ; extra == 'doc' Requires-Dist: exceptiongroup ; extra == 'doc' -Requires-Dist: pytest <8 ; extra == 'doc' -Requires-Dist: pytest-asyncio <0.22 ; extra == 'doc' -Requires-Dist: testpath ; extra == 'doc' -Requires-Dist: pickleshare ; extra == 'doc' +Requires-Dist: ipython[test] ; extra == 'doc' Provides-Extra: kernel Requires-Dist: ipykernel ; extra == 'kernel' Provides-Extra: nbconvert @@ -99,10 +74,7 @@ Requires-Dist: pytest-asyncio <0.22 ; extra == 'test' Requires-Dist: testpath ; extra == 'test' Requires-Dist: pickleshare ; extra == 'test' Provides-Extra: test_extra -Requires-Dist: pytest <8 ; extra == 'test_extra' -Requires-Dist: pytest-asyncio <0.22 ; extra == 'test_extra' -Requires-Dist: testpath ; extra == 'test_extra' -Requires-Dist: pickleshare ; extra == 'test_extra' +Requires-Dist: ipython[test] ; extra == 'test_extra' Requires-Dist: curio ; extra == 'test_extra' Requires-Dist: matplotlib !=3.2.0 ; extra == 'test_extra' Requires-Dist: nbformat ; extra == 'test_extra' diff --git a/contrib/python/ipython/py3/IPython/core/alias.py b/contrib/python/ipython/py3/IPython/core/alias.py index 52843b3d774..845e6b7d319 100644 --- a/contrib/python/ipython/py3/IPython/core/alias.py +++ b/contrib/python/ipython/py3/IPython/core/alias.py @@ -30,6 +30,9 @@ from .error import UsageError from traitlets import List, Instance from logging import error +import typing as t + + #----------------------------------------------------------------------------- # Utilities #----------------------------------------------------------------------------- @@ -37,7 +40,7 @@ from logging import error # This is used as the pattern for calls to split_user_input. shell_line_split = re.compile(r'^(\s*)()(\S+)(.*$)') -def default_aliases(): +def default_aliases() -> t.List[t.Tuple[str, str]]: """Return list of shell aliases to auto-define. """ # Note: the aliases defined here should be safe to use on a kernel diff --git a/contrib/python/ipython/py3/IPython/core/completer.py b/contrib/python/ipython/py3/IPython/core/completer.py index 8e2bb7f8103..09a033a2278 100644 --- a/contrib/python/ipython/py3/IPython/core/completer.py +++ b/contrib/python/ipython/py3/IPython/core/completer.py @@ -2551,7 +2551,7 @@ class IPCompleter(Completer): EvaluationContext( globals=self.global_namespace, locals=self.namespace, - evaluation=self.evaluation, + evaluation=self.evaluation, # type: ignore in_subscript=True, ), ) diff --git a/contrib/python/ipython/py3/IPython/core/completerlib.py b/contrib/python/ipython/py3/IPython/core/completerlib.py index a970ba69680..de6c4249b01 100644 --- a/contrib/python/ipython/py3/IPython/core/completerlib.py +++ b/contrib/python/ipython/py3/IPython/core/completerlib.py @@ -67,6 +67,7 @@ magic_run_re = re.compile(r'.*(\.ipy|\.ipynb|\.py[w]?)$') # Local utilities #----------------------------------------------------------------------------- + arcadia_rootmodules_cache = None arcadia_modules_cache = None @@ -111,7 +112,7 @@ def arcadia_get_root_modules(): return arcadia_rootmodules_cache -def module_list(path): +def module_list(path: str) -> List[str]: """ Return the list containing the names of the modules available in the given folder. @@ -127,7 +128,7 @@ def module_list(path): # Build a list of all files in the directory and all files # in its subdirectories. For performance reasons, do not # recurse more than one level into subdirectories. - files = [] + files: List[str] = [] for root, dirs, nondirs in os.walk(path, followlinks=True): subdir = root[len(path)+1:] if subdir: @@ -138,8 +139,8 @@ def module_list(path): else: try: - files = list(zipimporter(path)._files.keys()) - except: + files = list(zipimporter(path)._files.keys()) # type: ignore + except Exception: files = [] # Build a list of modules which match the import_re regex. @@ -242,6 +243,9 @@ def try_import(mod: str, only_modules=False) -> List[str]: if m_is_init: file_ = m.__file__ + file_path = os.path.dirname(file_) # type: ignore + if file_path is not None: + completions.extend(module_list(file_path)) completions.extend(arcadia_module_list(mod)) completions_set = {c for c in completions if isinstance(c, str)} completions_set.discard('__init__') diff --git a/contrib/python/ipython/py3/IPython/core/displaypub.py b/contrib/python/ipython/py3/IPython/core/displaypub.py index 74028ec79e0..ed6a7082e75 100644 --- a/contrib/python/ipython/py3/IPython/core/displaypub.py +++ b/contrib/python/ipython/py3/IPython/core/displaypub.py @@ -24,7 +24,9 @@ from traitlets import List # This used to be defined here - it is imported for backwards compatibility from .display_functions import publish_display_data -#----------------------------------------------------------------------------- +import typing as t + +# ----------------------------------------------------------------------------- # Main payload class #----------------------------------------------------------------------------- @@ -103,9 +105,9 @@ class DisplayPublisher(Configurable): rather than creating a new output. """ - handlers = {} + handlers: t.Dict = {} if self.shell is not None: - handlers = getattr(self.shell, 'mime_renderers', {}) + handlers = getattr(self.shell, "mime_renderers", {}) for mime, handler in handlers.items(): if mime in data: @@ -125,11 +127,20 @@ class DisplayPublisher(Configurable): class CapturingDisplayPublisher(DisplayPublisher): """A DisplayPublisher that stores""" - outputs = List() - def publish(self, data, metadata=None, source=None, *, transient=None, update=False): - self.outputs.append({'data':data, 'metadata':metadata, - 'transient':transient, 'update':update}) + outputs: List = List() + + def publish( + self, data, metadata=None, source=None, *, transient=None, update=False + ): + self.outputs.append( + { + "data": data, + "metadata": metadata, + "transient": transient, + "update": update, + } + ) def clear_output(self, wait=False): super(CapturingDisplayPublisher, self).clear_output(wait) diff --git a/contrib/python/ipython/py3/IPython/core/formatters.py b/contrib/python/ipython/py3/IPython/core/formatters.py index 15cf703c2a0..9e59e23de12 100644 --- a/contrib/python/ipython/py3/IPython/core/formatters.py +++ b/contrib/python/ipython/py3/IPython/core/formatters.py @@ -53,20 +53,23 @@ class DisplayFormatter(Configurable): else: formatter.enabled = False - ipython_display_formatter = ForwardDeclaredInstance('FormatterABC') - @default('ipython_display_formatter') + ipython_display_formatter = ForwardDeclaredInstance("FormatterABC") # type: ignore + + @default("ipython_display_formatter") def _default_formatter(self): return IPythonDisplayFormatter(parent=self) - mimebundle_formatter = ForwardDeclaredInstance('FormatterABC') - @default('mimebundle_formatter') + mimebundle_formatter = ForwardDeclaredInstance("FormatterABC") # type: ignore + + @default("mimebundle_formatter") def _default_mime_formatter(self): return MimeBundleFormatter(parent=self) # A dict of formatter whose keys are format types (MIME types) and whose # values are subclasses of BaseFormatter. formatters = Dict() - @default('formatters') + + @default("formatters") def _formatters_default(self): """Activate the default formatters.""" formatter_classes = [ diff --git a/contrib/python/ipython/py3/IPython/core/history.py b/contrib/python/ipython/py3/IPython/core/history.py index fb67d158ef9..f59ca119168 100644 --- a/contrib/python/ipython/py3/IPython/core/history.py +++ b/contrib/python/ipython/py3/IPython/core/history.py @@ -6,15 +6,12 @@ import atexit import datetime -from pathlib import Path import re import sqlite3 import threading +from pathlib import Path -from traitlets.config.configurable import LoggingConfigurable from decorator import decorator -from IPython.utils.decorators import undoc -from IPython.paths import locate_profile from traitlets import ( Any, Bool, @@ -22,12 +19,16 @@ from traitlets import ( Instance, Integer, List, + TraitError, Unicode, Union, - TraitError, default, observe, ) +from traitlets.config.configurable import LoggingConfigurable + +from IPython.paths import locate_profile +from IPython.utils.decorators import undoc #----------------------------------------------------------------------------- # Classes and functions @@ -489,8 +490,9 @@ class HistoryManager(HistoryAccessor): input_hist_parsed = List([""]) input_hist_raw = List([""]) # A list of directories visited during session - dir_hist = List() - @default('dir_hist') + dir_hist: List = List() + + @default("dir_hist") def _dir_hist_default(self): try: return [Path.cwd()] @@ -514,8 +516,8 @@ class HistoryManager(HistoryAccessor): "Values of 1 or less effectively disable caching." ).tag(config=True) # The input and output caches - db_input_cache = List() - db_output_cache = List() + db_input_cache: List = List() + db_output_cache: List = List() # History saving in separate thread save_thread = Instance('IPython.core.history.HistorySavingThread', @@ -526,10 +528,10 @@ class HistoryManager(HistoryAccessor): # Variables used to store the three last inputs from the user. On each new # history update, we populate the user's namespace with these, shifted as # necessary. - _i00 = Unicode(u'') - _i = Unicode(u'') - _ii = Unicode(u'') - _iii = Unicode(u'') + _i00 = Unicode("") + _i = Unicode("") + _ii = Unicode("") + _iii = Unicode("") # A regex matching all forms of the exit command, so that we don't store # them in the history (it's annoying to rewind the first entry and land on @@ -554,7 +556,14 @@ class HistoryManager(HistoryAccessor): if self.enabled and self.hist_file != ':memory:': self.save_thread = HistorySavingThread(self) - self.save_thread.start() + try: + self.save_thread.start() + except RuntimeError: + self.log.error( + "Failed to start history saving thread. History will not be saved.", + exc_info=True, + ) + self.hist_file = ":memory:" def _get_hist_file_name(self, profile=None): """Get default history file name based on the Shell's profile. @@ -880,10 +889,10 @@ class HistorySavingThread(threading.Thread): super(HistorySavingThread, self).__init__(name="IPythonHistorySavingThread") self.history_manager = history_manager self.enabled = history_manager.enabled - atexit.register(self.stop) @only_when_enabled def run(self): + atexit.register(self.stop) # We need a separate db connection per thread: try: self.db = sqlite3.connect( @@ -900,6 +909,8 @@ class HistorySavingThread(threading.Thread): except Exception as e: print(("The history saving thread hit an unexpected error (%s)." "History will not be written to the database.") % repr(e)) + finally: + atexit.unregister(self.stop) def stop(self): """This can be called from the main thread to safely stop this thread. diff --git a/contrib/python/ipython/py3/IPython/core/historyapp.py b/contrib/python/ipython/py3/IPython/core/historyapp.py index 01a55343f8a..85dd9c5c3be 100644 --- a/contrib/python/ipython/py3/IPython/core/historyapp.py +++ b/contrib/python/ipython/py3/IPython/core/historyapp.py @@ -32,25 +32,21 @@ This is an handy alias to `ipython history trim --keep=0` class HistoryTrim(BaseIPythonApplication): description = trim_hist_help - - backup = Bool(False, - help="Keep the old history file as history.sqlite.<N>" - ).tag(config=True) - - keep = Int(1000, - help="Number of recent lines to keep in the database." - ).tag(config=True) - - flags = Dict(dict( - backup = ({'HistoryTrim' : {'backup' : True}}, - backup.help - ) - )) - aliases=Dict(dict( - keep = 'HistoryTrim.keep' - )) - + backup = Bool(False, help="Keep the old history file as history.sqlite.<N>").tag( + config=True + ) + + keep = Int(1000, help="Number of recent lines to keep in the database.").tag( + config=True + ) + + flags = Dict( # type: ignore + dict(backup=({"HistoryTrim": {"backup": True}}, backup.help)) + ) + + aliases = Dict(dict(keep="HistoryTrim.keep")) # type: ignore + def start(self): profile_dir = Path(self.profile_dir.location) hist_file = profile_dir / "history.sqlite" @@ -114,34 +110,33 @@ class HistoryTrim(BaseIPythonApplication): print("Backed up longer history file to", backup_hist_file) else: hist_file.unlink() - + new_hist_file.rename(hist_file) + class HistoryClear(HistoryTrim): description = clear_hist_help - keep = Int(0, - help="Number of recent lines to keep in the database.") - - force = Bool(False, - help="Don't prompt user for confirmation" - ).tag(config=True) - - flags = Dict(dict( - force = ({'HistoryClear' : {'force' : True}}, - force.help), - f = ({'HistoryTrim' : {'force' : True}}, - force.help + keep = Int(0, help="Number of recent lines to keep in the database.") + + force = Bool(False, help="Don't prompt user for confirmation").tag(config=True) + + flags = Dict( # type: ignore + dict( + force=({"HistoryClear": {"force": True}}, force.help), + f=({"HistoryTrim": {"force": True}}, force.help), ) - )) - aliases = Dict() + ) + aliases = Dict() # type: ignore def start(self): - if self.force or ask_yes_no("Really delete all ipython history? ", - default="no", interrupt="no"): + if self.force or ask_yes_no( + "Really delete all ipython history? ", default="no", interrupt="no" + ): HistoryTrim.start(self) + class HistoryApp(Application): - name = u'ipython-history' + name = "ipython-history" description = "Manage the IPython history database." subcommands = Dict(dict( diff --git a/contrib/python/ipython/py3/IPython/core/inputsplitter.py b/contrib/python/ipython/py3/IPython/core/inputsplitter.py index 33ed563221b..f1ebd96b69c 100644 --- a/contrib/python/ipython/py3/IPython/core/inputsplitter.py +++ b/contrib/python/ipython/py3/IPython/core/inputsplitter.py @@ -15,6 +15,7 @@ and stores the results. For more details, see the class docstrings below. """ +from __future__ import annotations from warnings import warn @@ -31,7 +32,7 @@ import sys import tokenize import warnings -from typing import List, Tuple, Union, Optional +from typing import List, Tuple, Union, Optional, TYPE_CHECKING from types import CodeType from IPython.core.inputtransformer import (leading_indent, @@ -52,6 +53,8 @@ from IPython.core.inputtransformer import (ESC_SHELL, ESC_SH_CAP, ESC_HELP, ESC_HELP2, ESC_MAGIC, ESC_MAGIC2, ESC_QUOTE, ESC_QUOTE2, ESC_PAREN, ESC_SEQUENCES) +if TYPE_CHECKING: + from typing_extensions import Self #----------------------------------------------------------------------------- # Utilities #----------------------------------------------------------------------------- @@ -637,9 +640,9 @@ class IPythonInputSplitter(InputSplitter): # Nothing that calls reset() expects to handle transformer # errors pass - - def flush_transformers(self): - def _flush(transform, outs): + + def flush_transformers(self: Self): + def _flush(transform, outs: List[str]): """yield transformed lines always strings, never None diff --git a/contrib/python/ipython/py3/IPython/core/interactiveshell.py b/contrib/python/ipython/py3/IPython/core/interactiveshell.py index fef5ddc949b..12c120625b2 100644 --- a/contrib/python/ipython/py3/IPython/core/interactiveshell.py +++ b/contrib/python/ipython/py3/IPython/core/interactiveshell.py @@ -47,16 +47,29 @@ except ModuleNotFoundError: def __init__(self, path): pass - def get(self, key, default): + def get(self, key, default=None): warn( - f"using {key} requires you to install the `pickleshare` library.", + f"This is now an optional IPython functionality, using {key} requires you to install the `pickleshare` library.", stacklevel=2, ) return default + def __getitem__(self, key): + warn( + f"This is now an optional IPython functionality, using {key} requires you to install the `pickleshare` library.", + stacklevel=2, + ) + return None + def __setitem__(self, key, value): warn( - f"using {key} requires you to install the `pickleshare` library.", + f"This is now an optional IPython functionality, setting {key} requires you to install the `pickleshare` library.", + stacklevel=2, + ) + + def __delitem__(self, key): + warn( + f"This is now an optional IPython functionality, deleting {key} requires you to install the `pickleshare` library.", stacklevel=2, ) @@ -268,13 +281,14 @@ class ExecutionInfo(object): ) -class ExecutionResult(object): +class ExecutionResult: """The result of a call to :meth:`InteractiveShell.run_cell` Stores information about what took place. """ - execution_count = None - error_before_exec = None + + execution_count: Optional[int] = None + error_before_exec: Optional[bool] = None error_in_exec: Optional[BaseException] = None info = None result = None @@ -314,11 +328,12 @@ class InteractiveShell(SingletonConfigurable): _instance = None - ast_transformers = List([], help= - """ + ast_transformers: List[ast.NodeTransformer] = List( + [], + help=""" A list of ast.NodeTransformer subclass instances, which will be applied to user input before code is run. - """ + """, ).tag(config=True) autocall = Enum((0,1,2), default_value=0, help= @@ -463,7 +478,8 @@ class InteractiveShell(SingletonConfigurable): def input_transformers_cleanup(self): return self.input_transformer_manager.cleanup_transforms - input_transformers_post = List([], + input_transformers_post: List = List( + [], help="A list of string input transformers, to be applied after IPython's " "own input transformations." ) @@ -553,14 +569,20 @@ class InteractiveShell(SingletonConfigurable): ).tag(config=True) # Subcomponents of InteractiveShell - alias_manager = Instance('IPython.core.alias.AliasManager', allow_none=True) - prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True) - builtin_trap = Instance('IPython.core.builtin_trap.BuiltinTrap', allow_none=True) - display_trap = Instance('IPython.core.display_trap.DisplayTrap', allow_none=True) - extension_manager = Instance('IPython.core.extensions.ExtensionManager', allow_none=True) - payload_manager = Instance('IPython.core.payload.PayloadManager', allow_none=True) - history_manager = Instance('IPython.core.history.HistoryAccessorBase', allow_none=True) - magics_manager = Instance('IPython.core.magic.MagicsManager', allow_none=True) + alias_manager = Instance("IPython.core.alias.AliasManager", allow_none=True) + prefilter_manager = Instance( + "IPython.core.prefilter.PrefilterManager", allow_none=True + ) + builtin_trap = Instance("IPython.core.builtin_trap.BuiltinTrap") + display_trap = Instance("IPython.core.display_trap.DisplayTrap") + extension_manager = Instance( + "IPython.core.extensions.ExtensionManager", allow_none=True + ) + payload_manager = Instance("IPython.core.payload.PayloadManager", allow_none=True) + history_manager = Instance( + "IPython.core.history.HistoryAccessorBase", allow_none=True + ) + magics_manager = Instance("IPython.core.magic.MagicsManager") profile_dir = Instance('IPython.core.application.ProfileDir', allow_none=True) @property @@ -1396,6 +1418,7 @@ class InteractiveShell(SingletonConfigurable): If new_session is True, a new history session will be opened. """ # Clear histories + assert self.history_manager is not None self.history_manager.reset(new_session) # Reset counter used to index all histories if new_session: @@ -1482,6 +1505,7 @@ class InteractiveShell(SingletonConfigurable): except KeyError as e: raise NameError("name '%s' is not defined" % varname) from e # Also check in output history + assert self.history_manager is not None ns_refs.append(self.history_manager.output_hist) for ns in ns_refs: to_delete = [n for n, o in ns.items() if o is obj] @@ -1801,7 +1825,7 @@ class InteractiveShell(SingletonConfigurable): """Find an object and return a struct with info about it.""" return self._ofind(oname, namespaces) - def _inspect(self, meth, oname, namespaces=None, **kw): + def _inspect(self, meth, oname: str, namespaces=None, **kw): """Generic interface to the inspector system. This function is meant to be called by pdef, pdoc & friends. @@ -2409,7 +2433,7 @@ class InteractiveShell(SingletonConfigurable): res = finder(magic_name) return res - def run_line_magic(self, magic_name: str, line, _stack_depth=1): + def run_line_magic(self, magic_name: str, line: str, _stack_depth=1): """Execute the given line magic. Parameters @@ -3256,6 +3280,7 @@ class InteractiveShell(SingletonConfigurable): # Store raw and processed history if store_history: + assert self.history_manager is not None self.history_manager.store_inputs(self.execution_count, cell, raw_cell) if not silent: self.logger.log(cell, raw_cell) @@ -3272,8 +3297,6 @@ class InteractiveShell(SingletonConfigurable): # compiler compiler = self.compile if shell_futures else self.compiler_class() - _run_async = False - with self.builtin_trap: cell_name = compiler.cache(cell, self.execution_count, raw_code=raw_cell) @@ -3319,6 +3342,7 @@ class InteractiveShell(SingletonConfigurable): self.displayhook.exec_result = None if store_history: + assert self.history_manager is not None # Write output to the database. Does nothing unless # history output logging is enabled. self.history_manager.store_output(self.execution_count) @@ -3630,8 +3654,6 @@ class InteractiveShell(SingletonConfigurable): make sense in all contexts, for example a terminal ipython can't display figures inline. """ - from matplotlib_inline.backend_inline import configure_inline_support - from IPython.core import pylabtools as pt gui, backend = pt.find_gui_and_backend(gui, self.pylab_gui_select) @@ -3646,6 +3668,9 @@ class InteractiveShell(SingletonConfigurable): gui, backend = pt.find_gui_and_backend(self.pylab_gui_select) pt.activate_matplotlib(backend) + + from matplotlib_inline.backend_inline import configure_inline_support + configure_inline_support(self, backend) # Now we must activate the gui pylab wants to use, and fix %run to take diff --git a/contrib/python/ipython/py3/IPython/core/magic.py b/contrib/python/ipython/py3/IPython/core/magic.py index 4f9e4e548f7..bbb1550a47f 100644 --- a/contrib/python/ipython/py3/IPython/core/magic.py +++ b/contrib/python/ipython/py3/IPython/core/magic.py @@ -26,6 +26,8 @@ from ..utils.text import dedent from traitlets import Bool, Dict, Instance, observe from logging import error +import typing as t + #----------------------------------------------------------------------------- # Globals #----------------------------------------------------------------------------- @@ -36,7 +38,7 @@ from logging import error # access to the class when they run. See for more details: # http://stackoverflow.com/questions/2366713/can-a-python-decorator-of-an-instance-method-access-the-class -magics = dict(line={}, cell={}) +magics: t.Dict = dict(line={}, cell={}) magic_kinds = ('line', 'cell') magic_spec = ('line', 'cell', 'line_cell') diff --git a/contrib/python/ipython/py3/IPython/core/magics/ast_mod.py b/contrib/python/ipython/py3/IPython/core/magics/ast_mod.py index e28b9f1231f..fa547914437 100644 --- a/contrib/python/ipython/py3/IPython/core/magics/ast_mod.py +++ b/contrib/python/ipython/py3/IPython/core/magics/ast_mod.py @@ -178,11 +178,21 @@ transforming: __skip_doctest__ = True -from ast import NodeTransformer, Store, Load, Name, Expr, Assign, Module +from ast import ( + NodeTransformer, + Store, + Load, + Name, + Expr, + Assign, + Module, + Import, + ImportFrom, +) import ast import copy -from typing import Dict, Optional +from typing import Dict, Optional, Union mangle_all = lambda name: False if name in ("__ret__", "__code__") else True @@ -231,13 +241,13 @@ class Mangler(NodeTransformer): self.log("Not mangling function arg", arg.arg) return self.generic_visit(node) - def visit_ImportFrom(self, node): + def visit_ImportFrom(self, node: ImportFrom): return self._visit_Import_and_ImportFrom(node) - def visit_Import(self, node): + def visit_Import(self, node: Import): return self._visit_Import_and_ImportFrom(node) - def _visit_Import_and_ImportFrom(self, node): + def _visit_Import_and_ImportFrom(self, node: Union[Import, ImportFrom]): for alias in node.names: asname = alias.name if alias.asname is None else alias.asname if self.predicate(asname): diff --git a/contrib/python/ipython/py3/IPython/core/magics/script.py b/contrib/python/ipython/py3/IPython/core/magics/script.py index a858c6489c8..0c405ef420f 100644 --- a/contrib/python/ipython/py3/IPython/core/magics/script.py +++ b/contrib/python/ipython/py3/IPython/core/magics/script.py @@ -86,7 +86,7 @@ class ScriptMagics(Magics): """ ) - script_magics = List( + script_magics: List = List( help="""Extra script cell magics to define This generates simple wrappers of `%%script foo` as `%%foo`. @@ -95,6 +95,7 @@ class ScriptMagics(Magics): specify them in script_paths """, ).tag(config=True) + @default('script_magics') def _script_magics_default(self): """default to a common list of programs""" diff --git a/contrib/python/ipython/py3/IPython/core/oinspect.py b/contrib/python/ipython/py3/IPython/core/oinspect.py index 9eecf290ae0..937e5a9d4bc 100644 --- a/contrib/python/ipython/py3/IPython/core/oinspect.py +++ b/contrib/python/ipython/py3/IPython/core/oinspect.py @@ -24,9 +24,18 @@ import os import types import warnings -from typing import Any, Optional, Dict, Union, List, Tuple -from typing import TypeAlias +from typing import ( + cast, + Any, + Optional, + Dict, + Union, + List, + TypedDict, + TypeAlias, + Tuple, +) import traitlets @@ -34,15 +43,12 @@ import traitlets from IPython.core import page from IPython.lib.pretty import pretty from IPython.testing.skipdoctest import skip_doctest -from IPython.utils import PyColorize -from IPython.utils import openpy +from IPython.utils import PyColorize, openpy from IPython.utils.dir2 import safe_hasattr from IPython.utils.path import compress_user from IPython.utils.text import indent -from IPython.utils.wildcard import list_namespace -from IPython.utils.wildcard import typestr2type +from IPython.utils.wildcard import list_namespace, typestr2type from IPython.utils.coloransi import TermColors -from IPython.utils.py3compat import cast_unicode from IPython.utils.colorable import Colorable from IPython.utils.decorators import undoc @@ -106,23 +112,78 @@ InspectColors = PyColorize.ANSICodeColors #**************************************************************************** # Auxiliary functions and objects -# See the messaging spec for the definition of all these fields. This list -# effectively defines the order of display -info_fields = ['type_name', 'base_class', 'string_form', 'namespace', - 'length', 'file', 'definition', 'docstring', 'source', - 'init_definition', 'class_docstring', 'init_docstring', - 'call_def', 'call_docstring', - # These won't be printed but will be used to determine how to - # format the object - 'ismagic', 'isalias', 'isclass', 'found', 'name' - ] +class InfoDict(TypedDict): + type_name: Optional[str] + base_class: Optional[str] + string_form: Optional[str] + namespace: Optional[str] + length: Optional[str] + file: Optional[str] + definition: Optional[str] + docstring: Optional[str] + source: Optional[str] + init_definition: Optional[str] + class_docstring: Optional[str] + init_docstring: Optional[str] + call_def: Optional[str] + call_docstring: Optional[str] + subclasses: Optional[str] + # These won't be printed but will be used to determine how to + # format the object + ismagic: bool + isalias: bool + isclass: bool + found: bool + name: str + + +_info_fields = list(InfoDict.__annotations__.keys()) + + +def __getattr__(name): + if name == "info_fields": + warnings.warn( + "IPython.core.oinspect's `info_fields` is considered for deprecation and may be removed in the Future. ", + DeprecationWarning, + stacklevel=2, + ) + return _info_fields + + raise AttributeError(f"module {__name__!r} has no attribute {name!r}") + + +@dataclass +class InspectorHookData: + """Data passed to the mime hook""" -def object_info(**kw): + obj: Any + info: Optional[OInfo] + info_dict: InfoDict + detail_level: int + omit_sections: list[str] + + +@undoc +def object_info( + *, + name: str, + found: bool, + isclass: bool = False, + isalias: bool = False, + ismagic: bool = False, + **kw, +) -> InfoDict: """Make an object info dict with all fields present.""" - infodict = {k:None for k in info_fields} - infodict.update(kw) - return infodict + infodict = kw + infodict = {k: None for k in _info_fields if k not in infodict} + infodict["name"] = name # type: ignore + infodict["found"] = found # type: ignore + infodict["isclass"] = isclass # type: ignore + infodict["isalias"] = isalias # type: ignore + infodict["ismagic"] = ismagic # type: ignore + + return InfoDict(**infodict) # type:ignore def get_encoding(obj): @@ -148,7 +209,8 @@ def get_encoding(obj): encoding, _lines = openpy.detect_encoding(buffer.readline) return encoding -def getdoc(obj) -> Union[str,None]: + +def getdoc(obj) -> Union[str, None]: """Stable wrapper around inspect.getdoc. This can't crash because of attribute problems. @@ -554,8 +616,10 @@ class Inspector(Colorable): # run contents of file through pager starting at line where the object # is defined, as long as the file isn't binary and is actually on the # filesystem. - if ofile.endswith(('.so', '.dll', '.pyd')): - print('File %r is binary, not printing.' % ofile) + if ofile is None: + print("Could not find file for object") + elif ofile.endswith((".so", ".dll", ".pyd")): + print("File %r is binary, not printing." % ofile) elif not os.path.isfile(ofile): print('File %r does not exist, not printing.' % ofile) else: @@ -643,7 +707,7 @@ class Inspector(Colorable): title: str, key: str, info, - omit_sections, + omit_sections: List[str], formatter, ): """Append an info value to the unformatted mimebundle being constructed by _make_info_unformatted""" @@ -740,8 +804,8 @@ class Inspector(Colorable): oname: str = "", formatter=None, info: Optional[OInfo] = None, - detail_level=0, - omit_sections=(), + detail_level: int = 0, + omit_sections: Union[List[str], Tuple[()]] = (), ) -> Bundle: """Retrieve an info dict and format it. @@ -756,11 +820,13 @@ class Inspector(Colorable): already computed information detail_level : integer Granularity of detail level, if set to 1, give more information. - omit_sections : container[str] + omit_sections : list[str] Titles or keys to omit from output (can be set, tuple, etc., anything supporting `in`) """ info_dict = self.info(obj, oname=oname, info=info, detail_level=detail_level) + omit_sections = list(omit_sections) + bundle = self._make_info_unformatted( obj, info_dict, @@ -768,10 +834,33 @@ class Inspector(Colorable): detail_level=detail_level, omit_sections=omit_sections, ) - for key, hook in self.mime_hooks.items(): - res = hook(obj, info) - if res is not None: - bundle[key] = res + if self.mime_hooks: + hook_data = InspectorHookData( + obj=obj, + info=info, + info_dict=info_dict, + detail_level=detail_level, + omit_sections=omit_sections, + ) + for key, hook in self.mime_hooks.items(): # type:ignore + required_parameters = [ + parameter + for parameter in inspect.signature(hook).parameters.values() + if parameter.default != inspect.Parameter.default + ] + if len(required_parameters) == 1: + res = hook(hook_data) + else: + warnings.warn( + "MIME hook format changed in IPython 8.22; hooks should now accept" + " a single parameter (InspectorHookData); support for hooks requiring" + " two-parameters (obj and info) will be removed in a future version", + DeprecationWarning, + stacklevel=2, + ) + res = hook(obj, info) + if res is not None: + bundle[key] = res return self.format_mime(bundle) def pinfo( @@ -830,7 +919,7 @@ class Inspector(Colorable): ) return self.info(obj, oname=oname, info=info, detail_level=detail_level) - def info(self, obj, oname="", info=None, detail_level=0) -> Dict[str, Any]: + def info(self, obj, oname="", info=None, detail_level=0) -> InfoDict: """Compute a dict with detailed information about an object. Parameters @@ -847,8 +936,7 @@ class Inspector(Colorable): Returns ------- - An object info dict with known fields from `info_fields`. Keys are - strings, values are string or None. + An object info dict with known fields from `info_fields` (see `InfoDict`). """ if info is None: @@ -867,8 +955,18 @@ class Inspector(Colorable): if info and info.parent is not None and hasattr(info.parent, HOOK_NAME): parents_docs_dict = getattr(info.parent, HOOK_NAME) parents_docs = parents_docs_dict.get(att_name, None) - out = dict( - name=oname, found=True, isalias=isalias, ismagic=ismagic, subclasses=None + out: InfoDict = cast( + InfoDict, + { + **{field: None for field in _info_fields}, + **{ + "name": oname, + "found": True, + "isalias": isalias, + "ismagic": ismagic, + "subclasses": None, + }, + }, ) if parents_docs: @@ -914,12 +1012,14 @@ class Inspector(Colorable): if detail_level >= self.str_detail_level: try: ostr = str(obj) - str_head = 'string_form' - if not detail_level and len(ostr)>string_max: + if not detail_level and len(ostr) > string_max: ostr = ostr[:shalf] + ' <...> ' + ostr[-shalf:] - ostr = ("\n" + " " * len(str_head.expandtabs())).\ - join(q.strip() for q in ostr.split("\n")) - out[str_head] = ostr + # TODO: `'string_form'.expandtabs()` seems wrong, but + # it was (nearly) like this since the first commit ever. + ostr = ("\n" + " " * len("string_form".expandtabs())).join( + q.strip() for q in ostr.split("\n") + ) + out["string_form"] = ostr except: pass @@ -1054,7 +1154,7 @@ class Inspector(Colorable): if call_ds: out['call_docstring'] = call_ds - return object_info(**out) + return out @staticmethod def _source_contains_docstring(src, doc): diff --git a/contrib/python/ipython/py3/IPython/core/prefilter.py b/contrib/python/ipython/py3/IPython/core/prefilter.py index e7e82e33771..5b1b86c7530 100644 --- a/contrib/python/ipython/py3/IPython/core/prefilter.py +++ b/contrib/python/ipython/py3/IPython/core/prefilter.py @@ -524,11 +524,14 @@ class AutocallChecker(PrefilterChecker): class PrefilterHandler(Configurable): - - handler_name = Unicode('normal') - esc_strings = List([]) - shell = Instance('IPython.core.interactiveshell.InteractiveShellABC', allow_none=True) - prefilter_manager = Instance('IPython.core.prefilter.PrefilterManager', allow_none=True) + handler_name = Unicode("normal") + esc_strings: List = List([]) + shell = Instance( + "IPython.core.interactiveshell.InteractiveShellABC", allow_none=True + ) + prefilter_manager = Instance( + "IPython.core.prefilter.PrefilterManager", allow_none=True + ) def __init__(self, shell=None, prefilter_manager=None, **kwargs): super(PrefilterHandler, self).__init__( diff --git a/contrib/python/ipython/py3/IPython/core/release.py b/contrib/python/ipython/py3/IPython/core/release.py index f71ee85c08c..f668902edf0 100644 --- a/contrib/python/ipython/py3/IPython/core/release.py +++ b/contrib/python/ipython/py3/IPython/core/release.py @@ -16,8 +16,8 @@ # release. 'dev' as a _version_extra string means this is a development # version _version_major = 8 -_version_minor = 21 -_version_patch = 0 +_version_minor = 22 +_version_patch = 2 _version_extra = ".dev" # _version_extra = "rc1" _version_extra = "" # Uncomment this for full releases diff --git a/contrib/python/ipython/py3/IPython/core/ultratb.py b/contrib/python/ipython/py3/IPython/core/ultratb.py index b0f9e08a3d1..382ab1c029a 100644 --- a/contrib/python/ipython/py3/IPython/core/ultratb.py +++ b/contrib/python/ipython/py3/IPython/core/ultratb.py @@ -743,6 +743,7 @@ class FrameInfo: lineno: Tuple[int] # number of context lines to use context: Optional[int] + raw_lines: List[str] @classmethod def _from_stack_data_FrameInfo(cls, frame_info): @@ -777,8 +778,13 @@ class FrameInfo: # self.lines = [] if sd is None: - ix = inspect.getsourcelines(frame) - self.raw_lines = ix[0] + try: + # return a list of source lines and a starting line number + self.raw_lines = inspect.getsourcelines(frame)[0] + except OSError: + self.raw_lines = [ + "'Could not get source, probably due dynamically evaluated source code.'" + ] @property def variables_in_executing_piece(self): diff --git a/contrib/python/ipython/py3/IPython/extensions/storemagic.py b/contrib/python/ipython/py3/IPython/extensions/storemagic.py index d9d00f14b9a..f3bc8f6c136 100644 --- a/contrib/python/ipython/py3/IPython/extensions/storemagic.py +++ b/contrib/python/ipython/py3/IPython/extensions/storemagic.py @@ -145,7 +145,7 @@ class StoreMagics(Magics): if args: for arg in args: try: - obj = db['autorestore/' + arg] + obj = db["autorestore/" + arg] except KeyError: try: restore_aliases(ip, alias=arg) diff --git a/contrib/python/ipython/py3/IPython/lib/pretty.py b/contrib/python/ipython/py3/IPython/lib/pretty.py index 2575c3b0a94..631445b24e3 100644 --- a/contrib/python/ipython/py3/IPython/lib/pretty.py +++ b/contrib/python/ipython/py3/IPython/lib/pretty.py @@ -1,4 +1,3 @@ -# -*- coding: utf-8 -*- """ Python advanced pretty printer. This pretty printer is intended to replace the old `pprint` python module which does not allow developers @@ -108,6 +107,8 @@ from warnings import warn from IPython.utils.decorators import undoc from IPython.utils.py3compat import PYPY +from typing import Dict + __all__ = ['pretty', 'pprint', 'PrettyPrinter', 'RepresentationPrinter', 'for_type', 'for_type_by_name', 'RawText', 'RawStringLiteral', 'CallExpression'] @@ -807,6 +808,7 @@ def _exception_pprint(obj, p, cycle): #: the exception base +_exception_base: type try: _exception_base = BaseException except NameError: @@ -848,8 +850,8 @@ _type_pprinters[range] = _repr_pprint _type_pprinters[bytes] = _repr_pprint #: printers for types specified by name -_deferred_type_pprinters = { -} +_deferred_type_pprinters: Dict = {} + def for_type(typ, func): """ diff --git a/contrib/python/ipython/py3/IPython/utils/_process_emscripten.py b/contrib/python/ipython/py3/IPython/utils/_process_emscripten.py new file mode 100644 index 00000000000..05dcdc34d5f --- /dev/null +++ b/contrib/python/ipython/py3/IPython/utils/_process_emscripten.py @@ -0,0 +1,23 @@ +"""Emscripten-specific implementation of process utilities. + +This file is only meant to be imported by process.py, not by end-users. +""" + + +from ._process_common import arg_split + + +def system(cmd): + raise OSError("Not available") + + +def getoutput(cmd): + raise OSError("Not available") + + +def check_pid(cmd): + raise OSError("Not available") + + +# `arg_split` is still used by magics regardless of whether we are on a posix/windows/emscipten +__all__ = ["system", "getoutput", "check_pid", "arg_split"] diff --git a/contrib/python/ipython/py3/IPython/utils/_sysinfo.py b/contrib/python/ipython/py3/IPython/utils/_sysinfo.py index 56568073d77..22be56b84bb 100644 --- a/contrib/python/ipython/py3/IPython/utils/_sysinfo.py +++ b/contrib/python/ipython/py3/IPython/utils/_sysinfo.py @@ -1,2 +1,2 @@ # GENERATED BY setup.py -commit = "8b1204b6c" +commit = "d1804576b" diff --git a/contrib/python/ipython/py3/IPython/utils/path.py b/contrib/python/ipython/py3/IPython/utils/path.py index ccb70dccd43..cb5be041957 100644 --- a/contrib/python/ipython/py3/IPython/utils/path.py +++ b/contrib/python/ipython/py3/IPython/utils/path.py @@ -12,6 +12,7 @@ import errno import shutil import random import glob +import warnings from IPython.utils.process import system @@ -292,7 +293,14 @@ def target_outdated(target,deps): If target doesn't exist or is older than any file listed in deps, return true, otherwise return false. + + .. deprecated:: 8.22 """ + warnings.warn( + "`target_outdated` is deprecated since IPython 8.22 and will be removed in future versions", + DeprecationWarning, + stacklevel=2, + ) try: target_time = os.path.getmtime(target) except os.error: @@ -312,9 +320,17 @@ def target_update(target,deps,cmd): target_update(target,deps,cmd) -> runs cmd if target is outdated. This is just a wrapper around target_outdated() which calls the given - command if target is outdated.""" + command if target is outdated. + + .. deprecated:: 8.22 + """ - if target_outdated(target,deps): + warnings.warn( + "`target_update` is deprecated since IPython 8.22 and will be removed in future versions", + DeprecationWarning, + stacklevel=2, + ) + if target_outdated(target, deps): system(cmd) diff --git a/contrib/python/ipython/py3/IPython/utils/process.py b/contrib/python/ipython/py3/IPython/utils/process.py index 489b7c13d0c..f50cf9ba223 100644 --- a/contrib/python/ipython/py3/IPython/utils/process.py +++ b/contrib/python/ipython/py3/IPython/utils/process.py @@ -15,6 +15,8 @@ if sys.platform == 'win32': from ._process_win32 import system, getoutput, arg_split, check_pid elif sys.platform == 'cli': from ._process_cli import system, getoutput, arg_split, check_pid +elif sys.platform == "emscripten": + from ._process_emscripten import system, getoutput, arg_split, check_pid else: from ._process_posix import system, getoutput, arg_split, check_pid diff --git a/contrib/python/ipython/py3/IPython/utils/text.py b/contrib/python/ipython/py3/IPython/utils/text.py index 8f73dca28a0..51dcdae5dd3 100644 --- a/contrib/python/ipython/py3/IPython/utils/text.py +++ b/contrib/python/ipython/py3/IPython/utils/text.py @@ -1,4 +1,3 @@ -# encoding: utf-8 """ Utilities for working with strings and text. @@ -11,13 +10,12 @@ Inheritance diagram: import os import re import string -import sys import textwrap import warnings from string import Formatter from pathlib import Path -from typing import List, Dict, Tuple +from typing import List, Dict, Tuple, Optional, cast class LSString(str): @@ -540,11 +538,12 @@ class FullEvalFormatter(Formatter): """ # copied from Formatter._vformat with minor changes to allow eval # and replace the format_spec code with slicing - def vformat(self, format_string:str, args, kwargs)->str: + def vformat(self, format_string: str, args, kwargs) -> str: result = [] - for literal_text, field_name, format_spec, conversion in \ - self.parse(format_string): - + conversion: Optional[str] + for literal_text, field_name, format_spec, conversion in self.parse( + format_string + ): # output the literal text if literal_text: result.append(literal_text) @@ -563,7 +562,8 @@ class FullEvalFormatter(Formatter): obj = eval(field_name, kwargs) # do any conversion on the resulting object - obj = self.convert_field(obj, conversion) + # type issue in typeshed, fined in https://github.com/python/typeshed/pull/11377 + obj = self.convert_field(obj, conversion) # type: ignore[arg-type] # format the object and append to the result result.append(self.format_field(obj, '')) @@ -722,7 +722,13 @@ def compute_item_matrix( return ([[_get_or_default(items, c * nrow + r, default=empty) for c in range(ncol)] for r in range(nrow)], info) -def columnize(items, row_first=False, separator=" ", displaywidth=80, spread=False): +def columnize( + items: List[str], + row_first: bool = False, + separator: str = " ", + displaywidth: int = 80, + spread: bool = False, +): """Transform a list of strings into a single string with columns. Parameters @@ -743,7 +749,7 @@ def columnize(items, row_first=False, separator=" ", displaywidth=80, spread=Fa """ warnings.warn( "`columnize` is Pending Deprecation since IPython 8.17." - "It is considered fro removal in in future version. " + "It is considered for removal in future versions. " "Please open an issue if you believe it should be kept.", stacklevel=2, category=PendingDeprecationWarning, @@ -761,7 +767,7 @@ def columnize(items, row_first=False, separator=" ", displaywidth=80, spread=Fa separator = separator.ljust(int(info["optimal_separator_width"])) fmatrix: List[filter[int]] = [filter(None, x) for x in matrix] sjoin = lambda x: separator.join( - [y.ljust(w, " ") for y, w in zip(x, info["column_widths"])] + [y.ljust(w, " ") for y, w in zip(x, cast(List[int], info["column_widths"]))] ) return "\n".join(map(sjoin, fmatrix)) + "\n" diff --git a/contrib/python/ipython/py3/ya.make b/contrib/python/ipython/py3/ya.make index a53c5172e7f..76d52094def 100644 --- a/contrib/python/ipython/py3/ya.make +++ b/contrib/python/ipython/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(8.21.0) +VERSION(8.22.2) LICENSE(BSD-3-Clause) @@ -174,6 +174,7 @@ PY_SRCS( IPython/utils/__init__.py IPython/utils/_process_cli.py IPython/utils/_process_common.py + IPython/utils/_process_emscripten.py IPython/utils/_process_posix.py IPython/utils/_process_win32.py IPython/utils/_process_win32_controller.py diff --git a/contrib/python/setuptools/py3/.dist-info/METADATA b/contrib/python/setuptools/py3/.dist-info/METADATA index 6abcbef24b4..237cc66f131 100644 --- a/contrib/python/setuptools/py3/.dist-info/METADATA +++ b/contrib/python/setuptools/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: setuptools -Version: 69.1.0 +Version: 69.1.1 Summary: Easily download, build, install, upgrade, and uninstall Python packages Home-page: https://github.com/pypa/setuptools Author: Python Packaging Authority @@ -43,6 +43,7 @@ Requires-Dist: flake8-2020 ; extra == 'testing' Requires-Dist: virtualenv >=13.0.0 ; extra == 'testing' Requires-Dist: wheel ; extra == 'testing' Requires-Dist: pip >=19.1 ; extra == 'testing' +Requires-Dist: packaging >=23.2 ; extra == 'testing' Requires-Dist: jaraco.envs >=2.2 ; extra == 'testing' Requires-Dist: pytest-xdist ; extra == 'testing' Requires-Dist: jaraco.path >=3.2.0 ; extra == 'testing' @@ -63,7 +64,7 @@ Requires-Dist: jaraco.path >=3.2.0 ; extra == 'testing-integration' Requires-Dist: jaraco.envs >=2.2 ; extra == 'testing-integration' Requires-Dist: build[virtualenv] >=1.0.3 ; extra == 'testing-integration' Requires-Dist: filelock >=3.4.0 ; extra == 'testing-integration' -Requires-Dist: packaging >=23.1 ; extra == 'testing-integration' +Requires-Dist: packaging >=23.2 ; extra == 'testing-integration' Requires-Dist: pytest-cov ; (platform_python_implementation != "PyPy") and extra == 'testing' Requires-Dist: pytest-mypy >=0.9.1 ; (platform_python_implementation != "PyPy") and extra == 'testing' Requires-Dist: jaraco.develop >=7.21 ; (python_version >= "3.9" and sys_platform != "cygwin") and extra == 'testing' diff --git a/contrib/python/setuptools/py3/setuptools/build_meta.py b/contrib/python/setuptools/py3/setuptools/build_meta.py index 0a0abfdae0d..2decd2d2140 100644 --- a/contrib/python/setuptools/py3/setuptools/build_meta.py +++ b/contrib/python/setuptools/py3/setuptools/build_meta.py @@ -369,7 +369,12 @@ class _BuildMetaBackend(_ConfigSettingsTranslator): return self._bubble_up_info_directory(metadata_directory, ".dist-info") def _build_with_temp_dir( - self, setup_command, result_extension, result_directory, config_settings + self, + setup_command, + result_extension, + result_directory, + config_settings, + arbitrary_args=(), ): result_directory = os.path.abspath(result_directory) @@ -384,6 +389,7 @@ class _BuildMetaBackend(_ConfigSettingsTranslator): *setup_command, "--dist-dir", tmp_dist_dir, + *arbitrary_args, ] with no_install_setup_requires(): self.run_setup() @@ -402,10 +408,11 @@ class _BuildMetaBackend(_ConfigSettingsTranslator): ): with suppress_known_deprecation(): return self._build_with_temp_dir( - ['bdist_wheel', *self._arbitrary_args(config_settings)], + ['bdist_wheel'], '.whl', wheel_directory, config_settings, + self._arbitrary_args(config_settings), ) def build_sdist(self, sdist_directory, config_settings=None): diff --git a/contrib/python/setuptools/py3/ya.make b/contrib/python/setuptools/py3/ya.make index 564d2688755..4210fba1924 100644 --- a/contrib/python/setuptools/py3/ya.make +++ b/contrib/python/setuptools/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(69.1.0) +VERSION(69.1.1) LICENSE(MIT) diff --git a/contrib/python/sniffio/.dist-info/METADATA b/contrib/python/sniffio/.dist-info/METADATA index 22520c72aff..88968aed169 100644 --- a/contrib/python/sniffio/.dist-info/METADATA +++ b/contrib/python/sniffio/.dist-info/METADATA @@ -1,11 +1,12 @@ Metadata-Version: 2.1 Name: sniffio -Version: 1.3.0 +Version: 1.3.1 Summary: Sniff out which async library your code is running under -Home-page: https://github.com/python-trio/sniffio -Author: Nathaniel J. Smith -Author-email: [email protected] +Author-email: "Nathaniel J. Smith" <[email protected]> License: MIT OR Apache-2.0 +Project-URL: Homepage, https://github.com/python-trio/sniffio +Project-URL: Documentation, https://sniffio.readthedocs.io/ +Project-URL: Changelog, https://sniffio.readthedocs.io/en/latest/history.html Keywords: async,trio,asyncio Classifier: License :: OSI Approved :: MIT License Classifier: License :: OSI Approved :: Apache Software License @@ -20,6 +21,7 @@ Classifier: Programming Language :: Python :: Implementation :: PyPy Classifier: Intended Audience :: Developers Classifier: Development Status :: 5 - Production/Stable Requires-Python: >=3.7 +Description-Content-Type: text/x-rst License-File: LICENSE License-File: LICENSE.APACHE2 License-File: LICENSE.MIT diff --git a/contrib/python/sniffio/sniffio/__init__.py b/contrib/python/sniffio/sniffio/__init__.py index fb3364d7f1f..63f2f19e409 100644 --- a/contrib/python/sniffio/sniffio/__init__.py +++ b/contrib/python/sniffio/sniffio/__init__.py @@ -1,8 +1,10 @@ """Top-level package for sniffio.""" __all__ = [ - "current_async_library", "AsyncLibraryNotFoundError", - "current_async_library_cvar" + "current_async_library", + "AsyncLibraryNotFoundError", + "current_async_library_cvar", + "thread_local", ] from ._version import __version__ diff --git a/contrib/python/sniffio/sniffio/_version.py b/contrib/python/sniffio/sniffio/_version.py index 5a5f906bbf9..0495d10545c 100644 --- a/contrib/python/sniffio/sniffio/_version.py +++ b/contrib/python/sniffio/sniffio/_version.py @@ -1,3 +1,3 @@ # This file is imported from __init__.py and exec'd from setup.py -__version__ = "1.3.0" +__version__ = "1.3.1" diff --git a/contrib/python/sniffio/ya.make b/contrib/python/sniffio/ya.make index d0e376d4ca8..165b99c587e 100644 --- a/contrib/python/sniffio/ya.make +++ b/contrib/python/sniffio/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(1.3.0) +VERSION(1.3.1) LICENSE(Apache-2.0 AND MIT) diff --git a/contrib/python/typing-extensions/py3/.dist-info/METADATA b/contrib/python/typing-extensions/py3/.dist-info/METADATA index 863e977c2f7..13d06e24b78 100644 --- a/contrib/python/typing-extensions/py3/.dist-info/METADATA +++ b/contrib/python/typing-extensions/py3/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: typing_extensions -Version: 4.9.0 +Version: 4.10.0 Summary: Backported and Experimental Type Hints for Python 3.8+ Keywords: annotations,backport,checker,checking,function,hinting,hints,type,typechecking,typehinting,typehints,typing Author-email: "Guido van Rossum, Jukka Lehtosalo, Ćukasz Langa, Michael Lee" <[email protected]> diff --git a/contrib/python/typing-extensions/py3/typing_extensions.py b/contrib/python/typing-extensions/py3/typing_extensions.py index 1666e96b7e2..f3132ea4ae1 100644 --- a/contrib/python/typing-extensions/py3/typing_extensions.py +++ b/contrib/python/typing-extensions/py3/typing_extensions.py @@ -83,6 +83,7 @@ __all__ = [ 'TypeAlias', 'TypeAliasType', 'TypeGuard', + 'TypeIs', 'TYPE_CHECKING', 'Never', 'NoReturn', @@ -473,7 +474,7 @@ _EXCLUDED_ATTRS = { "_is_runtime_protocol", "__dict__", "__slots__", "__parameters__", "__orig_bases__", "__module__", "_MutableMapping__marker", "__doc__", "__subclasshook__", "__orig_class__", "__init__", "__new__", - "__protocol_attrs__", "__callable_proto_members_only__", + "__protocol_attrs__", "__non_callable_proto_members__", "__match_args__", } @@ -521,6 +522,22 @@ else: if type(self)._is_protocol: raise TypeError('Protocols cannot be instantiated') + def _type_check_issubclass_arg_1(arg): + """Raise TypeError if `arg` is not an instance of `type` + in `issubclass(arg, <protocol>)`. + + In most cases, this is verified by type.__subclasscheck__. + Checking it again unnecessarily would slow down issubclass() checks, + so, we don't perform this check unless we absolutely have to. + + For various error paths, however, + we want to ensure that *this* error message is shown to the user + where relevant, rather than a typing.py-specific error message. + """ + if not isinstance(arg, type): + # Same error message as for issubclass(1, int). + raise TypeError('issubclass() arg 1 must be a class') + # Inheriting from typing._ProtocolMeta isn't actually desirable, # but is necessary to allow typing.Protocol and typing_extensions.Protocol # to mix without getting TypeErrors about "metaclass conflict" @@ -551,11 +568,6 @@ else: abc.ABCMeta.__init__(cls, *args, **kwargs) if getattr(cls, "_is_protocol", False): cls.__protocol_attrs__ = _get_protocol_attrs(cls) - # PEP 544 prohibits using issubclass() - # with protocols that have non-method members. - cls.__callable_proto_members_only__ = all( - callable(getattr(cls, attr, None)) for attr in cls.__protocol_attrs__ - ) def __subclasscheck__(cls, other): if cls is Protocol: @@ -564,26 +576,23 @@ else: getattr(cls, '_is_protocol', False) and not _allow_reckless_class_checks() ): - if not isinstance(other, type): - # Same error message as for issubclass(1, int). - raise TypeError('issubclass() arg 1 must be a class') + if not getattr(cls, '_is_runtime_protocol', False): + _type_check_issubclass_arg_1(other) + raise TypeError( + "Instance and class checks can only be used with " + "@runtime_checkable protocols" + ) if ( - not cls.__callable_proto_members_only__ + # this attribute is set by @runtime_checkable: + cls.__non_callable_proto_members__ and cls.__dict__.get("__subclasshook__") is _proto_hook ): - non_method_attrs = sorted( - attr for attr in cls.__protocol_attrs__ - if not callable(getattr(cls, attr, None)) - ) + _type_check_issubclass_arg_1(other) + non_method_attrs = sorted(cls.__non_callable_proto_members__) raise TypeError( "Protocols with non-method members don't support issubclass()." f" Non-method members: {str(non_method_attrs)[1:-1]}." ) - if not getattr(cls, '_is_runtime_protocol', False): - raise TypeError( - "Instance and class checks can only be used with " - "@runtime_checkable protocols" - ) return abc.ABCMeta.__subclasscheck__(cls, other) def __instancecheck__(cls, instance): @@ -610,7 +619,8 @@ else: val = inspect.getattr_static(instance, attr) except AttributeError: break - if val is None and callable(getattr(cls, attr, None)): + # this attribute is set by @runtime_checkable: + if val is None and attr not in cls.__non_callable_proto_members__: break else: return True @@ -678,8 +688,58 @@ else: cls.__init__ = _no_init +if sys.version_info >= (3, 13): + runtime_checkable = typing.runtime_checkable +else: + def runtime_checkable(cls): + """Mark a protocol class as a runtime protocol. + + Such protocol can be used with isinstance() and issubclass(). + Raise TypeError if applied to a non-protocol class. + This allows a simple-minded structural check very similar to + one trick ponies in collections.abc such as Iterable. + + For example:: + + @runtime_checkable + class Closable(Protocol): + def close(self): ... + + assert isinstance(open('/some/file'), Closable) + + Warning: this will check only the presence of the required methods, + not their type signatures! + """ + if not issubclass(cls, typing.Generic) or not getattr(cls, '_is_protocol', False): + raise TypeError('@runtime_checkable can be only applied to protocol classes,' + ' got %r' % cls) + cls._is_runtime_protocol = True + + # Only execute the following block if it's a typing_extensions.Protocol class. + # typing.Protocol classes don't need it. + if isinstance(cls, _ProtocolMeta): + # PEP 544 prohibits using issubclass() + # with protocols that have non-method members. + # See gh-113320 for why we compute this attribute here, + # rather than in `_ProtocolMeta.__init__` + cls.__non_callable_proto_members__ = set() + for attr in cls.__protocol_attrs__: + try: + is_callable = callable(getattr(cls, attr, None)) + except Exception as e: + raise TypeError( + f"Failed to determine whether protocol member {attr!r} " + "is a method member" + ) from e + else: + if not is_callable: + cls.__non_callable_proto_members__.add(attr) + + return cls + + # The "runtime" alias exists for backwards compatibility. -runtime = runtime_checkable = typing.runtime_checkable +runtime = runtime_checkable # Our version of runtime-checkable protocols is faster on Python 3.8-3.11 @@ -815,7 +875,7 @@ else: break class _TypedDictMeta(type): - def __new__(cls, name, bases, ns, *, total=True): + def __new__(cls, name, bases, ns, *, total=True, closed=False): """Create new typed dict class object. This method is called when TypedDict is subclassed, @@ -860,6 +920,7 @@ else: optional_keys = set() readonly_keys = set() mutable_keys = set() + extra_items_type = None for base in bases: base_dict = base.__dict__ @@ -869,6 +930,26 @@ else: optional_keys.update(base_dict.get('__optional_keys__', ())) readonly_keys.update(base_dict.get('__readonly_keys__', ())) mutable_keys.update(base_dict.get('__mutable_keys__', ())) + base_extra_items_type = base_dict.get('__extra_items__', None) + if base_extra_items_type is not None: + extra_items_type = base_extra_items_type + + if closed and extra_items_type is None: + extra_items_type = Never + if closed and "__extra_items__" in own_annotations: + annotation_type = own_annotations.pop("__extra_items__") + qualifiers = set(_get_typeddict_qualifiers(annotation_type)) + if Required in qualifiers: + raise TypeError( + "Special key __extra_items__ does not support " + "Required" + ) + if NotRequired in qualifiers: + raise TypeError( + "Special key __extra_items__ does not support " + "NotRequired" + ) + extra_items_type = annotation_type annotations.update(own_annotations) for annotation_key, annotation_type in own_annotations.items(): @@ -883,11 +964,7 @@ else: else: optional_keys.add(annotation_key) if ReadOnly in qualifiers: - if annotation_key in mutable_keys: - raise TypeError( - f"Cannot override mutable key {annotation_key!r}" - " with read-only key" - ) + mutable_keys.discard(annotation_key) readonly_keys.add(annotation_key) else: mutable_keys.add(annotation_key) @@ -900,6 +977,8 @@ else: tp_dict.__mutable_keys__ = frozenset(mutable_keys) if not hasattr(tp_dict, '__total__'): tp_dict.__total__ = total + tp_dict.__closed__ = closed + tp_dict.__extra_items__ = extra_items_type return tp_dict __call__ = dict # static method @@ -913,7 +992,7 @@ else: _TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {}) @_ensure_subclassable(lambda bases: (_TypedDict,)) - def TypedDict(typename, fields=_marker, /, *, total=True, **kwargs): + def TypedDict(typename, fields=_marker, /, *, total=True, closed=False, **kwargs): """A simple typed namespace. At runtime it is equivalent to a plain dict. TypedDict creates a dictionary type such that a type checker will expect all @@ -973,6 +1052,9 @@ else: "using the functional syntax, pass an empty dictionary, e.g. " ) + example + "." warnings.warn(deprecation_msg, DeprecationWarning, stacklevel=2) + if closed is not False and closed is not True: + kwargs["closed"] = closed + closed = False fields = kwargs elif kwargs: raise TypeError("TypedDict takes either a dict or keyword arguments," @@ -994,7 +1076,7 @@ else: # Setting correct module is necessary to make typed dict classes pickleable. ns['__module__'] = module - td = _TypedDictMeta(typename, (), ns, total=total) + td = _TypedDictMeta(typename, (), ns, total=total, closed=closed) td.__orig_bases__ = (TypedDict,) return td @@ -1768,6 +1850,98 @@ else: PEP 647 (User-Defined Type Guards). """) +# 3.13+ +if hasattr(typing, 'TypeIs'): + TypeIs = typing.TypeIs +# 3.9 +elif sys.version_info[:2] >= (3, 9): + @_ExtensionsSpecialForm + def TypeIs(self, parameters): + """Special typing form used to annotate the return type of a user-defined + type narrower function. ``TypeIs`` only accepts a single type argument. + At runtime, functions marked this way should return a boolean. + + ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static + type checkers to determine a more precise type of an expression within a + program's code flow. Usually type narrowing is done by analyzing + conditional code flow and applying the narrowing to a block of code. The + conditional expression here is sometimes referred to as a "type guard". + + Sometimes it would be convenient to use a user-defined boolean function + as a type guard. Such a function should use ``TypeIs[...]`` as its + return type to alert static type checkers to this intention. + + Using ``-> TypeIs`` tells the static type checker that for a given + function: + + 1. The return value is a boolean. + 2. If the return value is ``True``, the type of its argument + is the intersection of the type inside ``TypeGuard`` and the argument's + previously known type. + + For example:: + + def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]: + return hasattr(val, '__await__') + + def f(val: Union[int, Awaitable[int]]) -> int: + if is_awaitable(val): + assert_type(val, Awaitable[int]) + else: + assert_type(val, int) + + ``TypeIs`` also works with type variables. For more information, see + PEP 742 (Narrowing types with TypeIs). + """ + item = typing._type_check(parameters, f'{self} accepts only a single type.') + return typing._GenericAlias(self, (item,)) +# 3.8 +else: + class _TypeIsForm(_ExtensionsSpecialForm, _root=True): + def __getitem__(self, parameters): + item = typing._type_check(parameters, + f'{self._name} accepts only a single type') + return typing._GenericAlias(self, (item,)) + + TypeIs = _TypeIsForm( + 'TypeIs', + doc="""Special typing form used to annotate the return type of a user-defined + type narrower function. ``TypeIs`` only accepts a single type argument. + At runtime, functions marked this way should return a boolean. + + ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static + type checkers to determine a more precise type of an expression within a + program's code flow. Usually type narrowing is done by analyzing + conditional code flow and applying the narrowing to a block of code. The + conditional expression here is sometimes referred to as a "type guard". + + Sometimes it would be convenient to use a user-defined boolean function + as a type guard. Such a function should use ``TypeIs[...]`` as its + return type to alert static type checkers to this intention. + + Using ``-> TypeIs`` tells the static type checker that for a given + function: + + 1. The return value is a boolean. + 2. If the return value is ``True``, the type of its argument + is the intersection of the type inside ``TypeGuard`` and the argument's + previously known type. + + For example:: + + def is_awaitable(val: object) -> TypeIs[Awaitable[Any]]: + return hasattr(val, '__await__') + + def f(val: Union[int, Awaitable[int]]) -> int: + if is_awaitable(val): + assert_type(val, Awaitable[int]) + else: + assert_type(val, int) + + ``TypeIs`` also works with type variables. For more information, see + PEP 742 (Narrowing types with TypeIs). + """) + # Vendored from cpython typing._SpecialFrom class _SpecialForm(typing._Final, _root=True): diff --git a/contrib/python/typing-extensions/py3/ya.make b/contrib/python/typing-extensions/py3/ya.make index 1e65722a16d..6a099000e49 100644 --- a/contrib/python/typing-extensions/py3/ya.make +++ b/contrib/python/typing-extensions/py3/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(4.9.0) +VERSION(4.10.0) LICENSE(PSF-2.0) |
