diff options
Diffstat (limited to 'Lib')
86 files changed, 587 insertions, 974 deletions
diff --git a/Lib/_bootlocale.py b/Lib/_bootlocale.py index 4bccac1139..0c61b0d3a0 100644 --- a/Lib/_bootlocale.py +++ b/Lib/_bootlocale.py @@ -14,11 +14,17 @@ else: try: _locale.CODESET except AttributeError: - def getpreferredencoding(do_setlocale=True): - # This path for legacy systems needs the more complex - # getdefaultlocale() function, import the full locale module. - import locale - return locale.getpreferredencoding(do_setlocale) + if hasattr(sys, 'getandroidapilevel'): + # On Android langinfo.h and CODESET are missing, and UTF-8 is + # always used in mbstowcs() and wcstombs(). + def getpreferredencoding(do_setlocale=True): + return 'UTF-8' + else: + def getpreferredencoding(do_setlocale=True): + # This path for legacy systems needs the more complex + # getdefaultlocale() function, import the full locale module. + import locale + return locale.getpreferredencoding(do_setlocale) else: def getpreferredencoding(do_setlocale=True): assert not do_setlocale diff --git a/Lib/_pyio.py b/Lib/_pyio.py index 2ebfb0576f..8f9397660b 100644 --- a/Lib/_pyio.py +++ b/Lib/_pyio.py @@ -635,7 +635,7 @@ class BufferedIOBase(IOBase): implementation, but wrap one. """ - def read(self, size=None): + def read(self, size=-1): """Read and return up to size bytes, where size is an int. If the argument is omitted, None, or negative, reads and @@ -655,7 +655,7 @@ class BufferedIOBase(IOBase): """ self._unsupported("read") - def read1(self, size=None): + def read1(self, size=-1): """Read up to size bytes with at most one read() system call, where size is an int. """ @@ -863,7 +863,7 @@ class BytesIO(BufferedIOBase): self._buffer.clear() super().close() - def read(self, size=None): + def read(self, size=-1): if self.closed: raise ValueError("read from closed file") if size is None: @@ -877,7 +877,7 @@ class BytesIO(BufferedIOBase): self._pos = newpos return bytes(b) - def read1(self, size): + def read1(self, size=-1): """This is the same as read. """ return self.read(size) @@ -1073,12 +1073,12 @@ class BufferedReader(_BufferedIOMixin): self._read_pos = 0 return self._read_buf[self._read_pos:] - def read1(self, size): + def read1(self, size=-1): """Reads up to size bytes, with at most one read() system call.""" # Returns up to size bytes. If at least one byte is buffered, we # only return buffered bytes. Otherwise, we do one raw read. if size < 0: - raise ValueError("number of bytes to read must be positive") + size = self.buffer_size if size == 0: return b"" with self._read_lock: @@ -1270,7 +1270,7 @@ class BufferedRWPair(BufferedIOBase): self.reader = BufferedReader(reader, buffer_size) self.writer = BufferedWriter(writer, buffer_size) - def read(self, size=None): + def read(self, size=-1): if size is None: size = -1 return self.reader.read(size) @@ -1284,7 +1284,7 @@ class BufferedRWPair(BufferedIOBase): def peek(self, size=0): return self.reader.peek(size) - def read1(self, size): + def read1(self, size=-1): return self.reader.read1(size) def readinto1(self, b): @@ -1370,7 +1370,7 @@ class BufferedRandom(BufferedWriter, BufferedReader): self.flush() return BufferedReader.peek(self, size) - def read1(self, size): + def read1(self, size=-1): self.flush() return BufferedReader.read1(self, size) diff --git a/Lib/asyncio/base_events.py b/Lib/asyncio/base_events.py index 0df58c5f87..ee34996c8a 100644 --- a/Lib/asyncio/base_events.py +++ b/Lib/asyncio/base_events.py @@ -16,7 +16,6 @@ to modify the meaning of the API call itself. import collections import concurrent.futures import heapq -import inspect import itertools import logging import os diff --git a/Lib/bisect.py b/Lib/bisect.py index 4a4d05255e..7732c639e3 100644 --- a/Lib/bisect.py +++ b/Lib/bisect.py @@ -19,8 +19,6 @@ def insort_right(a, x, lo=0, hi=None): else: lo = mid+1 a.insert(lo, x) -insort = insort_right # backward compatibility - def bisect_right(a, x, lo=0, hi=None): """Return the index where to insert item x in list a, assuming a is sorted. @@ -42,8 +40,6 @@ def bisect_right(a, x, lo=0, hi=None): else: lo = mid+1 return lo -bisect = bisect_right # backward compatibility - def insort_left(a, x, lo=0, hi=None): """Insert item x in list a, and keep it sorted assuming a is sorted. @@ -90,3 +86,7 @@ try: from _bisect import * except ImportError: pass + +# Create aliases +bisect = bisect_right +insort = insort_right diff --git a/Lib/calendar.py b/Lib/calendar.py index 07594f3a83..28ac56fdbe 100644 --- a/Lib/calendar.py +++ b/Lib/calendar.py @@ -267,7 +267,7 @@ class TextCalendar(Calendar): """ Print a single week (no newline). """ - print(self.formatweek(theweek, width), end=' ') + print(self.formatweek(theweek, width), end='') def formatday(self, day, weekday, width): """ @@ -371,7 +371,7 @@ class TextCalendar(Calendar): def pryear(self, theyear, w=0, l=0, c=6, m=3): """Print a year's calendar.""" - print(self.formatyear(theyear, w, l, c, m)) + print(self.formatyear(theyear, w, l, c, m), end='') class HTMLCalendar(Calendar): diff --git a/Lib/ctypes/util.py b/Lib/ctypes/util.py index 339ae8aa8a..8856f6594c 100644 --- a/Lib/ctypes/util.py +++ b/Lib/ctypes/util.py @@ -318,10 +318,6 @@ def test(): print(find_library("c")) print(find_library("bz2")) - # getattr -## print cdll.m -## print cdll.bz2 - # load if sys.platform == "darwin": print(cdll.LoadLibrary("libm.dylib")) diff --git a/Lib/dbm/dumb.py b/Lib/dbm/dumb.py index 2296dbfd54..c3c4a66601 100644 --- a/Lib/dbm/dumb.py +++ b/Lib/dbm/dumb.py @@ -68,7 +68,7 @@ class _Database(collections.MutableMapping): # Handle the creation self._create(flag) - self._update() + self._update(flag) def _create(self, flag): if flag == 'n': @@ -92,12 +92,17 @@ class _Database(collections.MutableMapping): f.close() # Read directory file into the in-memory index dict. - def _update(self): + def _update(self, flag): self._index = {} try: f = _io.open(self._dirfile, 'r', encoding="Latin-1") except OSError: self._modified = not self._readonly + if flag not in ('c', 'n'): + import warnings + warnings.warn("The index file is missing, the " + "semantics of the 'c' flag will be used.", + DeprecationWarning, stacklevel=4) else: self._modified = False with f: diff --git a/Lib/distutils/command/build_ext.py b/Lib/distutils/command/build_ext.py index 74de782d8a..9155626a47 100644 --- a/Lib/distutils/command/build_ext.py +++ b/Lib/distutils/command/build_ext.py @@ -715,13 +715,6 @@ class build_ext(Command): return ext.libraries + [pythonlib] else: return ext.libraries - elif sys.platform[:6] == "cygwin": - template = "python%d.%d" - pythonlib = (template % - (sys.hexversion >> 24, (sys.hexversion >> 16) & 0xff)) - # don't extend ext.libraries, it may be shared with other - # extensions, it is a reference to the original list - return ext.libraries + [pythonlib] elif sys.platform[:6] == "atheos": from distutils import sysconfig diff --git a/Lib/distutils/command/sdist.py b/Lib/distutils/command/sdist.py index 4fd1d4715d..180e28626d 100644 --- a/Lib/distutils/command/sdist.py +++ b/Lib/distutils/command/sdist.py @@ -4,17 +4,19 @@ Implements the Distutils 'sdist' command (create a source distribution).""" import os import sys -from types import * from glob import glob from warnings import warn from distutils.core import Command -from distutils import dir_util, dep_util, file_util, archive_util +from distutils import dir_util +from distutils import file_util +from distutils import archive_util from distutils.text_file import TextFile -from distutils.errors import * from distutils.filelist import FileList from distutils import log from distutils.util import convert_path +from distutils.errors import DistutilsTemplateError, DistutilsOptionError + def show_formats(): """Print all possible values for the 'formats' option (used by @@ -30,6 +32,7 @@ def show_formats(): FancyGetopt(formats).print_help( "List of available source distribution formats:") + class sdist(Command): description = "create a source distribution (tarball, zip file, etc.)" @@ -93,6 +96,8 @@ class sdist(Command): sub_commands = [('check', checking_metadata)] + READMES = 'README', 'README.txt' + def initialize_options(self): # 'template' and 'manifest' are, respectively, the names of # the manifest template and manifest file. @@ -216,13 +221,39 @@ class sdist(Command): Warns if (README or README.txt) or setup.py are missing; everything else is optional. """ - standards = [('README', 'README.txt'), self.distribution.script_name] + self._add_defaults_standards() + self._add_defaults_optional() + self._add_defaults_python() + self._add_defaults_data_files() + self._add_defaults_ext() + self._add_defaults_c_libs() + self._add_defaults_scripts() + + @staticmethod + def _cs_path_exists(fspath): + """ + Case-sensitive path existence check + + >>> sdist._cs_path_exists(__file__) + True + >>> sdist._cs_path_exists(__file__.upper()) + False + """ + if not os.path.exists(fspath): + return False + # make absolute so we always have a directory + abspath = os.path.abspath(fspath) + directory, filename = os.path.split(abspath) + return filename in os.listdir(directory) + + def _add_defaults_standards(self): + standards = [self.READMES, self.distribution.script_name] for fn in standards: if isinstance(fn, tuple): alts = fn got_it = False for fn in alts: - if os.path.exists(fn): + if self._cs_path_exists(fn): got_it = True self.filelist.append(fn) break @@ -231,16 +262,18 @@ class sdist(Command): self.warn("standard file not found: should have one of " + ', '.join(alts)) else: - if os.path.exists(fn): + if self._cs_path_exists(fn): self.filelist.append(fn) else: self.warn("standard file '%s' not found" % fn) + def _add_defaults_optional(self): optional = ['test/test*.py', 'setup.cfg'] for pattern in optional: files = filter(os.path.isfile, glob(pattern)) self.filelist.extend(files) + def _add_defaults_python(self): # build_py is used to get: # - python modules # - files defined in package_data @@ -256,28 +289,34 @@ class sdist(Command): for filename in filenames: self.filelist.append(os.path.join(src_dir, filename)) + def _add_defaults_data_files(self): # getting distribution.data_files if self.distribution.has_data_files(): for item in self.distribution.data_files: - if isinstance(item, str): # plain file + if isinstance(item, str): + # plain file item = convert_path(item) if os.path.isfile(item): self.filelist.append(item) - else: # a (dirname, filenames) tuple + else: + # a (dirname, filenames) tuple dirname, filenames = item for f in filenames: f = convert_path(f) if os.path.isfile(f): self.filelist.append(f) + def _add_defaults_ext(self): if self.distribution.has_ext_modules(): build_ext = self.get_finalized_command('build_ext') self.filelist.extend(build_ext.get_source_files()) + def _add_defaults_c_libs(self): if self.distribution.has_c_libraries(): build_clib = self.get_finalized_command('build_clib') self.filelist.extend(build_clib.get_source_files()) + def _add_defaults_scripts(self): if self.distribution.has_scripts(): build_scripts = self.get_finalized_command('build_scripts') self.filelist.extend(build_scripts.get_source_files()) diff --git a/Lib/functools.py b/Lib/functools.py index 45e5f87ede..b278bc20eb 100644 --- a/Lib/functools.py +++ b/Lib/functools.py @@ -493,6 +493,7 @@ def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo): hits = misses = 0 full = False cache_get = cache.get # bound method to lookup a key or return None + cache_len = cache.__len__ # get cache size without calling len() lock = RLock() # because linkedlist updates aren't threadsafe root = [] # root of the circular doubly linked list root[:] = [root, root, None, None] # initialize by pointing to self @@ -574,16 +575,16 @@ def _lru_cache_wrapper(user_function, maxsize, typed, _CacheInfo): last = root[PREV] link = [last, root, key, result] last[NEXT] = root[PREV] = cache[key] = link - # Use the __len__() method instead of the len() function + # Use the cache_len bound method instead of the len() function # which could potentially be wrapped in an lru_cache itself. - full = (cache.__len__() >= maxsize) + full = (cache_len() >= maxsize) misses += 1 return result def cache_info(): """Report cache statistics""" with lock: - return _CacheInfo(hits, misses, maxsize, cache.__len__()) + return _CacheInfo(hits, misses, maxsize, cache_len()) def cache_clear(): """Clear the cache and cache statistics""" diff --git a/Lib/http/client.py b/Lib/http/client.py index a8e59b9561..0234199dfa 100644 --- a/Lib/http/client.py +++ b/Lib/http/client.py @@ -72,7 +72,6 @@ import email.parser import email.message import http import io -import os import re import socket import collections @@ -642,14 +641,7 @@ class HTTPResponse(io.BufferedIOBase): return self._read1_chunked(n) if self.length is not None and (n < 0 or n > self.length): n = self.length - try: - result = self.fp.read1(n) - except ValueError: - if n >= 0: - raise - # some implementations, like BufferedReader, don't support -1 - # Read an arbitrarily selected largeish chunk. - result = self.fp.read1(16*1024) + result = self.fp.read1(n) if not result and n: self._close_conn() elif self.length is not None: diff --git a/Lib/http/server.py b/Lib/http/server.py index e12e45bfc3..61ddecc7ef 100644 --- a/Lib/http/server.py +++ b/Lib/http/server.py @@ -267,8 +267,8 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): are in self.command, self.path, self.request_version and self.headers. - Return True for success, False for failure; on failure, an - error is sent back. + Return True for success, False for failure; on failure, any relevant + error response has already been sent back. """ self.command = None # set in case of error on the first line @@ -278,10 +278,13 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): requestline = requestline.rstrip('\r\n') self.requestline = requestline words = requestline.split() - if len(words) == 3: - command, path, version = words + if len(words) == 0: + return False + + if len(words) >= 3: # Enough to determine protocol version + version = words[-1] try: - if version[:5] != 'HTTP/': + if not version.startswith('HTTP/'): raise ValueError base_version_number = version.split('/', 1)[1] version_number = base_version_number.split(".") @@ -306,22 +309,22 @@ class BaseHTTPRequestHandler(socketserver.StreamRequestHandler): HTTPStatus.HTTP_VERSION_NOT_SUPPORTED, "Invalid HTTP version (%s)" % base_version_number) return False - elif len(words) == 2: - command, path = words + self.request_version = version + + if not 2 <= len(words) <= 3: + self.send_error( + HTTPStatus.BAD_REQUEST, + "Bad request syntax (%r)" % requestline) + return False + command, path = words[:2] + if len(words) == 2: self.close_connection = True if command != 'GET': self.send_error( HTTPStatus.BAD_REQUEST, "Bad HTTP/0.9 request type (%r)" % command) return False - elif not words: - return False - else: - self.send_error( - HTTPStatus.BAD_REQUEST, - "Bad request syntax (%r)" % requestline) - return False - self.command, self.path, self.request_version = command, path, version + self.command, self.path = command, path # Examine the headers and look for a Connection directive. try: diff --git a/Lib/idlelib/idle_test/test_macosx.py b/Lib/idlelib/idle_test/test_macosx.py index fae75d8a49..775697b278 100644 --- a/Lib/idlelib/idle_test/test_macosx.py +++ b/Lib/idlelib/idle_test/test_macosx.py @@ -4,7 +4,6 @@ Coverage: 71% on Windows. ''' from idlelib import macosx from test.support import requires -import sys import tkinter as tk import unittest import unittest.mock as mock diff --git a/Lib/idlelib/idle_test/test_tree.py b/Lib/idlelib/idle_test/test_tree.py index 09ba9641af..bb597d87ff 100644 --- a/Lib/idlelib/idle_test/test_tree.py +++ b/Lib/idlelib/idle_test/test_tree.py @@ -5,7 +5,6 @@ Coverage: 56% from idlelib import tree from test.support import requires requires('gui') -import os import unittest from tkinter import Tk diff --git a/Lib/idlelib/macosx.py b/Lib/idlelib/macosx.py index c225dd9e1a..d4566cd815 100644 --- a/Lib/idlelib/macosx.py +++ b/Lib/idlelib/macosx.py @@ -2,7 +2,6 @@ A number of functions that enhance IDLE on Mac OSX. """ from sys import platform # Used in _init_tk_type, changed by test. -import warnings import tkinter diff --git a/Lib/idlelib/stackviewer.py b/Lib/idlelib/stackviewer.py index 0698def5d4..400fa632a0 100644 --- a/Lib/idlelib/stackviewer.py +++ b/Lib/idlelib/stackviewer.py @@ -1,6 +1,5 @@ import linecache import os -import re import sys import tkinter as tk diff --git a/Lib/importlib/_bootstrap_external.py b/Lib/importlib/_bootstrap_external.py index 9feec50842..ec528b2f0d 100644 --- a/Lib/importlib/_bootstrap_external.py +++ b/Lib/importlib/_bootstrap_external.py @@ -240,6 +240,7 @@ _code_type = type(_write_atomic.__code__) # Python 3.6b1 3377 (set __class__ cell from type.__new__ #23722) # Python 3.6b2 3378 (add BUILD_TUPLE_UNPACK_WITH_CALL #28257) # Python 3.6rc1 3379 (more thorough __class__ validation #23722) +# Python 3.7a0 3390 (add LOAD_METHOD and CALL_METHOD opcodes) # # MAGIC must change whenever the bytecode emitted by the compiler may no # longer be understood by older implementations of the eval loop (usually @@ -248,7 +249,7 @@ _code_type = type(_write_atomic.__code__) # Whenever MAGIC_NUMBER is changed, the ranges in the magic_values array # in PC/launcher.c must also be updated. -MAGIC_NUMBER = (3379).to_bytes(2, 'little') + b'\r\n' +MAGIC_NUMBER = (3390).to_bytes(2, 'little') + b'\r\n' _RAW_MAGIC_NUMBER = int.from_bytes(MAGIC_NUMBER, 'little') # For import.c _PYCACHE = '__pycache__' diff --git a/Lib/lib2to3/pytree.py b/Lib/lib2to3/pytree.py index ad3592c05f..c425fe6827 100644 --- a/Lib/lib2to3/pytree.py +++ b/Lib/lib2to3/pytree.py @@ -13,7 +13,6 @@ There's also a pattern matching implementation here. __author__ = "Guido van Rossum <guido@python.org>" import sys -import warnings from io import StringIO HUGE = 0x7FFFFFFF # maximum repeat count, default max diff --git a/Lib/lib2to3/tests/__init__.py b/Lib/lib2to3/tests/__init__.py index c5166fc94c..54221c7994 100644 --- a/Lib/lib2to3/tests/__init__.py +++ b/Lib/lib2to3/tests/__init__.py @@ -1,7 +1,6 @@ # Author: Collin Winter import os -import unittest from test.support import load_package_tests diff --git a/Lib/locale.py b/Lib/locale.py index 4de0090ed9..f8d1d78c36 100644 --- a/Lib/locale.py +++ b/Lib/locale.py @@ -618,15 +618,21 @@ else: try: CODESET except NameError: - # Fall back to parsing environment variables :-( - def getpreferredencoding(do_setlocale = True): - """Return the charset that the user is likely using, - by looking at environment variables.""" - res = getdefaultlocale()[1] - if res is None: - # LANG not set, default conservatively to ASCII - res = 'ascii' - return res + if hasattr(sys, 'getandroidapilevel'): + # On Android langinfo.h and CODESET are missing, and UTF-8 is + # always used in mbstowcs() and wcstombs(). + def getpreferredencoding(do_setlocale = True): + return 'UTF-8' + else: + # Fall back to parsing environment variables :-( + def getpreferredencoding(do_setlocale = True): + """Return the charset that the user is likely using, + by looking at environment variables.""" + res = getdefaultlocale()[1] + if res is None: + # LANG not set, default conservatively to ASCII + res = 'ascii' + return res else: def getpreferredencoding(do_setlocale = True): """Return the charset that the user is likely using, diff --git a/Lib/logging/config.py b/Lib/logging/config.py index 8a99923bf3..917178e511 100644 --- a/Lib/logging/config.py +++ b/Lib/logging/config.py @@ -1,4 +1,4 @@ -# Copyright 2001-2014 by Vinay Sajip. All Rights Reserved. +# Copyright 2001-2016 by Vinay Sajip. All Rights Reserved. # # Permission to use, copy, modify, and distribute this software and its # documentation for any purpose and without fee is hereby granted, @@ -19,7 +19,7 @@ Configuration functions for the logging package for Python. The core package is based on PEP 282 and comments thereto in comp.lang.python, and influenced by Apache's log4j system. -Copyright (C) 2001-2014 Vinay Sajip. All Rights Reserved. +Copyright (C) 2001-2016 Vinay Sajip. All Rights Reserved. To use, simply 'import logging' and log away! """ @@ -509,21 +509,21 @@ class DictConfigurator(BaseConfigurator): handler.setLevel(logging._checkLevel(level)) except Exception as e: raise ValueError('Unable to configure handler ' - '%r: %s' % (name, e)) + '%r' % name) from e loggers = config.get('loggers', EMPTY_DICT) for name in loggers: try: self.configure_logger(name, loggers[name], True) except Exception as e: raise ValueError('Unable to configure logger ' - '%r: %s' % (name, e)) + '%r' % name) from e root = config.get('root', None) if root: try: self.configure_root(root, True) except Exception as e: raise ValueError('Unable to configure root ' - 'logger: %s' % e) + 'logger') from e else: disable_existing = config.pop('disable_existing_loggers', True) @@ -538,7 +538,7 @@ class DictConfigurator(BaseConfigurator): formatters[name]) except Exception as e: raise ValueError('Unable to configure ' - 'formatter %r: %s' % (name, e)) + 'formatter %r' % name) from e # Next, do filters - they don't refer to anything else, either filters = config.get('filters', EMPTY_DICT) for name in filters: @@ -546,7 +546,7 @@ class DictConfigurator(BaseConfigurator): filters[name] = self.configure_filter(filters[name]) except Exception as e: raise ValueError('Unable to configure ' - 'filter %r: %s' % (name, e)) + 'filter %r' % name) from e # Next, do handlers - they refer to formatters and filters # As handlers can refer to other handlers, sort the keys @@ -559,11 +559,11 @@ class DictConfigurator(BaseConfigurator): handler.name = name handlers[name] = handler except Exception as e: - if 'target not configured yet' in str(e): + if 'target not configured yet' in str(e.__cause__): deferred.append(name) else: raise ValueError('Unable to configure handler ' - '%r: %s' % (name, e)) + '%r' % name) from e # Now do any that were deferred for name in deferred: @@ -573,7 +573,7 @@ class DictConfigurator(BaseConfigurator): handlers[name] = handler except Exception as e: raise ValueError('Unable to configure handler ' - '%r: %s' % (name, e)) + '%r' % name) from e # Next, do loggers - they refer to handlers and filters @@ -612,7 +612,7 @@ class DictConfigurator(BaseConfigurator): self.configure_logger(name, loggers[name]) except Exception as e: raise ValueError('Unable to configure logger ' - '%r: %s' % (name, e)) + '%r' % name) from e #Disable any old loggers. There's no point deleting #them as other threads may continue to hold references @@ -637,7 +637,7 @@ class DictConfigurator(BaseConfigurator): self.configure_root(root) except Exception as e: raise ValueError('Unable to configure root ' - 'logger: %s' % e) + 'logger') from e finally: logging._releaseLock() @@ -684,7 +684,7 @@ class DictConfigurator(BaseConfigurator): try: filterer.addFilter(self.config['filters'][f]) except Exception as e: - raise ValueError('Unable to add filter %r: %s' % (f, e)) + raise ValueError('Unable to add filter %r' % f) from e def configure_handler(self, config): """Configure a handler from a dictionary.""" @@ -695,7 +695,7 @@ class DictConfigurator(BaseConfigurator): formatter = self.config['formatters'][formatter] except Exception as e: raise ValueError('Unable to set formatter ' - '%r: %s' % (formatter, e)) + '%r' % formatter) from e level = config.pop('level', None) filters = config.pop('filters', None) if '()' in config: @@ -717,7 +717,7 @@ class DictConfigurator(BaseConfigurator): config['target'] = th except Exception as e: raise ValueError('Unable to set target handler ' - '%r: %s' % (config['target'], e)) + '%r' % config['target']) from e elif issubclass(klass, logging.handlers.SMTPHandler) and\ 'mailhost' in config: config['mailhost'] = self.as_tuple(config['mailhost']) @@ -755,7 +755,7 @@ class DictConfigurator(BaseConfigurator): try: logger.addHandler(self.config['handlers'][h]) except Exception as e: - raise ValueError('Unable to add handler %r: %s' % (h, e)) + raise ValueError('Unable to add handler %r' % h) from e def common_logger_config(self, logger, config, incremental=False): """ diff --git a/Lib/macurl2path.py b/Lib/macurl2path.py deleted file mode 100644 index a68821d0b7..0000000000 --- a/Lib/macurl2path.py +++ /dev/null @@ -1,77 +0,0 @@ -"""Macintosh-specific module for conversion between pathnames and URLs. - -Do not import directly; use urllib instead.""" - -import urllib.parse -import os - -__all__ = ["url2pathname","pathname2url"] - -def url2pathname(pathname): - """OS-specific conversion from a relative URL of the 'file' scheme - to a file system path; not recommended for general use.""" - # - # XXXX The .. handling should be fixed... - # - tp = urllib.parse.splittype(pathname)[0] - if tp and tp != 'file': - raise RuntimeError('Cannot convert non-local URL to pathname') - # Turn starting /// into /, an empty hostname means current host - if pathname[:3] == '///': - pathname = pathname[2:] - elif pathname[:2] == '//': - raise RuntimeError('Cannot convert non-local URL to pathname') - components = pathname.split('/') - # Remove . and embedded .. - i = 0 - while i < len(components): - if components[i] == '.': - del components[i] - elif components[i] == '..' and i > 0 and \ - components[i-1] not in ('', '..'): - del components[i-1:i+1] - i = i-1 - elif components[i] == '' and i > 0 and components[i-1] != '': - del components[i] - else: - i = i+1 - if not components[0]: - # Absolute unix path, don't start with colon - rv = ':'.join(components[1:]) - else: - # relative unix path, start with colon. First replace - # leading .. by empty strings (giving ::file) - i = 0 - while i < len(components) and components[i] == '..': - components[i] = '' - i = i + 1 - rv = ':' + ':'.join(components) - # and finally unquote slashes and other funny characters - return urllib.parse.unquote(rv) - -def pathname2url(pathname): - """OS-specific conversion from a file system path to a relative URL - of the 'file' scheme; not recommended for general use.""" - if '/' in pathname: - raise RuntimeError("Cannot convert pathname containing slashes") - components = pathname.split(':') - # Remove empty first and/or last component - if components[0] == '': - del components[0] - if components[-1] == '': - del components[-1] - # Replace empty string ('::') by .. (will result in '/../' later) - for i in range(len(components)): - if components[i] == '': - components[i] = '..' - # Truncate names longer than 31 bytes - components = map(_pncomp2url, components) - - if os.path.isabs(pathname): - return '/' + '/'.join(components) - else: - return '/'.join(components) - -def _pncomp2url(component): - # We want to quote slashes - return urllib.parse.quote(component[:31], safe='') diff --git a/Lib/modulefinder.py b/Lib/modulefinder.py index e220315253..e277ca72f8 100644 --- a/Lib/modulefinder.py +++ b/Lib/modulefinder.py @@ -7,7 +7,6 @@ import marshal import os import sys import types -import struct import warnings with warnings.catch_warnings(): warnings.simplefilter('ignore', DeprecationWarning) diff --git a/Lib/opcode.py b/Lib/opcode.py index b5916b6619..dffb38c314 100644 --- a/Lib/opcode.py +++ b/Lib/opcode.py @@ -212,4 +212,7 @@ def_op('BUILD_CONST_KEY_MAP', 156) def_op('BUILD_STRING', 157) def_op('BUILD_TUPLE_UNPACK_WITH_CALL', 158) +name_op('LOAD_METHOD', 160) +def_op('CALL_METHOD', 161) + del def_op, name_op, jrel_op, jabs_op diff --git a/Lib/pydoc_data/topics.py b/Lib/pydoc_data/topics.py index c7fac3395b..3579484fd0 100644 --- a/Lib/pydoc_data/topics.py +++ b/Lib/pydoc_data/topics.py @@ -1,5 +1,5 @@ # -*- coding: utf-8 -*- -# Autogenerated by Sphinx on Tue Dec 6 18:51:51 2016 +# Autogenerated by Sphinx on Mon Sep 12 10:47:11 2016 topics = {'assert': '\n' 'The "assert" statement\n' '**********************\n' @@ -3702,7 +3702,7 @@ topics = {'assert': '\n' ' end). This is because any time you resume execution (even ' 'with a\n' ' simple next or step), you may encounter another ' - 'breakpoint—which\n' + 'breakpoint--which\n' ' could have its own command list, leading to ambiguities about ' 'which\n' ' list to execute.\n' @@ -5066,9 +5066,9 @@ topics = {'assert': '\n' 'be formatted\n' 'with the floating point presentation types listed below ' '(except "\'n\'"\n' - 'and "None"). When doing so, "float()" is used to convert ' - 'the integer\n' - 'to a floating point number before formatting.\n' + 'and None). When doing so, "float()" is used to convert the ' + 'integer to\n' + 'a floating point number before formatting.\n' '\n' 'The available presentation types for floating point and ' 'decimal values\n' @@ -8503,10 +8503,9 @@ topics = {'assert': '\n' 'defined at the\n' 'class scope. Class variables must be accessed through the ' 'first\n' - 'parameter of instance or class methods, or through the ' - 'implicit\n' - 'lexically scoped "__class__" reference described in the next ' - 'section.\n' + 'parameter of instance or class methods, and cannot be ' + 'accessed at all\n' + 'from static methods.\n' '\n' '\n' 'Creating the class object\n' @@ -8536,38 +8535,6 @@ topics = {'assert': '\n' 'passed to the\n' 'method.\n' '\n' - '**CPython implementation detail:** In CPython 3.6 and later, ' - 'the\n' - '"__class__" cell is passed to the metaclass as a ' - '"__classcell__" entry\n' - 'in the class namespace. If present, this must be propagated ' - 'up to the\n' - '"type.__new__" call in order for the class to be ' - 'initialised\n' - 'correctly. Failing to do so will result in a ' - '"DeprecationWarning" in\n' - 'Python 3.6, and a "RuntimeWarning" in the future.\n' - '\n' - 'When using the default metaclass "type", or any metaclass ' - 'that\n' - 'ultimately calls "type.__new__", the following additional\n' - 'customisation steps are invoked after creating the class ' - 'object:\n' - '\n' - '* first, "type.__new__" collects all of the descriptors in ' - 'the class\n' - ' namespace that define a "__set_name__()" method;\n' - '\n' - '* second, all of these "__set_name__" methods are called ' - 'with the\n' - ' class being defined and the assigned name of that ' - 'particular\n' - ' descriptor; and\n' - '\n' - '* finally, the "__init_subclass__()" hook is called on the ' - 'immediate\n' - ' parent of the new class in its method resolution order.\n' - '\n' 'After the class object is created, it is passed to the ' 'class\n' 'decorators included in the class definition (if any) and the ' @@ -9659,7 +9626,7 @@ topics = {'assert': '\n' ' Unicode ordinals (integers) or characters (strings of ' 'length 1) to\n' ' Unicode ordinals, strings (of arbitrary lengths) or ' - '"None".\n' + 'None.\n' ' Character keys will then be converted to ordinals.\n' '\n' ' If there are two arguments, they must be strings of ' @@ -9670,7 +9637,7 @@ topics = {'assert': '\n' 'is a third\n' ' argument, it must be a string, whose characters will be ' 'mapped to\n' - ' "None" in the result.\n' + ' None in the result.\n' '\n' 'str.partition(sep)\n' '\n' @@ -11237,7 +11204,7 @@ topics = {'assert': '\n' 'the\n' ' order of their occurrence in the base class list; "__doc__" is ' 'the\n' - ' class\'s documentation string, or "None" if undefined;\n' + " class's documentation string, or None if undefined;\n" ' "__annotations__" (optional) is a dictionary containing ' '*variable\n' ' annotations* collected during class body execution.\n' diff --git a/Lib/socketserver.py b/Lib/socketserver.py index 41a3766772..6e1ae9fddd 100644 --- a/Lib/socketserver.py +++ b/Lib/socketserver.py @@ -126,7 +126,6 @@ __version__ = "0.4" import socket import selectors import os -import errno import sys try: import threading diff --git a/Lib/sre_compile.py b/Lib/sre_compile.py index 420d83de63..2cc39007ac 100644 --- a/Lib/sre_compile.py +++ b/Lib/sre_compile.py @@ -576,5 +576,5 @@ def compile(p, flags=0): return _sre.compile( pattern, flags | p.pattern.flags, code, p.pattern.groups-1, - groupindex, indexgroup + groupindex, tuple(indexgroup) ) diff --git a/Lib/sre_parse.py b/Lib/sre_parse.py index 6aa49c3bf6..ab37fd3fe2 100644 --- a/Lib/sre_parse.py +++ b/Lib/sre_parse.py @@ -947,9 +947,7 @@ def parse_template(source, pattern): this = chr(ESCAPES[this][1]) except KeyError: if c in ASCIILETTERS: - import warnings - warnings.warn('bad escape %s' % this, - DeprecationWarning, stacklevel=4) + raise s.error('bad escape %s' % this, len(this)) lappend(this) else: lappend(this) diff --git a/Lib/subprocess.py b/Lib/subprocess.py index 0b880f68d9..809e59f5eb 100644 --- a/Lib/subprocess.py +++ b/Lib/subprocess.py @@ -1027,15 +1027,9 @@ class Popen(object): return self.returncode - def wait(self, timeout=None, endtime=None): + def wait(self, timeout=None): """Wait for child process to terminate. Returns returncode attribute.""" - if endtime is not None: - warnings.warn( - "'endtime' argument is deprecated; use 'timeout'.", - DeprecationWarning, - stacklevel=2) - timeout = self._remaining_time(endtime) if timeout is None: timeout_millis = _winapi.INFINITE else: @@ -1210,7 +1204,10 @@ class Popen(object): args = list(args) if shell: - args = ["/bin/sh", "-c"] + args + # On Android the default shell is at '/system/bin/sh'. + unix_shell = ('/system/bin/sh' if + hasattr(sys, 'getandroidapilevel') else '/bin/sh') + args = [unix_shell, "-c"] + args if executable: args[0] = executable @@ -1390,24 +1387,14 @@ class Popen(object): return (pid, sts) - def wait(self, timeout=None, endtime=None): + def wait(self, timeout=None): """Wait for child process to terminate. Returns returncode attribute.""" if self.returncode is not None: return self.returncode - if endtime is not None: - warnings.warn( - "'endtime' argument is deprecated; use 'timeout'.", - DeprecationWarning, - stacklevel=2) - if endtime is not None or timeout is not None: - if endtime is None: - endtime = _time() + timeout - elif timeout is None: - timeout = self._remaining_time(endtime) - - if endtime is not None: + if timeout is not None: + endtime = _time() + timeout # Enter a busy loop if we have a timeout. This busy loop was # cribbed from Lib/threading.py in Thread.wait() at r71065. delay = 0.0005 # 500 us -> initial delay of 1 ms diff --git a/Lib/test/libregrtest/main.py b/Lib/test/libregrtest/main.py index f0effc973c..e113ed63dd 100644 --- a/Lib/test/libregrtest/main.py +++ b/Lib/test/libregrtest/main.py @@ -179,19 +179,17 @@ class Regrtest: self.tests = [] # regex to match 'test_builtin' in line: # '0:00:00 [ 4/400] test_builtin -- test_dict took 1 sec' - regex = (r'^(?:[0-9]+:[0-9]+:[0-9]+ *)?' + regex = (r'(?:[0-9]+:[0-9]+:[0-9]+ *)?' r'(?:\[[0-9/ ]+\] *)?' - r'(test_[a-zA-Z0-9_]+)') + r'(test_[a-zA-Z0-9_]+)\b(?:\.py)?') regex = re.compile(regex) with open(os.path.join(support.SAVEDCWD, self.ns.fromfile)) as fp: for line in fp: + line = line.split('#', 1)[0] line = line.strip() - if line.startswith('#'): - continue - match = regex.match(line) - if match is None: - continue - self.tests.append(match.group(1)) + match = regex.search(line) + if match is not None: + self.tests.append(match.group(1)) removepy(self.tests) diff --git a/Lib/test/libregrtest/runtest_mp.py b/Lib/test/libregrtest/runtest_mp.py index 9604c16600..74ac4fa895 100644 --- a/Lib/test/libregrtest/runtest_mp.py +++ b/Lib/test/libregrtest/runtest_mp.py @@ -41,7 +41,7 @@ def run_test_in_subprocess(testname, ns): slaveargs = json.dumps(slaveargs) cmd = [sys.executable, *support.args_from_interpreter_flags(), - '-X', 'faulthandler', + '-u', # Unbuffered stdout and stderr '-m', 'test.regrtest', '--slaveargs', slaveargs] if ns.pgo: diff --git a/Lib/test/pystone.py b/Lib/test/pystone.py deleted file mode 100755 index cf1692ec2d..0000000000 --- a/Lib/test/pystone.py +++ /dev/null @@ -1,277 +0,0 @@ -#! /usr/bin/env python3 - -""" -"PYSTONE" Benchmark Program - -Version: Python/1.2 (corresponds to C/1.1 plus 3 Pystone fixes) - -Author: Reinhold P. Weicker, CACM Vol 27, No 10, 10/84 pg. 1013. - - Translated from ADA to C by Rick Richardson. - Every method to preserve ADA-likeness has been used, - at the expense of C-ness. - - Translated from C to Python by Guido van Rossum. - -Version History: - - Version 1.1 corrects two bugs in version 1.0: - - First, it leaked memory: in Proc1(), NextRecord ends - up having a pointer to itself. I have corrected this - by zapping NextRecord.PtrComp at the end of Proc1(). - - Second, Proc3() used the operator != to compare a - record to None. This is rather inefficient and not - true to the intention of the original benchmark (where - a pointer comparison to None is intended; the != - operator attempts to find a method __cmp__ to do value - comparison of the record). Version 1.1 runs 5-10 - percent faster than version 1.0, so benchmark figures - of different versions can't be compared directly. - - Version 1.2 changes the division to floor division. - - Under Python 3 version 1.1 would use the normal division - operator, resulting in some of the operations mistakenly - yielding floats. Version 1.2 instead uses floor division - making the benchmark an integer benchmark again. - -""" - -LOOPS = 50000 - -from time import time - -__version__ = "1.2" - -[Ident1, Ident2, Ident3, Ident4, Ident5] = range(1, 6) - -class Record: - - def __init__(self, PtrComp = None, Discr = 0, EnumComp = 0, - IntComp = 0, StringComp = 0): - self.PtrComp = PtrComp - self.Discr = Discr - self.EnumComp = EnumComp - self.IntComp = IntComp - self.StringComp = StringComp - - def copy(self): - return Record(self.PtrComp, self.Discr, self.EnumComp, - self.IntComp, self.StringComp) - -TRUE = 1 -FALSE = 0 - -def main(loops=LOOPS): - benchtime, stones = pystones(loops) - print("Pystone(%s) time for %d passes = %g" % \ - (__version__, loops, benchtime)) - print("This machine benchmarks at %g pystones/second" % stones) - - -def pystones(loops=LOOPS): - return Proc0(loops) - -IntGlob = 0 -BoolGlob = FALSE -Char1Glob = '\0' -Char2Glob = '\0' -Array1Glob = [0]*51 -Array2Glob = [x[:] for x in [Array1Glob]*51] -PtrGlb = None -PtrGlbNext = None - -def Proc0(loops=LOOPS): - global IntGlob - global BoolGlob - global Char1Glob - global Char2Glob - global Array1Glob - global Array2Glob - global PtrGlb - global PtrGlbNext - - starttime = time() - for i in range(loops): - pass - nulltime = time() - starttime - - PtrGlbNext = Record() - PtrGlb = Record() - PtrGlb.PtrComp = PtrGlbNext - PtrGlb.Discr = Ident1 - PtrGlb.EnumComp = Ident3 - PtrGlb.IntComp = 40 - PtrGlb.StringComp = "DHRYSTONE PROGRAM, SOME STRING" - String1Loc = "DHRYSTONE PROGRAM, 1'ST STRING" - Array2Glob[8][7] = 10 - - starttime = time() - - for i in range(loops): - Proc5() - Proc4() - IntLoc1 = 2 - IntLoc2 = 3 - String2Loc = "DHRYSTONE PROGRAM, 2'ND STRING" - EnumLoc = Ident2 - BoolGlob = not Func2(String1Loc, String2Loc) - while IntLoc1 < IntLoc2: - IntLoc3 = 5 * IntLoc1 - IntLoc2 - IntLoc3 = Proc7(IntLoc1, IntLoc2) - IntLoc1 = IntLoc1 + 1 - Proc8(Array1Glob, Array2Glob, IntLoc1, IntLoc3) - PtrGlb = Proc1(PtrGlb) - CharIndex = 'A' - while CharIndex <= Char2Glob: - if EnumLoc == Func1(CharIndex, 'C'): - EnumLoc = Proc6(Ident1) - CharIndex = chr(ord(CharIndex)+1) - IntLoc3 = IntLoc2 * IntLoc1 - IntLoc2 = IntLoc3 // IntLoc1 - IntLoc2 = 7 * (IntLoc3 - IntLoc2) - IntLoc1 - IntLoc1 = Proc2(IntLoc1) - - benchtime = time() - starttime - nulltime - if benchtime == 0.0: - loopsPerBenchtime = 0.0 - else: - loopsPerBenchtime = (loops / benchtime) - return benchtime, loopsPerBenchtime - -def Proc1(PtrParIn): - PtrParIn.PtrComp = NextRecord = PtrGlb.copy() - PtrParIn.IntComp = 5 - NextRecord.IntComp = PtrParIn.IntComp - NextRecord.PtrComp = PtrParIn.PtrComp - NextRecord.PtrComp = Proc3(NextRecord.PtrComp) - if NextRecord.Discr == Ident1: - NextRecord.IntComp = 6 - NextRecord.EnumComp = Proc6(PtrParIn.EnumComp) - NextRecord.PtrComp = PtrGlb.PtrComp - NextRecord.IntComp = Proc7(NextRecord.IntComp, 10) - else: - PtrParIn = NextRecord.copy() - NextRecord.PtrComp = None - return PtrParIn - -def Proc2(IntParIO): - IntLoc = IntParIO + 10 - while 1: - if Char1Glob == 'A': - IntLoc = IntLoc - 1 - IntParIO = IntLoc - IntGlob - EnumLoc = Ident1 - if EnumLoc == Ident1: - break - return IntParIO - -def Proc3(PtrParOut): - global IntGlob - - if PtrGlb is not None: - PtrParOut = PtrGlb.PtrComp - else: - IntGlob = 100 - PtrGlb.IntComp = Proc7(10, IntGlob) - return PtrParOut - -def Proc4(): - global Char2Glob - - BoolLoc = Char1Glob == 'A' - BoolLoc = BoolLoc or BoolGlob - Char2Glob = 'B' - -def Proc5(): - global Char1Glob - global BoolGlob - - Char1Glob = 'A' - BoolGlob = FALSE - -def Proc6(EnumParIn): - EnumParOut = EnumParIn - if not Func3(EnumParIn): - EnumParOut = Ident4 - if EnumParIn == Ident1: - EnumParOut = Ident1 - elif EnumParIn == Ident2: - if IntGlob > 100: - EnumParOut = Ident1 - else: - EnumParOut = Ident4 - elif EnumParIn == Ident3: - EnumParOut = Ident2 - elif EnumParIn == Ident4: - pass - elif EnumParIn == Ident5: - EnumParOut = Ident3 - return EnumParOut - -def Proc7(IntParI1, IntParI2): - IntLoc = IntParI1 + 2 - IntParOut = IntParI2 + IntLoc - return IntParOut - -def Proc8(Array1Par, Array2Par, IntParI1, IntParI2): - global IntGlob - - IntLoc = IntParI1 + 5 - Array1Par[IntLoc] = IntParI2 - Array1Par[IntLoc+1] = Array1Par[IntLoc] - Array1Par[IntLoc+30] = IntLoc - for IntIndex in range(IntLoc, IntLoc+2): - Array2Par[IntLoc][IntIndex] = IntLoc - Array2Par[IntLoc][IntLoc-1] = Array2Par[IntLoc][IntLoc-1] + 1 - Array2Par[IntLoc+20][IntLoc] = Array1Par[IntLoc] - IntGlob = 5 - -def Func1(CharPar1, CharPar2): - CharLoc1 = CharPar1 - CharLoc2 = CharLoc1 - if CharLoc2 != CharPar2: - return Ident1 - else: - return Ident2 - -def Func2(StrParI1, StrParI2): - IntLoc = 1 - while IntLoc <= 1: - if Func1(StrParI1[IntLoc], StrParI2[IntLoc+1]) == Ident1: - CharLoc = 'A' - IntLoc = IntLoc + 1 - if CharLoc >= 'W' and CharLoc <= 'Z': - IntLoc = 7 - if CharLoc == 'X': - return TRUE - else: - if StrParI1 > StrParI2: - IntLoc = IntLoc + 7 - return TRUE - else: - return FALSE - -def Func3(EnumParIn): - EnumLoc = EnumParIn - if EnumLoc == Ident3: return TRUE - return FALSE - -if __name__ == '__main__': - import sys - def error(msg): - print(msg, end=' ', file=sys.stderr) - print("usage: %s [number_of_loops]" % sys.argv[0], file=sys.stderr) - sys.exit(100) - nargs = len(sys.argv) - 1 - if nargs > 1: - error("%d arguments are too many;" % nargs) - elif nargs == 1: - try: loops = int(sys.argv[1]) - except ValueError: - error("Invalid argument %r;" % sys.argv[1]) - else: - loops = LOOPS - main(loops) diff --git a/Lib/test/support/__init__.py b/Lib/test/support/__init__.py index 15d8fc849b..345e16d754 100644 --- a/Lib/test/support/__init__.py +++ b/Lib/test/support/__init__.py @@ -777,8 +777,13 @@ requires_lzma = unittest.skipUnless(lzma, 'requires lzma') is_jython = sys.platform.startswith('java') -_ANDROID_API_LEVEL = sysconfig.get_config_var('ANDROID_API_LEVEL') -is_android = (_ANDROID_API_LEVEL is not None and _ANDROID_API_LEVEL > 0) +try: + # constant used by requires_android_level() + _ANDROID_API_LEVEL = sys.getandroidapilevel() + is_android = True +except AttributeError: + # sys.getandroidapilevel() is only available on Android + is_android = False android_not_root = (is_android and os.geteuid() != 0) if sys.platform != 'win32': diff --git a/Lib/test/support/script_helper.py b/Lib/test/support/script_helper.py index 80889b17f3..2627a1ee68 100644 --- a/Lib/test/support/script_helper.py +++ b/Lib/test/support/script_helper.py @@ -6,11 +6,8 @@ import importlib import sys import os import os.path -import tempfile import subprocess import py_compile -import contextlib -import shutil import zipfile from importlib.util import source_from_cache diff --git a/Lib/test/test_asyncgen.py b/Lib/test/test_asyncgen.py index 34ab8a04ee..2b7c5d0d35 100644 --- a/Lib/test/test_asyncgen.py +++ b/Lib/test/test_asyncgen.py @@ -1,5 +1,4 @@ import inspect -import sys import types import unittest diff --git a/Lib/test/test_asyncio/test_tasks.py b/Lib/test/test_asyncio/test_tasks.py index a18d49ae37..fdf91a36b5 100644 --- a/Lib/test/test_asyncio/test_tasks.py +++ b/Lib/test/test_asyncio/test_tasks.py @@ -7,7 +7,6 @@ import io import os import re import sys -import time import types import unittest import weakref diff --git a/Lib/test/test_asyncio/test_unix_events.py b/Lib/test/test_asyncio/test_unix_events.py index 5a49984135..11f0890d65 100644 --- a/Lib/test/test_asyncio/test_unix_events.py +++ b/Lib/test/test_asyncio/test_unix_events.py @@ -12,7 +12,6 @@ import sys import tempfile import threading import unittest -import warnings from unittest import mock if sys.platform == 'win32': diff --git a/Lib/test/test_bz2.py b/Lib/test/test_bz2.py index eaa472a6cc..e76b283261 100644 --- a/Lib/test/test_bz2.py +++ b/Lib/test/test_bz2.py @@ -10,7 +10,6 @@ import pathlib import random import shutil import subprocess -import sys from test.support import unlink import _compression diff --git a/Lib/test/test_calendar.py b/Lib/test/test_calendar.py index 2bc4feebbd..bd57653ffa 100644 --- a/Lib/test/test_calendar.py +++ b/Lib/test/test_calendar.py @@ -404,7 +404,7 @@ class OutputTestCase(unittest.TestCase): with support.captured_stdout() as out: week = [(1,0), (2,1), (3,2), (4,3), (5,4), (6,5), (7,6)] calendar.TextCalendar().prweek(week, 1) - self.assertEqual(out.getvalue().strip(), "1 2 3 4 5 6 7") + self.assertEqual(out.getvalue(), " 1 2 3 4 5 6 7") def test_prmonth(self): with support.captured_stdout() as out: @@ -414,7 +414,7 @@ class OutputTestCase(unittest.TestCase): def test_pryear(self): with support.captured_stdout() as out: calendar.TextCalendar().pryear(2004) - self.assertEqual(out.getvalue().strip(), result_2004_text.strip()) + self.assertEqual(out.getvalue(), result_2004_text) def test_format(self): with support.captured_stdout() as out: diff --git a/Lib/test/test_cmd.py b/Lib/test/test_cmd.py index dd8981f893..99a483be43 100644 --- a/Lib/test/test_cmd.py +++ b/Lib/test/test_cmd.py @@ -6,7 +6,6 @@ Original by Michael Schneider import cmd import sys -import re import unittest import io from test import support diff --git a/Lib/test/test_cmd_line.py b/Lib/test/test_cmd_line.py index ae2bcd4375..958d282a42 100644 --- a/Lib/test/test_cmd_line.py +++ b/Lib/test/test_cmd_line.py @@ -4,7 +4,6 @@ import test.support, unittest import os -import shutil import sys import subprocess import tempfile diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py index 87454cc670..76c71392dd 100644 --- a/Lib/test/test_collections.py +++ b/Lib/test/test_collections.py @@ -319,8 +319,7 @@ class TestNamedTuple(unittest.TestCase): self.assertEqual(Dot(1)._replace(d=999), (999,)) self.assertEqual(Dot(1)._fields, ('d',)) - # n = 5000 - n = 254 # SyntaxError: more than 255 arguments: + n = 5000 names = list(set(''.join([choice(string.ascii_letters) for j in range(10)]) for i in range(n))) n = len(names) diff --git a/Lib/test/test_compile.py b/Lib/test/test_compile.py index 409ec86c75..4a7230f671 100644 --- a/Lib/test/test_compile.py +++ b/Lib/test/test_compile.py @@ -401,16 +401,9 @@ if 1: self.assertNotIn((Ellipsis, Ellipsis), d) def test_annotation_limit(self): - # 16 bits are available for # of annotations, but only 8 bits are - # available for the parameter count, hence 255 - # is the max. Ensure the result of too many annotations is a - # SyntaxError. + # more than 255 annotations, should compile ok s = "def f(%s): pass" - s %= ', '.join('a%d:%d' % (i,i) for i in range(256)) - self.assertRaises(SyntaxError, compile, s, '?', 'exec') - # Test that the max # of annotations compiles. - s = "def f(%s): pass" - s %= ', '.join('a%d:%d' % (i,i) for i in range(255)) + s %= ', '.join('a%d:%d' % (i,i) for i in range(300)) compile(s, '?', 'exec') def test_mangling(self): diff --git a/Lib/test/test_configparser.py b/Lib/test/test_configparser.py index 0d06080da3..696f642621 100644 --- a/Lib/test/test_configparser.py +++ b/Lib/test/test_configparser.py @@ -2,7 +2,6 @@ import collections import configparser import io import os -import sys import textwrap import unittest import warnings diff --git a/Lib/test/test_dbm_dumb.py b/Lib/test/test_dbm_dumb.py index df531d64e4..73f2a32a7b 100644 --- a/Lib/test/test_dbm_dumb.py +++ b/Lib/test/test_dbm_dumb.py @@ -7,7 +7,6 @@ import operator import os import stat import unittest -import warnings import dbm.dumb as dumbdbm from test import support from functools import partial @@ -252,6 +251,20 @@ class DumbDBMTestCase(unittest.TestCase): f = dumbdbm.open(_fname, value) f.close() + def test_missing_index(self): + with dumbdbm.open(_fname, 'n') as f: + pass + os.unlink(_fname + '.dir') + for value in ('r', 'w'): + with self.assertWarnsRegex(DeprecationWarning, + "The index file is missing, the " + "semantics of the 'c' flag will " + "be used."): + f = dumbdbm.open(_fname, value) + f.close() + self.assertEqual(os.path.exists(_fname + '.dir'), value == 'w') + self.assertFalse(os.path.exists(_fname + '.bak')) + def test_invalid_flag(self): for flag in ('x', 'rf', None): with self.assertWarnsRegex(DeprecationWarning, diff --git a/Lib/test/test_decimal.py b/Lib/test/test_decimal.py index 617a37eec8..59a17af278 100644 --- a/Lib/test/test_decimal.py +++ b/Lib/test/test_decimal.py @@ -37,8 +37,6 @@ from test.support import (run_unittest, run_doctest, is_resource_enabled, from test.support import (check_warnings, import_fresh_module, TestFailed, run_with_locale, cpython_only) import random -import time -import warnings import inspect try: import threading diff --git a/Lib/test/test_dis.py b/Lib/test/test_dis.py index b9b5ac2667..980ae16c65 100644 --- a/Lib/test/test_dis.py +++ b/Lib/test/test_dis.py @@ -2,7 +2,6 @@ from test.support import captured_stdout from test.bytecode_helper import BytecodeTestCase -import difflib import unittest import sys import dis diff --git a/Lib/test/test_epoll.py b/Lib/test/test_epoll.py index a7aff8a59e..549e0f7121 100644 --- a/Lib/test/test_epoll.py +++ b/Lib/test/test_epoll.py @@ -76,6 +76,8 @@ class TestEPoll(unittest.TestCase): self.assertRaises(ValueError, ep.fileno) if hasattr(select, "EPOLL_CLOEXEC"): select.epoll(select.EPOLL_CLOEXEC).close() + select.epoll(flags=select.EPOLL_CLOEXEC).close() + select.epoll(flags=0).close() self.assertRaises(OSError, select.epoll, flags=12356) def test_badcreate(self): diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py index 48379222c3..34265a517f 100644 --- a/Lib/test/test_exceptions.py +++ b/Lib/test/test_exceptions.py @@ -1112,6 +1112,20 @@ class ImportErrorTests(unittest.TestCase): with self.assertRaisesRegex(TypeError, msg): ImportError('test', invalid='keyword', another=True) + def test_reset_attributes(self): + exc = ImportError('test', name='name', path='path') + self.assertEqual(exc.args, ('test',)) + self.assertEqual(exc.msg, 'test') + self.assertEqual(exc.name, 'name') + self.assertEqual(exc.path, 'path') + + # Reset not specified attributes + exc.__init__() + self.assertEqual(exc.args, ()) + self.assertEqual(exc.msg, None) + self.assertEqual(exc.name, None) + self.assertEqual(exc.path, None) + def test_non_str_argument(self): # Issue #15778 with check_warnings(('', BytesWarning), quiet=True): diff --git a/Lib/test/test_faulthandler.py b/Lib/test/test_faulthandler.py index bdd8d1a2a6..28dd5f4e98 100644 --- a/Lib/test/test_faulthandler.py +++ b/Lib/test/test_faulthandler.py @@ -2,7 +2,6 @@ from contextlib import contextmanager import datetime import faulthandler import os -import re import signal import subprocess import sys @@ -44,7 +43,7 @@ def temporary_filename(): def requires_raise(test): return (test if not is_android else - requires_android_level(24, 'raise() is buggy')(test)) + requires_android_level(24, 'raise() is buggy')(test)) class FaultHandlerTests(unittest.TestCase): def get_output(self, code, filename=None, fd=None): diff --git a/Lib/test/test_frame.py b/Lib/test/test_frame.py index 189fca90fe..cabfef236d 100644 --- a/Lib/test/test_frame.py +++ b/Lib/test/test_frame.py @@ -1,5 +1,3 @@ -import gc -import sys import types import unittest import weakref diff --git a/Lib/test/test_httpservers.py b/Lib/test/test_httpservers.py index 4e931446b9..5049538e66 100644 --- a/Lib/test/test_httpservers.py +++ b/Lib/test/test_httpservers.py @@ -822,6 +822,16 @@ class BaseHTTPRequestHandlerTestCase(unittest.TestCase): self.assertEqual(result[0], b'<html><body>Data</body></html>\r\n') self.verify_get_called() + def test_extra_space(self): + result = self.send_typical_request( + b'GET /spaced out HTTP/1.1\r\n' + b'Host: dummy\r\n' + b'\r\n' + ) + self.assertTrue(result[0].startswith(b'HTTP/1.1 400 ')) + self.verify_expected_headers(result[1:result.index(b'\r\n')]) + self.assertFalse(self.handler.get_called) + def test_with_continue_1_0(self): result = self.send_typical_request(b'GET / HTTP/1.0\r\nExpect: 100-continue\r\n\r\n') self.verify_http_server_response(result[0]) diff --git a/Lib/test/test_import/__init__.py b/Lib/test/test_import/__init__.py index 760908efe6..d61782a6cb 100644 --- a/Lib/test/test_import/__init__.py +++ b/Lib/test/test_import/__init__.py @@ -14,7 +14,6 @@ import unittest import unittest.mock as mock import textwrap import errno -import shutil import contextlib import test.support diff --git a/Lib/test/test_importlib/abc.py b/Lib/test/test_importlib/abc.py index 2070dadc23..5d4b958767 100644 --- a/Lib/test/test_importlib/abc.py +++ b/Lib/test/test_importlib/abc.py @@ -1,5 +1,4 @@ import abc -import unittest class FinderTests(metaclass=abc.ABCMeta): diff --git a/Lib/test/test_importlib/test_abc.py b/Lib/test/test_importlib/test_abc.py index c86248047f..4c090f32de 100644 --- a/Lib/test/test_importlib/test_abc.py +++ b/Lib/test/test_importlib/test_abc.py @@ -1,5 +1,3 @@ -import contextlib -import inspect import io import marshal import os diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py index 97634e591c..1be9a125fa 100644 --- a/Lib/test/test_inspect.py +++ b/Lib/test/test_inspect.py @@ -10,7 +10,6 @@ import os from os.path import normcase import _pickle import pickle -import re import shutil import sys import types @@ -56,8 +55,6 @@ modfile = normcase(modfile) def revise(filename, *args): return (normcase(filename),) + args -import builtins - git = mod.StupidGit() class IsTestBase(unittest.TestCase): diff --git a/Lib/test/test_io.py b/Lib/test/test_io.py index aaa64eadff..fc68b09d8f 100644 --- a/Lib/test/test_io.py +++ b/Lib/test/test_io.py @@ -1149,6 +1149,7 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): self.assertEqual(b"a", bufio.read(1)) self.assertEqual(b"b", bufio.read1(1)) self.assertEqual(rawio._reads, 1) + self.assertEqual(b"", bufio.read1(0)) self.assertEqual(b"c", bufio.read1(100)) self.assertEqual(rawio._reads, 1) self.assertEqual(b"d", bufio.read1(100)) @@ -1157,8 +1158,17 @@ class BufferedReaderTest(unittest.TestCase, CommonBufferedTests): self.assertEqual(rawio._reads, 3) self.assertEqual(b"", bufio.read1(100)) self.assertEqual(rawio._reads, 4) - # Invalid args - self.assertRaises(ValueError, bufio.read1, -1) + + def test_read1_arbitrary(self): + rawio = self.MockRawIO((b"abc", b"d", b"efg")) + bufio = self.tp(rawio) + self.assertEqual(b"a", bufio.read(1)) + self.assertEqual(b"bc", bufio.read1()) + self.assertEqual(b"d", bufio.read1()) + self.assertEqual(b"efg", bufio.read1(-1)) + self.assertEqual(rawio._reads, 3) + self.assertEqual(b"", bufio.read1()) + self.assertEqual(rawio._reads, 4) def test_readinto(self): rawio = self.MockRawIO((b"abc", b"d", b"efg")) @@ -1809,6 +1819,7 @@ class BufferedRWPairTest(unittest.TestCase): pair = self.tp(self.BytesIO(b"abcdef"), self.MockRawIO()) self.assertEqual(pair.read1(3), b"abc") + self.assertEqual(pair.read1(), b"def") def test_readinto(self): for method in ("readinto", "readinto1"): @@ -3470,6 +3481,7 @@ class MiscIOTest(unittest.TestCase): self.assertRaises(ValueError, f.read) if hasattr(f, "read1"): self.assertRaises(ValueError, f.read1, 1024) + self.assertRaises(ValueError, f.read1) if hasattr(f, "readall"): self.assertRaises(ValueError, f.readall) if hasattr(f, "readinto"): diff --git a/Lib/test/test_keywordonlyarg.py b/Lib/test/test_keywordonlyarg.py index d82e33d973..2cf8a89a07 100644 --- a/Lib/test/test_keywordonlyarg.py +++ b/Lib/test/test_keywordonlyarg.py @@ -51,24 +51,12 @@ class KeywordOnlyArgTestCase(unittest.TestCase): self.assertRaisesSyntaxError("def f(p, *, (k1, k2), **kw):\n pass\n") def testSyntaxForManyArguments(self): - fundef = "def f(" - for i in range(255): - fundef += "i%d, "%i - fundef += "*, key=100):\n pass\n" - self.assertRaisesSyntaxError(fundef) - - fundef2 = "def foo(i,*," - for i in range(255): - fundef2 += "i%d, "%i - fundef2 += "lastarg):\n pass\n" - self.assertRaisesSyntaxError(fundef2) - - # exactly 255 arguments, should compile ok - fundef3 = "def f(i,*," - for i in range(253): - fundef3 += "i%d, "%i - fundef3 += "lastarg):\n pass\n" - compile(fundef3, "<test>", "single") + # more than 255 positional arguments, should compile ok + fundef = "def f(%s):\n pass\n" % ', '.join('i%d' % i for i in range(300)) + compile(fundef, "<test>", "single") + # more than 255 keyword-only arguments, should compile ok + fundef = "def f(*, %s):\n pass\n" % ', '.join('i%d' % i for i in range(300)) + compile(fundef, "<test>", "single") def testTooManyPositionalErrorMessage(self): def f(a, b=None, *, c=None): diff --git a/Lib/test/test_macurl2path.py b/Lib/test/test_macurl2path.py deleted file mode 100644 index 3490d6daf1..0000000000 --- a/Lib/test/test_macurl2path.py +++ /dev/null @@ -1,31 +0,0 @@ -import macurl2path -import unittest - -class MacUrl2PathTestCase(unittest.TestCase): - def test_url2pathname(self): - self.assertEqual(":index.html", macurl2path.url2pathname("index.html")) - self.assertEqual(":bar:index.html", macurl2path.url2pathname("bar/index.html")) - self.assertEqual("foo:bar:index.html", macurl2path.url2pathname("/foo/bar/index.html")) - self.assertEqual("foo:bar", macurl2path.url2pathname("/foo/bar/")) - self.assertEqual("", macurl2path.url2pathname("/")) - self.assertRaises(RuntimeError, macurl2path.url2pathname, "http://foo.com") - self.assertEqual("index.html", macurl2path.url2pathname("///index.html")) - self.assertRaises(RuntimeError, macurl2path.url2pathname, "//index.html") - self.assertEqual(":index.html", macurl2path.url2pathname("./index.html")) - self.assertEqual(":index.html", macurl2path.url2pathname("foo/../index.html")) - self.assertEqual("::index.html", macurl2path.url2pathname("../index.html")) - - def test_pathname2url(self): - self.assertEqual("drive", macurl2path.pathname2url("drive:")) - self.assertEqual("drive/dir", macurl2path.pathname2url("drive:dir:")) - self.assertEqual("drive/dir/file", macurl2path.pathname2url("drive:dir:file")) - self.assertEqual("drive/file", macurl2path.pathname2url("drive:file")) - self.assertEqual("file", macurl2path.pathname2url("file")) - self.assertEqual("file", macurl2path.pathname2url(":file")) - self.assertEqual("dir", macurl2path.pathname2url(":dir:")) - self.assertEqual("dir/file", macurl2path.pathname2url(":dir:file")) - self.assertRaises(RuntimeError, macurl2path.pathname2url, "/") - self.assertEqual("dir/../file", macurl2path.pathname2url("dir::file")) - -if __name__ == "__main__": - unittest.main() diff --git a/Lib/test/test_memoryio.py b/Lib/test/test_memoryio.py index 55b693e564..80055ce1e7 100644 --- a/Lib/test/test_memoryio.py +++ b/Lib/test/test_memoryio.py @@ -437,10 +437,8 @@ class PyBytesIOTest(MemoryTestMixin, MemorySeekTestMixin, unittest.TestCase): def test_read1(self): buf = self.buftype("1234567890") - memio = self.ioclass(buf) - - self.assertRaises(TypeError, memio.read1) - self.assertEqual(memio.read(), buf) + self.assertEqual(self.ioclass(buf).read1(), buf) + self.assertEqual(self.ioclass(buf).read1(-1), buf) def test_readinto(self): buf = self.buftype("1234567890") diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py index e9fdb0719f..cb15234079 100644 --- a/Lib/test/test_os.py +++ b/Lib/test/test_os.py @@ -15,7 +15,6 @@ import locale import mmap import os import pickle -import re import shutil import signal import socket diff --git a/Lib/test/test_peepholer.py b/Lib/test/test_peepholer.py index b0336407c3..efc0afecf5 100644 --- a/Lib/test/test_peepholer.py +++ b/Lib/test/test_peepholer.py @@ -1,7 +1,4 @@ import dis -import re -import sys -import textwrap import unittest from test.bytecode_helper import BytecodeTestCase diff --git a/Lib/test/test_raise.py b/Lib/test/test_raise.py index a41b353778..c6d80b078e 100644 --- a/Lib/test/test_raise.py +++ b/Lib/test/test_raise.py @@ -4,7 +4,6 @@ """Tests for the raise statement.""" from test import support -import re import sys import types import unittest diff --git a/Lib/test/test_random.py b/Lib/test/test_random.py index 5b6a4f06ba..78909dd96e 100644 --- a/Lib/test/test_random.py +++ b/Lib/test/test_random.py @@ -5,7 +5,7 @@ import time import pickle import warnings from functools import partial -from math import log, exp, pi, fsum, sin +from math import log, exp, pi, fsum, sin, factorial from test import support from fractions import Fraction @@ -118,10 +118,6 @@ class TestBasicOps: n = 5 pop = range(n) trials = 10000 # large num prevents false negatives without slowing normal case - def factorial(n): - if n == 0: - return 1 - return n * factorial(n - 1) for k in range(n): expected = factorial(n) // factorial(n-k) perms = {} diff --git a/Lib/test/test_range.py b/Lib/test/test_range.py index 9e11e518f6..3675f250af 100644 --- a/Lib/test/test_range.py +++ b/Lib/test/test_range.py @@ -4,7 +4,6 @@ import unittest import sys import pickle import itertools -import test.support # pure Python implementations (3 args only), for comparison def pyrange(start, stop, step): @@ -494,37 +493,13 @@ class RangeTest(unittest.TestCase): test_id = "reversed(range({}, {}, {}))".format(start, end, step) self.assert_iterators_equal(iter1, iter2, test_id, limit=100) - @test.support.cpython_only - def test_range_iterator_invocation(self): - import _testcapi + def test_range_iterators_invocation(self): + # verify range iterators instances cannot be created by + # calling their type rangeiter_type = type(iter(range(0))) - - self.assertWarns(DeprecationWarning, rangeiter_type, 1, 3, 1) - - with test.support.check_warnings(('', DeprecationWarning)): - # rangeiter_new doesn't take keyword arguments - with self.assertRaises(TypeError): - rangeiter_type(a=1) - - # rangeiter_new takes exactly 3 arguments - self.assertRaises(TypeError, rangeiter_type) - self.assertRaises(TypeError, rangeiter_type, 1) - self.assertRaises(TypeError, rangeiter_type, 1, 1) - self.assertRaises(TypeError, rangeiter_type, 1, 1, 1, 1) - - # start, stop and stop must fit in C long - for good_val in [_testcapi.LONG_MAX, _testcapi.LONG_MIN]: - rangeiter_type(good_val, good_val, good_val) - for bad_val in [_testcapi.LONG_MAX + 1, _testcapi.LONG_MIN - 1]: - self.assertRaises(OverflowError, - rangeiter_type, bad_val, 1, 1) - self.assertRaises(OverflowError, - rangeiter_type, 1, bad_val, 1) - self.assertRaises(OverflowError, - rangeiter_type, 1, 1, bad_val) - - # step mustn't be zero - self.assertRaises(ValueError, rangeiter_type, 1, 1, 0) + self.assertRaises(TypeError, rangeiter_type, 1, 3, 1) + long_rangeiter_type = type(iter(range(1 << 1000))) + self.assertRaises(TypeError, long_rangeiter_type, 1, 3, 1) def test_slice(self): def check(start, stop, step=None): diff --git a/Lib/test/test_re.py b/Lib/test/test_re.py index 4bdaa4b6c6..c90bdc9609 100644 --- a/Lib/test/test_re.py +++ b/Lib/test/test_re.py @@ -1,12 +1,9 @@ from test.support import verbose, run_unittest, gc_collect, bigmemtest, _2G, \ cpython_only, captured_stdout -import io import locale import re import sre_compile import string -import sys -import traceback import unittest import warnings from re import Scanner @@ -126,7 +123,7 @@ class ReTests(unittest.TestCase): (chr(9)+chr(10)+chr(11)+chr(13)+chr(12)+chr(7)+chr(8))) for c in 'cdehijklmopqsuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ': with self.subTest(c): - with self.assertWarns(DeprecationWarning): + with self.assertRaises(re.error): self.assertEqual(re.sub('a', '\\' + c, 'a'), '\\' + c) self.assertEqual(re.sub(r'^\s*', 'X', 'test'), 'Xtest') @@ -1506,7 +1503,7 @@ class ReTests(unittest.TestCase): long_overflow = 2**128 self.assertRaises(TypeError, re.finditer, "a", {}) with self.assertRaises(OverflowError): - _sre.compile("abc", 0, [long_overflow], 0, [], []) + _sre.compile("abc", 0, [long_overflow], 0, {}, ()) with self.assertRaises(TypeError): _sre.compile({}, 0, [], 0, [], []) diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py index 0202981d67..bb1081f034 100644 --- a/Lib/test/test_set.py +++ b/Lib/test/test_set.py @@ -10,7 +10,6 @@ import warnings import collections import collections.abc import itertools -import string class PassThru(Exception): pass diff --git a/Lib/test/test_shutil.py b/Lib/test/test_shutil.py index 2ad3a21c86..3688eae947 100644 --- a/Lib/test/test_shutil.py +++ b/Lib/test/test_shutil.py @@ -20,7 +20,6 @@ from shutil import (make_archive, SameFileError) import tarfile import zipfile -import warnings from test import support from test.support import (TESTFN, check_warnings, captured_stdout, diff --git a/Lib/test/test_signal.py b/Lib/test/test_signal.py index ab42ed70cc..8a404ef7a9 100644 --- a/Lib/test/test_signal.py +++ b/Lib/test/test_signal.py @@ -1,15 +1,11 @@ import unittest from test import support from contextlib import closing -import enum -import gc -import pickle import select import signal import socket import struct import subprocess -import traceback import sys, os, time, errno from test.support.script_helper import assert_python_ok, spawn_python try: diff --git a/Lib/test/test_socket.py b/Lib/test/test_socket.py index 6b29e18234..a063dbdb84 100644 --- a/Lib/test/test_socket.py +++ b/Lib/test/test_socket.py @@ -897,18 +897,28 @@ class GeneralModuleTests(unittest.TestCase): self.assertRaises(OverflowError, func, 1<<34) def testNtoHErrors(self): - good_values = [ 1, 2, 3, 1, 2, 3 ] - bad_values = [ -1, -2, -3, -1, -2, -3 ] - for k in good_values: - socket.ntohl(k) + import _testcapi + s_good_values = [0, 1, 2, 0xffff] + l_good_values = s_good_values + [0xffffffff] + l_bad_values = [-1, -2, 1<<32, 1<<1000] + s_bad_values = l_bad_values + [_testcapi.INT_MIN - 1, + _testcapi.INT_MAX + 1] + s_deprecated_values = [1<<16, _testcapi.INT_MAX] + for k in s_good_values: socket.ntohs(k) - socket.htonl(k) socket.htons(k) - for k in bad_values: - self.assertRaises(OverflowError, socket.ntohl, k) + for k in l_good_values: + socket.ntohl(k) + socket.htonl(k) + for k in s_bad_values: self.assertRaises(OverflowError, socket.ntohs, k) - self.assertRaises(OverflowError, socket.htonl, k) self.assertRaises(OverflowError, socket.htons, k) + for k in l_bad_values: + self.assertRaises(OverflowError, socket.ntohl, k) + self.assertRaises(OverflowError, socket.htonl, k) + for k in s_deprecated_values: + self.assertWarns(DeprecationWarning, socket.ntohs, k) + self.assertWarns(DeprecationWarning, socket.htons, k) def testGetServBy(self): eq = self.assertEqual @@ -931,8 +941,11 @@ class GeneralModuleTests(unittest.TestCase): else: raise OSError # Try same call with optional protocol omitted - port2 = socket.getservbyname(service) - eq(port, port2) + # Issue #26936: Android getservbyname() was broken before API 23. + if (not hasattr(sys, 'getandroidapilevel') or + sys.getandroidapilevel() >= 23): + port2 = socket.getservbyname(service) + eq(port, port2) # Try udp, but don't barf if it doesn't exist try: udpport = socket.getservbyname(service, 'udp') @@ -941,7 +954,9 @@ class GeneralModuleTests(unittest.TestCase): else: eq(udpport, port) # Now make sure the lookup by port returns the same service name - eq(socket.getservbyport(port2), service) + # Issue #26936: Android getservbyport() is broken. + if not support.is_android: + eq(socket.getservbyport(port2), service) eq(socket.getservbyport(port, 'tcp'), service) if udpport is not None: eq(socket.getservbyport(udpport, 'udp'), service) @@ -1274,7 +1289,10 @@ class GeneralModuleTests(unittest.TestCase): socket.getaddrinfo('::1', 80) # port can be a string service name such as "http", a numeric # port number or None - socket.getaddrinfo(HOST, "http") + # Issue #26936: Android getaddrinfo() was broken before API level 23. + if (not hasattr(sys, 'getandroidapilevel') or + sys.getandroidapilevel() >= 23): + socket.getaddrinfo(HOST, "http") socket.getaddrinfo(HOST, 80) socket.getaddrinfo(HOST, None) # test family and socktype filters diff --git a/Lib/test/test_ssl.py b/Lib/test/test_ssl.py index d203cddbdf..69a65d20a4 100644 --- a/Lib/test/test_ssl.py +++ b/Lib/test/test_ssl.py @@ -11,7 +11,6 @@ import gc import os import errno import pprint -import tempfile import urllib.request import traceback import asyncore diff --git a/Lib/test/test_subclassinit.py b/Lib/test/test_subclassinit.py index 3c331bb98f..0ad7d17fbd 100644 --- a/Lib/test/test_subclassinit.py +++ b/Lib/test/test_subclassinit.py @@ -1,4 +1,3 @@ -import sys import types import unittest diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index 89de6d1b1a..4cfb29db73 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -1015,19 +1015,6 @@ class ProcessTestCase(BaseTestCase): # time to start. self.assertEqual(p.wait(timeout=3), 0) - def test_wait_endtime(self): - """Confirm that the deprecated endtime parameter warns.""" - p = subprocess.Popen([sys.executable, "-c", "pass"]) - try: - with self.assertWarns(DeprecationWarning) as warn_cm: - p.wait(endtime=time.time()+0.01) - except subprocess.TimeoutExpired: - pass # We're not testing endtime timeout behavior. - finally: - p.kill() - self.assertIn('test_subprocess.py', warn_cm.filename) - self.assertIn('endtime', str(warn_cm.warning)) - def test_invalid_bufsize(self): # an invalid type of the bufsize argument should raise # TypeError. diff --git a/Lib/test/test_super.py b/Lib/test/test_super.py index 447dec9130..cb2d7c3223 100644 --- a/Lib/test/test_super.py +++ b/Lib/test/test_super.py @@ -1,6 +1,5 @@ """Unit tests for zero-argument super() & related machinery.""" -import sys import unittest import warnings from test.support import check_warnings diff --git a/Lib/test/test_syntax.py b/Lib/test/test_syntax.py index 7f7e6dafcf..5d398e6688 100644 --- a/Lib/test/test_syntax.py +++ b/Lib/test/test_syntax.py @@ -139,69 +139,100 @@ SyntaxError: Generator expression must be parenthesized if not sole argument >>> f((x for x in L), 1) [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] ->>> f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, -... i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, -... i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, -... i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, -... i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, -... i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, -... i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, -... i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, -... i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, -... i100, i101, i102, i103, i104, i105, i106, i107, i108, -... i109, i110, i111, i112, i113, i114, i115, i116, i117, -... i118, i119, i120, i121, i122, i123, i124, i125, i126, -... i127, i128, i129, i130, i131, i132, i133, i134, i135, -... i136, i137, i138, i139, i140, i141, i142, i143, i144, -... i145, i146, i147, i148, i149, i150, i151, i152, i153, -... i154, i155, i156, i157, i158, i159, i160, i161, i162, -... i163, i164, i165, i166, i167, i168, i169, i170, i171, -... i172, i173, i174, i175, i176, i177, i178, i179, i180, -... i181, i182, i183, i184, i185, i186, i187, i188, i189, -... i190, i191, i192, i193, i194, i195, i196, i197, i198, -... i199, i200, i201, i202, i203, i204, i205, i206, i207, -... i208, i209, i210, i211, i212, i213, i214, i215, i216, -... i217, i218, i219, i220, i221, i222, i223, i224, i225, -... i226, i227, i228, i229, i230, i231, i232, i233, i234, -... i235, i236, i237, i238, i239, i240, i241, i242, i243, -... i244, i245, i246, i247, i248, i249, i250, i251, i252, -... i253, i254, i255) -Traceback (most recent call last): -SyntaxError: more than 255 arguments - -The actual error cases counts positional arguments, keyword arguments, -and generator expression arguments separately. This test combines the -three. - ->>> f(i0, i1, i2, i3, i4, i5, i6, i7, i8, i9, i10, i11, -... i12, i13, i14, i15, i16, i17, i18, i19, i20, i21, i22, -... i23, i24, i25, i26, i27, i28, i29, i30, i31, i32, i33, -... i34, i35, i36, i37, i38, i39, i40, i41, i42, i43, i44, -... i45, i46, i47, i48, i49, i50, i51, i52, i53, i54, i55, -... i56, i57, i58, i59, i60, i61, i62, i63, i64, i65, i66, -... i67, i68, i69, i70, i71, i72, i73, i74, i75, i76, i77, -... i78, i79, i80, i81, i82, i83, i84, i85, i86, i87, i88, -... i89, i90, i91, i92, i93, i94, i95, i96, i97, i98, i99, -... i100, i101, i102, i103, i104, i105, i106, i107, i108, -... i109, i110, i111, i112, i113, i114, i115, i116, i117, -... i118, i119, i120, i121, i122, i123, i124, i125, i126, -... i127, i128, i129, i130, i131, i132, i133, i134, i135, -... i136, i137, i138, i139, i140, i141, i142, i143, i144, -... i145, i146, i147, i148, i149, i150, i151, i152, i153, -... i154, i155, i156, i157, i158, i159, i160, i161, i162, -... i163, i164, i165, i166, i167, i168, i169, i170, i171, -... i172, i173, i174, i175, i176, i177, i178, i179, i180, -... i181, i182, i183, i184, i185, i186, i187, i188, i189, -... i190, i191, i192, i193, i194, i195, i196, i197, i198, -... i199, i200, i201, i202, i203, i204, i205, i206, i207, -... i208, i209, i210, i211, i212, i213, i214, i215, i216, -... i217, i218, i219, i220, i221, i222, i223, i224, i225, -... i226, i227, i228, i229, i230, i231, i232, i233, i234, -... i235, i236, i237, i238, i239, i240, i241, i242, i243, -... (x for x in i244), i245, i246, i247, i248, i249, i250, i251, -... i252=1, i253=1, i254=1, i255=1) -Traceback (most recent call last): -SyntaxError: more than 255 arguments +>>> def g(*args, **kwargs): +... print(args, sorted(kwargs.items())) +>>> g(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +... 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, +... 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, +... 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, +... 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, +... 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, +... 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, +... 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, +... 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, +... 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, +... 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, +... 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +... 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, +... 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, +... 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, +... 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, +... 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, +... 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, +... 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, +... 290, 291, 292, 293, 294, 295, 296, 297, 298, 299) # doctest: +ELLIPSIS +(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ..., 297, 298, 299) [] + +>>> g(a000=0, a001=1, a002=2, a003=3, a004=4, a005=5, a006=6, a007=7, a008=8, +... a009=9, a010=10, a011=11, a012=12, a013=13, a014=14, a015=15, a016=16, +... a017=17, a018=18, a019=19, a020=20, a021=21, a022=22, a023=23, a024=24, +... a025=25, a026=26, a027=27, a028=28, a029=29, a030=30, a031=31, a032=32, +... a033=33, a034=34, a035=35, a036=36, a037=37, a038=38, a039=39, a040=40, +... a041=41, a042=42, a043=43, a044=44, a045=45, a046=46, a047=47, a048=48, +... a049=49, a050=50, a051=51, a052=52, a053=53, a054=54, a055=55, a056=56, +... a057=57, a058=58, a059=59, a060=60, a061=61, a062=62, a063=63, a064=64, +... a065=65, a066=66, a067=67, a068=68, a069=69, a070=70, a071=71, a072=72, +... a073=73, a074=74, a075=75, a076=76, a077=77, a078=78, a079=79, a080=80, +... a081=81, a082=82, a083=83, a084=84, a085=85, a086=86, a087=87, a088=88, +... a089=89, a090=90, a091=91, a092=92, a093=93, a094=94, a095=95, a096=96, +... a097=97, a098=98, a099=99, a100=100, a101=101, a102=102, a103=103, +... a104=104, a105=105, a106=106, a107=107, a108=108, a109=109, a110=110, +... a111=111, a112=112, a113=113, a114=114, a115=115, a116=116, a117=117, +... a118=118, a119=119, a120=120, a121=121, a122=122, a123=123, a124=124, +... a125=125, a126=126, a127=127, a128=128, a129=129, a130=130, a131=131, +... a132=132, a133=133, a134=134, a135=135, a136=136, a137=137, a138=138, +... a139=139, a140=140, a141=141, a142=142, a143=143, a144=144, a145=145, +... a146=146, a147=147, a148=148, a149=149, a150=150, a151=151, a152=152, +... a153=153, a154=154, a155=155, a156=156, a157=157, a158=158, a159=159, +... a160=160, a161=161, a162=162, a163=163, a164=164, a165=165, a166=166, +... a167=167, a168=168, a169=169, a170=170, a171=171, a172=172, a173=173, +... a174=174, a175=175, a176=176, a177=177, a178=178, a179=179, a180=180, +... a181=181, a182=182, a183=183, a184=184, a185=185, a186=186, a187=187, +... a188=188, a189=189, a190=190, a191=191, a192=192, a193=193, a194=194, +... a195=195, a196=196, a197=197, a198=198, a199=199, a200=200, a201=201, +... a202=202, a203=203, a204=204, a205=205, a206=206, a207=207, a208=208, +... a209=209, a210=210, a211=211, a212=212, a213=213, a214=214, a215=215, +... a216=216, a217=217, a218=218, a219=219, a220=220, a221=221, a222=222, +... a223=223, a224=224, a225=225, a226=226, a227=227, a228=228, a229=229, +... a230=230, a231=231, a232=232, a233=233, a234=234, a235=235, a236=236, +... a237=237, a238=238, a239=239, a240=240, a241=241, a242=242, a243=243, +... a244=244, a245=245, a246=246, a247=247, a248=248, a249=249, a250=250, +... a251=251, a252=252, a253=253, a254=254, a255=255, a256=256, a257=257, +... a258=258, a259=259, a260=260, a261=261, a262=262, a263=263, a264=264, +... a265=265, a266=266, a267=267, a268=268, a269=269, a270=270, a271=271, +... a272=272, a273=273, a274=274, a275=275, a276=276, a277=277, a278=278, +... a279=279, a280=280, a281=281, a282=282, a283=283, a284=284, a285=285, +... a286=286, a287=287, a288=288, a289=289, a290=290, a291=291, a292=292, +... a293=293, a294=294, a295=295, a296=296, a297=297, a298=298, a299=299) +... # doctest: +ELLIPSIS +() [('a000', 0), ('a001', 1), ('a002', 2), ..., ('a298', 298), ('a299', 299)] + +>>> class C: +... def meth(self, *args): +... return args +>>> obj = C() +>>> obj.meth( +... 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, +... 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, +... 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, +... 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, +... 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, +... 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, +... 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, +... 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, +... 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, +... 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, +... 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, +... 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, +... 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, +... 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, +... 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, +... 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, +... 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, +... 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, +... 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, +... 290, 291, 292, 293, 294, 295, 296, 297, 298, 299) # doctest: +ELLIPSIS +(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, ..., 297, 298, 299) >>> f(lambda x: x[0] = 3) Traceback (most recent call last): diff --git a/Lib/test/test_sys.py b/Lib/test/test_sys.py index df9ebd4085..e6d8e5082f 100644 --- a/Lib/test/test_sys.py +++ b/Lib/test/test_sys.py @@ -826,6 +826,13 @@ class SysModuleTest(unittest.TestCase): rc, stdout, stderr = assert_python_ok('-c', code) self.assertEqual(stdout.rstrip(), b'True') + @unittest.skipUnless(hasattr(sys, 'getandroidapilevel'), + 'need sys.getandroidapilevel()') + def test_getandroidapilevel(self): + level = sys.getandroidapilevel() + self.assertIsInstance(level, int) + self.assertGreater(level, 0) + @test.support.cpython_only class SizeofTest(unittest.TestCase): @@ -919,7 +926,7 @@ class SizeofTest(unittest.TestCase): def inner(): return x return inner - check(get_cell2.__code__, size('6i13P') + 1) + check(get_cell2.__code__, size('6i13P') + calcsize('n')) # complex check(complex(0,1), size('2d')) # method_descriptor (descriptor object) diff --git a/Lib/test/test_sysconfig.py b/Lib/test/test_sysconfig.py index 355bc614da..694435f56c 100644 --- a/Lib/test/test_sysconfig.py +++ b/Lib/test/test_sysconfig.py @@ -5,7 +5,7 @@ import subprocess import shutil from copy import copy -from test.support import (run_unittest, TESTFN, unlink, check_warnings, +from test.support import (import_module, TESTFN, unlink, check_warnings, captured_stdout, skip_unless_symlink, change_cwd) import sysconfig @@ -389,7 +389,8 @@ class TestSysConfig(unittest.TestCase): hasattr(sys.implementation, '_multiarch'), 'multiarch-specific test') def test_triplet_in_ext_suffix(self): - import ctypes, platform, re + ctypes = import_module('ctypes') + import platform, re machine = platform.machine() suffix = sysconfig.get_config_var('EXT_SUFFIX') if re.match('(aarch64|arm|mips|ppc|powerpc|s390|sparc)', machine): @@ -436,8 +437,5 @@ class MakefileTests(unittest.TestCase): }) -def test_main(): - run_unittest(TestSysConfig, MakefileTests) - if __name__ == "__main__": - test_main() + unittest.main() diff --git a/Lib/test/test_timeit.py b/Lib/test/test_timeit.py index 1a95e2979c..e02d4a71a9 100644 --- a/Lib/test/test_timeit.py +++ b/Lib/test/test_timeit.py @@ -2,7 +2,6 @@ import timeit import unittest import sys import io -import time from textwrap import dedent from test.support import captured_stdout @@ -12,7 +11,7 @@ from test.support import captured_stderr DEFAULT_NUMBER = 1000000 # timeit's default number of repetitions. -DEFAULT_REPEAT = 3 +DEFAULT_REPEAT = 5 # XXX: some tests are commented out that would improve the coverage but take a # long time to run because they test the default number of loops, which is @@ -226,7 +225,7 @@ class TestTimeit(unittest.TestCase): t.print_exc(s) self.assert_exc_string(s.getvalue(), 'ZeroDivisionError') - MAIN_DEFAULT_OUTPUT = "10 loops, best of 3: 1 sec per loop\n" + MAIN_DEFAULT_OUTPUT = "1 loop, best of 5: 1 sec per loop\n" def run_main(self, seconds_per_increment=1.0, switches=None, timer=None): if timer is None: @@ -252,39 +251,39 @@ class TestTimeit(unittest.TestCase): def test_main_seconds(self): s = self.run_main(seconds_per_increment=5.5) - self.assertEqual(s, "10 loops, best of 3: 5.5 sec per loop\n") + self.assertEqual(s, "1 loop, best of 5: 5.5 sec per loop\n") def test_main_milliseconds(self): s = self.run_main(seconds_per_increment=0.0055) - self.assertEqual(s, "100 loops, best of 3: 5.5 msec per loop\n") + self.assertEqual(s, "50 loops, best of 5: 5.5 msec per loop\n") def test_main_microseconds(self): s = self.run_main(seconds_per_increment=0.0000025, switches=['-n100']) - self.assertEqual(s, "100 loops, best of 3: 2.5 usec per loop\n") + self.assertEqual(s, "100 loops, best of 5: 2.5 usec per loop\n") def test_main_fixed_iters(self): s = self.run_main(seconds_per_increment=2.0, switches=['-n35']) - self.assertEqual(s, "35 loops, best of 3: 2 sec per loop\n") + self.assertEqual(s, "35 loops, best of 5: 2 sec per loop\n") def test_main_setup(self): s = self.run_main(seconds_per_increment=2.0, switches=['-n35', '-s', 'print("CustomSetup")']) - self.assertEqual(s, "CustomSetup\n" * 3 + - "35 loops, best of 3: 2 sec per loop\n") + self.assertEqual(s, "CustomSetup\n" * DEFAULT_REPEAT + + "35 loops, best of 5: 2 sec per loop\n") def test_main_multiple_setups(self): s = self.run_main(seconds_per_increment=2.0, switches=['-n35', '-s', 'a = "CustomSetup"', '-s', 'print(a)']) - self.assertEqual(s, "CustomSetup\n" * 3 + - "35 loops, best of 3: 2 sec per loop\n") + self.assertEqual(s, "CustomSetup\n" * DEFAULT_REPEAT + + "35 loops, best of 5: 2 sec per loop\n") def test_main_fixed_reps(self): s = self.run_main(seconds_per_increment=60.0, switches=['-r9']) - self.assertEqual(s, "10 loops, best of 9: 60 sec per loop\n") + self.assertEqual(s, "1 loop, best of 9: 60 sec per loop\n") def test_main_negative_reps(self): s = self.run_main(seconds_per_increment=60.0, switches=['-r-5']) - self.assertEqual(s, "10 loops, best of 1: 60 sec per loop\n") + self.assertEqual(s, "1 loop, best of 1: 60 sec per loop\n") @unittest.skipIf(sys.flags.optimize >= 2, "need __doc__") def test_main_help(self): @@ -293,56 +292,57 @@ class TestTimeit(unittest.TestCase): # the help text, but since it's there, check for it. self.assertEqual(s, timeit.__doc__ + ' ') - def test_main_using_time(self): - fake_timer = FakeTimer() - s = self.run_main(switches=['-t'], timer=fake_timer) - self.assertEqual(s, self.MAIN_DEFAULT_OUTPUT) - self.assertIs(fake_timer.saved_timer, time.time) - - def test_main_using_clock(self): - fake_timer = FakeTimer() - s = self.run_main(switches=['-c'], timer=fake_timer) - self.assertEqual(s, self.MAIN_DEFAULT_OUTPUT) - self.assertIs(fake_timer.saved_timer, time.clock) - def test_main_verbose(self): s = self.run_main(switches=['-v']) self.assertEqual(s, dedent("""\ - 10 loops -> 10 secs - raw times: 10 10 10 - 10 loops, best of 3: 1 sec per loop + 1 loop -> 1 secs + + raw times: 1 sec, 1 sec, 1 sec, 1 sec, 1 sec + + 1 loop, best of 5: 1 sec per loop """)) def test_main_very_verbose(self): - s = self.run_main(seconds_per_increment=0.000050, switches=['-vv']) + s = self.run_main(seconds_per_increment=0.000_030, switches=['-vv']) self.assertEqual(s, dedent("""\ - 10 loops -> 0.0005 secs - 100 loops -> 0.005 secs - 1000 loops -> 0.05 secs - 10000 loops -> 0.5 secs - raw times: 0.5 0.5 0.5 - 10000 loops, best of 3: 50 usec per loop + 1 loop -> 3e-05 secs + 2 loops -> 6e-05 secs + 5 loops -> 0.00015 secs + 10 loops -> 0.0003 secs + 20 loops -> 0.0006 secs + 50 loops -> 0.0015 secs + 100 loops -> 0.003 secs + 200 loops -> 0.006 secs + 500 loops -> 0.015 secs + 1000 loops -> 0.03 secs + 2000 loops -> 0.06 secs + 5000 loops -> 0.15 secs + 10000 loops -> 0.3 secs + + raw times: 300 msec, 300 msec, 300 msec, 300 msec, 300 msec + + 10000 loops, best of 5: 30 usec per loop """)) def test_main_with_time_unit(self): - unit_sec = self.run_main(seconds_per_increment=0.002, + unit_sec = self.run_main(seconds_per_increment=0.003, switches=['-u', 'sec']) self.assertEqual(unit_sec, - "1000 loops, best of 3: 0.002 sec per loop\n") - unit_msec = self.run_main(seconds_per_increment=0.002, + "100 loops, best of 5: 0.003 sec per loop\n") + unit_msec = self.run_main(seconds_per_increment=0.003, switches=['-u', 'msec']) self.assertEqual(unit_msec, - "1000 loops, best of 3: 2 msec per loop\n") - unit_usec = self.run_main(seconds_per_increment=0.002, + "100 loops, best of 5: 3 msec per loop\n") + unit_usec = self.run_main(seconds_per_increment=0.003, switches=['-u', 'usec']) self.assertEqual(unit_usec, - "1000 loops, best of 3: 2e+03 usec per loop\n") + "100 loops, best of 5: 3e+03 usec per loop\n") # Test invalid unit input with captured_stderr() as error_stringio: - invalid = self.run_main(seconds_per_increment=0.002, + invalid = self.run_main(seconds_per_increment=0.003, switches=['-u', 'parsec']) self.assertEqual(error_stringio.getvalue(), - "Unrecognized unit. Please select usec, msec, or sec.\n") + "Unrecognized unit. Please select nsec, usec, msec, or sec.\n") def test_main_exception(self): with captured_stderr() as error_stringio: @@ -354,26 +354,37 @@ class TestTimeit(unittest.TestCase): s = self.run_main(switches=['-n1', '1/0']) self.assert_exc_string(error_stringio.getvalue(), 'ZeroDivisionError') - def autorange(self, callback=None): - timer = FakeTimer(seconds_per_increment=0.001) + def autorange(self, seconds_per_increment=1/1024, callback=None): + timer = FakeTimer(seconds_per_increment=seconds_per_increment) t = timeit.Timer(stmt=self.fake_stmt, setup=self.fake_setup, timer=timer) return t.autorange(callback) def test_autorange(self): num_loops, time_taken = self.autorange() - self.assertEqual(num_loops, 1000) + self.assertEqual(num_loops, 500) + self.assertEqual(time_taken, 500/1024) + + def test_autorange_second(self): + num_loops, time_taken = self.autorange(seconds_per_increment=1.0) + self.assertEqual(num_loops, 1) self.assertEqual(time_taken, 1.0) def test_autorange_with_callback(self): def callback(a, b): print("{} {:.3f}".format(a, b)) with captured_stdout() as s: - num_loops, time_taken = self.autorange(callback) - self.assertEqual(num_loops, 1000) - self.assertEqual(time_taken, 1.0) - expected = ('10 0.010\n' - '100 0.100\n' - '1000 1.000\n') + num_loops, time_taken = self.autorange(callback=callback) + self.assertEqual(num_loops, 500) + self.assertEqual(time_taken, 500/1024) + expected = ('1 0.001\n' + '2 0.002\n' + '5 0.005\n' + '10 0.010\n' + '20 0.020\n' + '50 0.049\n' + '100 0.098\n' + '200 0.195\n' + '500 0.488\n') self.assertEqual(s.getvalue(), expected) diff --git a/Lib/test/test_unicode_identifiers.py b/Lib/test/test_unicode_identifiers.py index 0679845238..07332c4631 100644 --- a/Lib/test/test_unicode_identifiers.py +++ b/Lib/test/test_unicode_identifiers.py @@ -1,5 +1,4 @@ import unittest -import sys class PEP3131Test(unittest.TestCase): diff --git a/Lib/test/test_winsound.py b/Lib/test/test_winsound.py index 179e069a1c..c86bf553fd 100644 --- a/Lib/test/test_winsound.py +++ b/Lib/test/test_winsound.py @@ -1,8 +1,6 @@ # Ridiculously simple test of the winsound module for Windows. import functools -import os -import subprocess import time import unittest diff --git a/Lib/test/test_yield_from.py b/Lib/test/test_yield_from.py index 7e9711eaf5..d1da838ac7 100644 --- a/Lib/test/test_yield_from.py +++ b/Lib/test/test_yield_from.py @@ -8,10 +8,7 @@ see <http://www.cosc.canterbury.ac.nz/greg.ewing/python/yield-from/YieldFrom-Pyt """ import unittest -import io -import sys import inspect -import parser from test.support import captured_stderr, disable_gc, gc_collect diff --git a/Lib/test/test_zipfile.py b/Lib/test/test_zipfile.py index 0a43b20e2b..0a19d76f42 100644 --- a/Lib/test/test_zipfile.py +++ b/Lib/test/test_zipfile.py @@ -2055,8 +2055,9 @@ class CommandLineTest(unittest.TestCase): def test_test_command(self): zip_name = findfile('zipdir.zip') - out = self.zipfilecmd('-t', zip_name) - self.assertEqual(out.rstrip(), b'Done testing') + for opt in '-t', '--test': + out = self.zipfilecmd(opt, zip_name) + self.assertEqual(out.rstrip(), b'Done testing') zip_name = findfile('testtar.tar') rc, out, err = self.zipfilecmd_failure('-t', zip_name) self.assertEqual(out, b'') @@ -2067,9 +2068,10 @@ class CommandLineTest(unittest.TestCase): with zipfile.ZipFile(zip_name, 'r') as tf: tf.printdir(t) expected = t.getvalue().encode('ascii', 'backslashreplace') - out = self.zipfilecmd('-l', zip_name, - PYTHONIOENCODING='ascii:backslashreplace') - self.assertEqual(out, expected) + for opt in '-l', '--list': + out = self.zipfilecmd(opt, zip_name, + PYTHONIOENCODING='ascii:backslashreplace') + self.assertEqual(out, expected) @requires_zlib def test_create_command(self): @@ -2082,31 +2084,33 @@ class CommandLineTest(unittest.TestCase): f.write('test 2') files = [TESTFN, TESTFNDIR] namelist = [TESTFN, TESTFNDIR + '/', TESTFNDIR + '/file.txt'] - try: - out = self.zipfilecmd('-c', TESTFN2, *files) - self.assertEqual(out, b'') - with zipfile.ZipFile(TESTFN2) as zf: - self.assertEqual(zf.namelist(), namelist) - self.assertEqual(zf.read(namelist[0]), b'test 1') - self.assertEqual(zf.read(namelist[2]), b'test 2') - finally: - unlink(TESTFN2) + for opt in '-c', '--create': + try: + out = self.zipfilecmd(opt, TESTFN2, *files) + self.assertEqual(out, b'') + with zipfile.ZipFile(TESTFN2) as zf: + self.assertEqual(zf.namelist(), namelist) + self.assertEqual(zf.read(namelist[0]), b'test 1') + self.assertEqual(zf.read(namelist[2]), b'test 2') + finally: + unlink(TESTFN2) def test_extract_command(self): zip_name = findfile('zipdir.zip') - with temp_dir() as extdir: - out = self.zipfilecmd('-e', zip_name, extdir) - self.assertEqual(out, b'') - with zipfile.ZipFile(zip_name) as zf: - for zi in zf.infolist(): - path = os.path.join(extdir, - zi.filename.replace('/', os.sep)) - if zi.is_dir(): - self.assertTrue(os.path.isdir(path)) - else: - self.assertTrue(os.path.isfile(path)) - with open(path, 'rb') as f: - self.assertEqual(f.read(), zf.read(zi)) + for opt in '-e', '--extract': + with temp_dir() as extdir: + out = self.zipfilecmd(opt, zip_name, extdir) + self.assertEqual(out, b'') + with zipfile.ZipFile(zip_name) as zf: + for zi in zf.infolist(): + path = os.path.join(extdir, + zi.filename.replace('/', os.sep)) + if zi.is_dir(): + self.assertTrue(os.path.isdir(path)) + else: + self.assertTrue(os.path.isfile(path)) + with open(path, 'rb') as f: + self.assertEqual(f.read(), zf.read(zi)) if __name__ == "__main__": unittest.main() diff --git a/Lib/timeit.py b/Lib/timeit.py index 2770efa35a..38c2b1f061 100644 --- a/Lib/timeit.py +++ b/Lib/timeit.py @@ -9,7 +9,7 @@ the Python Cookbook, published by O'Reilly. Library usage: see the Timer class. Command line usage: - python timeit.py [-n N] [-r N] [-s S] [-t] [-c] [-p] [-h] [--] [statement] + python timeit.py [-n N] [-r N] [-s S] [-p] [-h] [--] [statement] Options: -n/--number N: how many times to execute 'statement' (default: see below) @@ -17,10 +17,8 @@ Options: -s/--setup S: statement to be executed once initially (default 'pass'). Execution time of this setup statement is NOT timed. -p/--process: use time.process_time() (default is time.perf_counter()) - -t/--time: use time.time() (deprecated) - -c/--clock: use time.clock() (deprecated) -v/--verbose: print raw timing results; repeat for more digits precision - -u/--unit: set the output time unit (usec, msec, or sec) + -u/--unit: set the output time unit (nsec, usec, msec, or sec) -h/--help: print this usage message and exit --: separate options from statement, use when statement starts with - statement: statement to be timed (default 'pass') @@ -59,7 +57,7 @@ __all__ = ["Timer", "timeit", "repeat", "default_timer"] dummy_src_name = "<timeit-src>" default_number = 1000000 -default_repeat = 3 +default_repeat = 5 default_timer = time.perf_counter _globals = globals @@ -210,22 +208,23 @@ class Timer: def autorange(self, callback=None): """Return the number of loops so that total time >= 0.2. - Calls the timeit method with *number* set to successive powers of - ten (10, 100, 1000, ...) up to a maximum of one billion, until - the time taken is at least 0.2 second, or the maximum is reached. - Returns ``(number, time_taken)``. + Calls the timeit method with increasing numbers from the sequence + 1, 2, 5, 10, 20, 50, ... until the time taken is at least 0.2 + second. Returns (number, time_taken). If *callback* is given and is not None, it will be called after each trial with two arguments: ``callback(number, time_taken)``. """ - for i in range(1, 10): - number = 10**i - time_taken = self.timeit(number) - if callback: - callback(number, time_taken) - if time_taken >= 0.2: - break - return (number, time_taken) + i = 1 + while True: + for j in 1, 2, 5: + number = i * j + time_taken = self.timeit(number) + if callback: + callback(number, time_taken) + if time_taken >= 0.2: + return (number, time_taken) + i *= 10 def timeit(stmt="pass", setup="pass", timer=default_timer, number=default_number, globals=None): @@ -266,6 +265,7 @@ def main(args=None, *, _wrap_timer=None): print(err) print("use -h/--help for command line help") return 2 + timer = default_timer stmt = "\n".join(args) or "pass" number = 0 # auto-determine @@ -273,7 +273,7 @@ def main(args=None, *, _wrap_timer=None): repeat = default_repeat verbose = 0 time_unit = None - units = {"usec": 1, "msec": 1e3, "sec": 1e6} + units = {"nsec": 1e-9, "usec": 1e-6, "msec": 1e-3, "sec": 1.0} precision = 3 for o, a in opts: if o in ("-n", "--number"): @@ -284,17 +284,13 @@ def main(args=None, *, _wrap_timer=None): if a in units: time_unit = a else: - print("Unrecognized unit. Please select usec, msec, or sec.", + print("Unrecognized unit. Please select nsec, usec, msec, or sec.", file=sys.stderr) return 2 if o in ("-r", "--repeat"): repeat = int(a) if repeat <= 0: repeat = 1 - if o in ("-t", "--time"): - timer = time.time - if o in ("-c", "--clock"): - timer = time.clock if o in ("-p", "--process"): timer = time.process_time if o in ("-v", "--verbose"): @@ -305,6 +301,7 @@ def main(args=None, *, _wrap_timer=None): print(__doc__, end=' ') return 0 setup = "\n".join(setup) or "pass" + # Include the current directory, so that local imports work (sys.path # contains the directory of this script, rather than the current # directory) @@ -312,50 +309,65 @@ def main(args=None, *, _wrap_timer=None): sys.path.insert(0, os.curdir) if _wrap_timer is not None: timer = _wrap_timer(timer) + t = Timer(stmt, setup, timer) if number == 0: # determine number so that 0.2 <= total time < 2.0 callback = None if verbose: def callback(number, time_taken): - msg = "{num} loops -> {secs:.{prec}g} secs" - print(msg.format(num=number, secs=time_taken, prec=precision)) + msg = "{num} loop{s} -> {secs:.{prec}g} secs" + plural = (number != 1) + print(msg.format(num=number, s='s' if plural else '', + secs=time_taken, prec=precision)) try: number, _ = t.autorange(callback) except: t.print_exc() return 1 + + if verbose: + print() + try: - r = t.repeat(repeat, number) + raw_timings = t.repeat(repeat, number) except: t.print_exc() return 1 - best = min(r) + + def format_time(dt): + unit = time_unit + + if unit is not None: + scale = units[unit] + else: + scales = [(scale, unit) for unit, scale in units.items()] + scales.sort(reverse=True) + for scale, unit in scales: + if dt >= scale: + break + + return "%.*g %s" % (precision, dt / scale, unit) + if verbose: - print("raw times:", " ".join(["%.*g" % (precision, x) for x in r])) - print("%d loops," % number, end=' ') - usec = best * 1e6 / number - if time_unit is not None: - scale = units[time_unit] - else: - scales = [(scale, unit) for unit, scale in units.items()] - scales.sort(reverse=True) - for scale, time_unit in scales: - if usec >= scale: - break - print("best of %d: %.*g %s per loop" % (repeat, precision, - usec/scale, time_unit)) - best = min(r) - usec = best * 1e6 / number - worst = max(r) + print("raw times: %s" % ", ".join(map(format_time, raw_timings))) + print() + timings = [dt / number for dt in raw_timings] + + best = min(timings) + print("%d loop%s, best of %d: %s per loop" + % (number, 's' if number != 1 else '', + repeat, format_time(best))) + + best = min(timings) + worst = max(timings) if worst >= best * 4: - usec = worst * 1e6 / number import warnings - warnings.warn_explicit( - "The test results are likely unreliable. The worst\n" - "time (%.*g %s) was more than four times slower than the best time." % - (precision, usec/scale, time_unit), - UserWarning, '', 0) + warnings.warn_explicit("The test results are likely unreliable. " + "The worst time (%s) was more than four times " + "slower than the best time (%s)." + % (format_time(worst), format_time(best)), + UserWarning, '', 0) return None if __name__ == "__main__": diff --git a/Lib/unittest/mock.py b/Lib/unittest/mock.py index f134919888..367c1e19ce 100644 --- a/Lib/unittest/mock.py +++ b/Lib/unittest/mock.py @@ -104,26 +104,16 @@ def _check_signature(func, mock, skipfirst, instance=False): def _copy_func_details(func, funcopy): - funcopy.__name__ = func.__name__ - funcopy.__doc__ = func.__doc__ - try: - funcopy.__text_signature__ = func.__text_signature__ - except AttributeError: - pass # we explicitly don't copy func.__dict__ into this copy as it would # expose original attributes that should be mocked - try: - funcopy.__module__ = func.__module__ - except AttributeError: - pass - try: - funcopy.__defaults__ = func.__defaults__ - except AttributeError: - pass - try: - funcopy.__kwdefaults__ = func.__kwdefaults__ - except AttributeError: - pass + for attribute in ( + '__name__', '__doc__', '__text_signature__', + '__module__', '__defaults__', '__kwdefaults__', + ): + try: + setattr(funcopy, attribute, getattr(func, attribute)) + except AttributeError: + pass def _callable(obj): diff --git a/Lib/urllib/request.py b/Lib/urllib/request.py index 5f15b74f4d..793ea7fbbd 100644 --- a/Lib/urllib/request.py +++ b/Lib/urllib/request.py @@ -94,7 +94,6 @@ import socket import string import sys import time -import collections import tempfile import contextlib import warnings diff --git a/Lib/zipfile.py b/Lib/zipfile.py index e2ae042cfd..e31c93a947 100644 --- a/Lib/zipfile.py +++ b/Lib/zipfile.py @@ -5,7 +5,6 @@ XXX references to utf-8 need further investigation. """ import io import os -import re import importlib.util import sys import time @@ -1950,51 +1949,45 @@ class PyZipFile(ZipFile): return (fname, archivename) -def main(args = None): - import textwrap - USAGE=textwrap.dedent("""\ - Usage: - zipfile.py -l zipfile.zip # Show listing of a zipfile - zipfile.py -t zipfile.zip # Test if a zipfile is valid - zipfile.py -e zipfile.zip target # Extract zipfile into target dir - zipfile.py -c zipfile.zip src ... # Create zipfile from sources - """) - if args is None: - args = sys.argv[1:] - - if not args or args[0] not in ('-l', '-c', '-e', '-t'): - print(USAGE) - sys.exit(1) - - if args[0] == '-l': - if len(args) != 2: - print(USAGE) - sys.exit(1) - with ZipFile(args[1], 'r') as zf: - zf.printdir() - - elif args[0] == '-t': - if len(args) != 2: - print(USAGE) - sys.exit(1) - with ZipFile(args[1], 'r') as zf: +def main(args=None): + import argparse + + description = 'A simple command line interface for zipfile module.' + parser = argparse.ArgumentParser(description=description) + group = parser.add_mutually_exclusive_group() + group.add_argument('-l', '--list', metavar='<zipfile>', + help='Show listing of a zipfile') + group.add_argument('-e', '--extract', nargs=2, + metavar=('<zipfile>', '<output_dir>'), + help='Extract zipfile into target dir') + group.add_argument('-c', '--create', nargs='+', + metavar=('<name>', '<file>'), + help='Create zipfile from sources') + group.add_argument('-t', '--test', metavar='<zipfile>', + help='Test if a zipfile is valid') + args = parser.parse_args(args) + + if args.test is not None: + src = args.test + with ZipFile(src, 'r') as zf: badfile = zf.testzip() if badfile: print("The following enclosed file is corrupted: {!r}".format(badfile)) print("Done testing") - elif args[0] == '-e': - if len(args) != 3: - print(USAGE) - sys.exit(1) + elif args.list is not None: + src = args.list + with ZipFile(src, 'r') as zf: + zf.printdir() - with ZipFile(args[1], 'r') as zf: - zf.extractall(args[2]) + elif args.extract is not None: + src, curdir = args.extract + with ZipFile(src, 'r') as zf: + zf.extractall(curdir) - elif args[0] == '-c': - if len(args) < 3: - print(USAGE) - sys.exit(1) + elif args.create is not None: + zip_name = args.create.pop(0) + files = args.create def addToZip(zf, path, zippath): if os.path.isfile(path): @@ -2007,8 +2000,8 @@ def main(args = None): os.path.join(path, nm), os.path.join(zippath, nm)) # else: ignore - with ZipFile(args[1], 'w') as zf: - for path in args[2:]: + with ZipFile(zip_name, 'w') as zf: + for path in files: zippath = os.path.basename(path) if not zippath: zippath = os.path.basename(os.path.dirname(path)) @@ -2016,5 +2009,8 @@ def main(args = None): zippath = '' addToZip(zf, path, zippath) + else: + parser.exit(2, parser.format_usage()) + if __name__ == "__main__": main() |