summaryrefslogtreecommitdiffstats
path: root/Lib/test
diff options
context:
space:
mode:
Diffstat (limited to 'Lib/test')
-rw-r--r--Lib/test/datetimetester.py38
-rw-r--r--Lib/test/eintrdata/eintr_tester.py251
-rw-r--r--Lib/test/test_argparse.py15
-rw-r--r--Lib/test/test_collections.py8
-rw-r--r--Lib/test/test_dictviews.py22
-rw-r--r--Lib/test/test_file.py2
-rw-r--r--Lib/test/test_grammar.py38
-rw-r--r--Lib/test/test_inspect.py42
-rw-r--r--Lib/test/test_itertools.py50
-rw-r--r--Lib/test/test_linecache.py75
-rw-r--r--Lib/test/test_operator.py83
-rw-r--r--Lib/test/test_os.py19
-rw-r--r--Lib/test/test_pydoc.py16
-rw-r--r--Lib/test/test_set.py24
-rw-r--r--Lib/test/test_symbol.py55
-rw-r--r--Lib/test/test_time.py373
-rw-r--r--Lib/test/test_urlparse.py36
-rw-r--r--Lib/test/test_warnings/data/import_warning.py2
-rw-r--r--Lib/test/test_zipimport.py21
19 files changed, 913 insertions, 257 deletions
diff --git a/Lib/test/datetimetester.py b/Lib/test/datetimetester.py
index babeb44..f23add3 100644
--- a/Lib/test/datetimetester.py
+++ b/Lib/test/datetimetester.py
@@ -258,7 +258,8 @@ class TestTimeZone(unittest.TestCase):
with self.assertRaises(TypeError): self.EST.dst(5)
def test_tzname(self):
- self.assertEqual('UTC+00:00', timezone(ZERO).tzname(None))
+ self.assertEqual('UTC', timezone.utc.tzname(None))
+ self.assertEqual('UTC', timezone(ZERO).tzname(None))
self.assertEqual('UTC-05:00', timezone(-5 * HOUR).tzname(None))
self.assertEqual('UTC+09:30', timezone(9.5 * HOUR).tzname(None))
self.assertEqual('UTC-00:01', timezone(timedelta(minutes=-1)).tzname(None))
@@ -662,28 +663,26 @@ class TestTimeDelta(HarmlessMixedComparison, unittest.TestCase):
# Single-field rounding.
eq(td(milliseconds=0.4/1000), td(0)) # rounds to 0
eq(td(milliseconds=-0.4/1000), td(0)) # rounds to 0
- eq(td(milliseconds=0.5/1000), td(microseconds=0))
- eq(td(milliseconds=-0.5/1000), td(microseconds=0))
+ eq(td(milliseconds=0.5/1000), td(microseconds=1))
+ eq(td(milliseconds=-0.5/1000), td(microseconds=-1))
eq(td(milliseconds=0.6/1000), td(microseconds=1))
eq(td(milliseconds=-0.6/1000), td(microseconds=-1))
- eq(td(seconds=0.5/10**6), td(microseconds=0))
- eq(td(seconds=-0.5/10**6), td(microseconds=0))
+ eq(td(seconds=0.5/10**6), td(microseconds=1))
+ eq(td(seconds=-0.5/10**6), td(microseconds=-1))
+ eq(td(seconds=1/2**7), td(microseconds=7813))
+ eq(td(seconds=-1/2**7), td(microseconds=-7813))
# Rounding due to contributions from more than one field.
us_per_hour = 3600e6
us_per_day = us_per_hour * 24
eq(td(days=.4/us_per_day), td(0))
eq(td(hours=.2/us_per_hour), td(0))
- eq(td(days=.4/us_per_day, hours=.2/us_per_hour), td(microseconds=1))
+ eq(td(days=.4/us_per_day, hours=.2/us_per_hour), td(microseconds=1), td)
eq(td(days=-.4/us_per_day), td(0))
eq(td(hours=-.2/us_per_hour), td(0))
eq(td(days=-.4/us_per_day, hours=-.2/us_per_hour), td(microseconds=-1))
- # Test for a patch in Issue 8860
- eq(td(microseconds=0.5), 0.5*td(microseconds=1.0))
- eq(td(microseconds=0.5)//td.resolution, 0.5*td.resolution//td.resolution)
-
def test_massive_normalization(self):
td = timedelta(microseconds=-1)
self.assertEqual((td.days, td.seconds, td.microseconds),
@@ -1846,11 +1845,12 @@ class TestDateTime(TestDate):
18000 + 3600 + 2*60 + 3 + 4*1e-6)
def test_microsecond_rounding(self):
- for fts in [self.theclass.fromtimestamp,
- self.theclass.utcfromtimestamp]:
+ for fts in (datetime.fromtimestamp,
+ self.theclass.utcfromtimestamp):
zero = fts(0)
self.assertEqual(zero.second, 0)
self.assertEqual(zero.microsecond, 0)
+ one = fts(1e-6)
try:
minus_one = fts(-1e-6)
except OSError:
@@ -1861,22 +1861,28 @@ class TestDateTime(TestDate):
self.assertEqual(minus_one.microsecond, 999999)
t = fts(-1e-8)
- self.assertEqual(t, minus_one)
+ self.assertEqual(t, zero)
t = fts(-9e-7)
self.assertEqual(t, minus_one)
t = fts(-1e-7)
- self.assertEqual(t, minus_one)
+ self.assertEqual(t, zero)
+ t = fts(-1/2**7)
+ self.assertEqual(t.second, 59)
+ self.assertEqual(t.microsecond, 992187)
t = fts(1e-7)
self.assertEqual(t, zero)
t = fts(9e-7)
- self.assertEqual(t, zero)
+ self.assertEqual(t, one)
t = fts(0.99999949)
self.assertEqual(t.second, 0)
self.assertEqual(t.microsecond, 999999)
t = fts(0.9999999)
+ self.assertEqual(t.second, 1)
+ self.assertEqual(t.microsecond, 0)
+ t = fts(1/2**7)
self.assertEqual(t.second, 0)
- self.assertEqual(t.microsecond, 999999)
+ self.assertEqual(t.microsecond, 7813)
def test_insane_fromtimestamp(self):
# It's possible that some platform maps time_t to double,
diff --git a/Lib/test/eintrdata/eintr_tester.py b/Lib/test/eintrdata/eintr_tester.py
index f755880..0616df6 100644
--- a/Lib/test/eintrdata/eintr_tester.py
+++ b/Lib/test/eintrdata/eintr_tester.py
@@ -13,6 +13,8 @@ import os
import select
import signal
import socket
+import subprocess
+import sys
import time
import unittest
@@ -28,7 +30,7 @@ class EINTRBaseTest(unittest.TestCase):
# signal delivery periodicity
signal_period = 0.1
# default sleep time for tests - should obviously have:
- # sleep_time > signal_period
+ # sleep_time > signal_period
sleep_time = 0.2
@classmethod
@@ -51,18 +53,22 @@ class EINTRBaseTest(unittest.TestCase):
# default sleep time
time.sleep(cls.sleep_time)
+ def subprocess(self, *args, **kw):
+ cmd_args = (sys.executable, '-c') + args
+ return subprocess.Popen(cmd_args, **kw)
+
@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()")
class OSEINTRTest(EINTRBaseTest):
""" EINTR tests for the os module. """
+ def new_sleep_process(self):
+ code = 'import time; time.sleep(%r)' % self.sleep_time
+ return self.subprocess(code)
+
def _test_wait_multiple(self, wait_func):
num = 3
- for _ in range(num):
- pid = os.fork()
- if pid == 0:
- self._sleep()
- os._exit(0)
+ processes = [self.new_sleep_process() for _ in range(num)]
for _ in range(num):
wait_func()
@@ -74,12 +80,8 @@ class OSEINTRTest(EINTRBaseTest):
self._test_wait_multiple(lambda: os.wait3(0))
def _test_wait_single(self, wait_func):
- pid = os.fork()
- if pid == 0:
- self._sleep()
- os._exit(0)
- else:
- wait_func(pid)
+ proc = self.new_sleep_process()
+ wait_func(proc.pid)
def test_waitpid(self):
self._test_wait_single(lambda pid: os.waitpid(pid, 0))
@@ -97,19 +99,24 @@ class OSEINTRTest(EINTRBaseTest):
# atomic
datas = [b"hello", b"world", b"spam"]
- pid = os.fork()
- if pid == 0:
- os.close(rd)
- for data in datas:
- # let the parent block on read()
- self._sleep()
- os.write(wr, data)
- os._exit(0)
- else:
- self.addCleanup(os.waitpid, pid, 0)
+ code = '\n'.join((
+ 'import os, sys, time',
+ '',
+ 'wr = int(sys.argv[1])',
+ 'datas = %r' % datas,
+ 'sleep_time = %r' % self.sleep_time,
+ '',
+ 'for data in datas:',
+ ' # let the parent block on read()',
+ ' time.sleep(sleep_time)',
+ ' os.write(wr, data)',
+ ))
+
+ with self.subprocess(code, str(wr), pass_fds=[wr]) as proc:
os.close(wr)
for data in datas:
self.assertEqual(data, os.read(rd, len(data)))
+ self.assertEqual(proc.wait(), 0)
def test_write(self):
rd, wr = os.pipe()
@@ -119,23 +126,34 @@ class OSEINTRTest(EINTRBaseTest):
# we must write enough data for the write() to block
data = b"xyz" * support.PIPE_MAX_SIZE
- pid = os.fork()
- if pid == 0:
- os.close(wr)
- read_data = io.BytesIO()
- # let the parent block on write()
- self._sleep()
- while len(read_data.getvalue()) < len(data):
- chunk = os.read(rd, 2 * len(data))
- read_data.write(chunk)
- self.assertEqual(read_data.getvalue(), data)
- os._exit(0)
- else:
+ code = '\n'.join((
+ 'import io, os, sys, time',
+ '',
+ 'rd = int(sys.argv[1])',
+ 'sleep_time = %r' % self.sleep_time,
+ 'data = b"xyz" * %s' % support.PIPE_MAX_SIZE,
+ 'data_len = len(data)',
+ '',
+ '# let the parent block on write()',
+ 'time.sleep(sleep_time)',
+ '',
+ 'read_data = io.BytesIO()',
+ 'while len(read_data.getvalue()) < data_len:',
+ ' chunk = os.read(rd, 2 * data_len)',
+ ' read_data.write(chunk)',
+ '',
+ 'value = read_data.getvalue()',
+ 'if value != data:',
+ ' raise Exception("read error: %s vs %s bytes"',
+ ' % (len(value), data_len))',
+ ))
+
+ with self.subprocess(code, str(rd), pass_fds=[rd]) as proc:
os.close(rd)
written = 0
while written < len(data):
written += os.write(wr, memoryview(data)[written:])
- self.assertEqual(0, os.waitpid(pid, 0)[1])
+ self.assertEqual(proc.wait(), 0)
@unittest.skipUnless(hasattr(signal, "setitimer"), "requires setitimer()")
@@ -151,19 +169,32 @@ class SocketEINTRTest(EINTRBaseTest):
# single-byte payload guard us against partial recv
datas = [b"x", b"y", b"z"]
- pid = os.fork()
- if pid == 0:
- rd.close()
- for data in datas:
- # let the parent block on recv()
- self._sleep()
- wr.sendall(data)
- os._exit(0)
- else:
- self.addCleanup(os.waitpid, pid, 0)
+ code = '\n'.join((
+ 'import os, socket, sys, time',
+ '',
+ 'fd = int(sys.argv[1])',
+ 'family = %s' % int(wr.family),
+ 'sock_type = %s' % int(wr.type),
+ 'datas = %r' % datas,
+ 'sleep_time = %r' % self.sleep_time,
+ '',
+ 'wr = socket.fromfd(fd, family, sock_type)',
+ 'os.close(fd)',
+ '',
+ 'with wr:',
+ ' for data in datas:',
+ ' # let the parent block on recv()',
+ ' time.sleep(sleep_time)',
+ ' wr.sendall(data)',
+ ))
+
+ fd = wr.fileno()
+ proc = self.subprocess(code, str(fd), pass_fds=[fd])
+ with proc:
wr.close()
for data in datas:
self.assertEqual(data, recv_func(rd, len(data)))
+ self.assertEqual(proc.wait(), 0)
def test_recv(self):
self._test_recv(socket.socket.recv)
@@ -180,25 +211,43 @@ class SocketEINTRTest(EINTRBaseTest):
# we must send enough data for the send() to block
data = b"xyz" * (support.SOCK_MAX_SIZE // 3)
- pid = os.fork()
- if pid == 0:
- wr.close()
- # let the parent block on send()
- self._sleep()
- received_data = bytearray(len(data))
- n = 0
- while n < len(data):
- n += rd.recv_into(memoryview(received_data)[n:])
- self.assertEqual(received_data, data)
- os._exit(0)
- else:
+ code = '\n'.join((
+ 'import os, socket, sys, time',
+ '',
+ 'fd = int(sys.argv[1])',
+ 'family = %s' % int(rd.family),
+ 'sock_type = %s' % int(rd.type),
+ 'sleep_time = %r' % self.sleep_time,
+ 'data = b"xyz" * %s' % (support.SOCK_MAX_SIZE // 3),
+ 'data_len = len(data)',
+ '',
+ 'rd = socket.fromfd(fd, family, sock_type)',
+ 'os.close(fd)',
+ '',
+ 'with rd:',
+ ' # let the parent block on send()',
+ ' time.sleep(sleep_time)',
+ '',
+ ' received_data = bytearray(data_len)',
+ ' n = 0',
+ ' while n < data_len:',
+ ' n += rd.recv_into(memoryview(received_data)[n:])',
+ '',
+ 'if received_data != data:',
+ ' raise Exception("recv error: %s vs %s bytes"',
+ ' % (len(received_data), data_len))',
+ ))
+
+ fd = rd.fileno()
+ proc = self.subprocess(code, str(fd), pass_fds=[fd])
+ with proc:
rd.close()
written = 0
while written < len(data):
sent = send_func(wr, memoryview(data)[written:])
# sendall() returns None
written += len(data) if sent is None else sent
- self.assertEqual(0, os.waitpid(pid, 0)[1])
+ self.assertEqual(proc.wait(), 0)
def test_send(self):
self._test_send(socket.socket.send)
@@ -215,45 +264,60 @@ class SocketEINTRTest(EINTRBaseTest):
self.addCleanup(sock.close)
sock.bind((support.HOST, 0))
- _, port = sock.getsockname()
+ port = sock.getsockname()[1]
sock.listen()
- pid = os.fork()
- if pid == 0:
- # let parent block on accept()
- self._sleep()
- with socket.create_connection((support.HOST, port)):
- self._sleep()
- os._exit(0)
- else:
- self.addCleanup(os.waitpid, pid, 0)
+ code = '\n'.join((
+ 'import socket, time',
+ '',
+ 'host = %r' % support.HOST,
+ 'port = %s' % port,
+ 'sleep_time = %r' % self.sleep_time,
+ '',
+ '# let parent block on accept()',
+ 'time.sleep(sleep_time)',
+ 'with socket.create_connection((host, port)):',
+ ' time.sleep(sleep_time)',
+ ))
+
+ with self.subprocess(code) as proc:
client_sock, _ = sock.accept()
client_sock.close()
+ self.assertEqual(proc.wait(), 0)
@unittest.skipUnless(hasattr(os, 'mkfifo'), 'needs mkfifo()')
def _test_open(self, do_open_close_reader, do_open_close_writer):
+ filename = support.TESTFN
+
# Use a fifo: until the child opens it for reading, the parent will
# block when trying to open it for writing.
- support.unlink(support.TESTFN)
- os.mkfifo(support.TESTFN)
- self.addCleanup(support.unlink, support.TESTFN)
-
- pid = os.fork()
- if pid == 0:
- # let the parent block
- self._sleep()
- do_open_close_reader(support.TESTFN)
- os._exit(0)
- else:
- self.addCleanup(os.waitpid, pid, 0)
- do_open_close_writer(support.TESTFN)
+ support.unlink(filename)
+ os.mkfifo(filename)
+ self.addCleanup(support.unlink, filename)
+
+ code = '\n'.join((
+ 'import os, time',
+ '',
+ 'path = %a' % filename,
+ 'sleep_time = %r' % self.sleep_time,
+ '',
+ '# let the parent block',
+ 'time.sleep(sleep_time)',
+ '',
+ do_open_close_reader,
+ ))
+
+ with self.subprocess(code) as proc:
+ do_open_close_writer(filename)
+
+ self.assertEqual(proc.wait(), 0)
def test_open(self):
- self._test_open(lambda path: open(path, 'r').close(),
+ self._test_open("open(path, 'r').close()",
lambda path: open(path, 'w').close())
def test_os_open(self):
- self._test_open(lambda path: os.close(os.open(path, os.O_RDONLY)),
+ self._test_open("os.close(os.open(path, os.O_RDONLY))",
lambda path: os.close(os.open(path, os.O_WRONLY)))
@@ -290,20 +354,21 @@ class SignalEINTRTest(EINTRBaseTest):
old_handler = signal.signal(signum, lambda *args: None)
self.addCleanup(signal.signal, signum, old_handler)
+ code = '\n'.join((
+ 'import os, time',
+ 'pid = %s' % os.getpid(),
+ 'signum = %s' % int(signum),
+ 'sleep_time = %r' % self.sleep_time,
+ 'time.sleep(sleep_time)',
+ 'os.kill(pid, signum)',
+ ))
+
t0 = time.monotonic()
- child_pid = os.fork()
- if child_pid == 0:
- # child
- try:
- self._sleep()
- os.kill(pid, signum)
- finally:
- os._exit(0)
- else:
+ with self.subprocess(code) as proc:
# parent
signal.sigwaitinfo([signum])
dt = time.monotonic() - t0
- os.waitpid(child_pid, 0)
+ self.assertEqual(proc.wait(), 0)
self.assertGreaterEqual(dt, self.sleep_time)
diff --git a/Lib/test/test_argparse.py b/Lib/test/test_argparse.py
index 27bfad5..893ec39 100644
--- a/Lib/test/test_argparse.py
+++ b/Lib/test/test_argparse.py
@@ -4512,6 +4512,21 @@ class TestStrings(TestCase):
string = "Namespace(bar='spam', foo=42)"
self.assertStringEqual(ns, string)
+ def test_namespace_starkwargs_notidentifier(self):
+ ns = argparse.Namespace(**{'"': 'quote'})
+ string = """Namespace(**{'"': 'quote'})"""
+ self.assertStringEqual(ns, string)
+
+ def test_namespace_kwargs_and_starkwargs_notidentifier(self):
+ ns = argparse.Namespace(a=1, **{'"': 'quote'})
+ string = """Namespace(a=1, **{'"': 'quote'})"""
+ self.assertStringEqual(ns, string)
+
+ def test_namespace_starkwargs_identifier(self):
+ ns = argparse.Namespace(**{'valid': True})
+ string = "Namespace(valid=True)"
+ self.assertStringEqual(ns, string)
+
def test_parser(self):
parser = argparse.ArgumentParser(prog='PROG')
string = (
diff --git a/Lib/test/test_collections.py b/Lib/test/test_collections.py
index 4124f91..cd238bc 100644
--- a/Lib/test/test_collections.py
+++ b/Lib/test/test_collections.py
@@ -2002,6 +2002,14 @@ class OrderedDictTests:
od = OrderedDict(**d)
self.assertGreater(sys.getsizeof(od), sys.getsizeof(d))
+ def test_views(self):
+ OrderedDict = self.module.OrderedDict
+ # See http://bugs.python.org/issue24286
+ s = 'the quick brown fox jumped over a lazy dog yesterday before dawn'.split()
+ od = OrderedDict.fromkeys(s)
+ self.assertEqual(od.keys(), dict(od).keys())
+ self.assertEqual(od.items(), dict(od).items())
+
def test_override_update(self):
OrderedDict = self.module.OrderedDict
# Verify that subclasses can override update() without breaking __init__()
diff --git a/Lib/test/test_dictviews.py b/Lib/test/test_dictviews.py
index 8d33801..fcb6814 100644
--- a/Lib/test/test_dictviews.py
+++ b/Lib/test/test_dictviews.py
@@ -1,3 +1,4 @@
+import collections
import unittest
class DictSetTest(unittest.TestCase):
@@ -197,6 +198,27 @@ class DictSetTest(unittest.TestCase):
d[42] = d.values()
self.assertRaises(RecursionError, repr, d)
+ def test_abc_registry(self):
+ d = dict(a=1)
+
+ self.assertIsInstance(d.keys(), collections.KeysView)
+ self.assertIsInstance(d.keys(), collections.MappingView)
+ self.assertIsInstance(d.keys(), collections.Set)
+ self.assertIsInstance(d.keys(), collections.Sized)
+ self.assertIsInstance(d.keys(), collections.Iterable)
+ self.assertIsInstance(d.keys(), collections.Container)
+
+ self.assertIsInstance(d.values(), collections.ValuesView)
+ self.assertIsInstance(d.values(), collections.MappingView)
+ self.assertIsInstance(d.values(), collections.Sized)
+
+ self.assertIsInstance(d.items(), collections.ItemsView)
+ self.assertIsInstance(d.items(), collections.MappingView)
+ self.assertIsInstance(d.items(), collections.Set)
+ self.assertIsInstance(d.items(), collections.Sized)
+ self.assertIsInstance(d.items(), collections.Iterable)
+ self.assertIsInstance(d.items(), collections.Container)
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_file.py b/Lib/test/test_file.py
index 4e392b7..67c3d86 100644
--- a/Lib/test/test_file.py
+++ b/Lib/test/test_file.py
@@ -139,7 +139,7 @@ class OtherFileTests:
def testModeStrings(self):
# check invalid mode strings
- for mode in ("", "aU", "wU+"):
+ for mode in ("", "aU", "wU+", "U+", "+U", "rU+"):
try:
f = self.open(TESTFN, mode)
except ValueError:
diff --git a/Lib/test/test_grammar.py b/Lib/test/test_grammar.py
index ec3d783..8f8d71c 100644
--- a/Lib/test/test_grammar.py
+++ b/Lib/test/test_grammar.py
@@ -295,6 +295,10 @@ class GrammarTests(unittest.TestCase):
pos2key2dict(1,2,k2=100,tokwarg1=100,tokwarg2=200)
pos2key2dict(1,2,tokwarg1=100,tokwarg2=200, k2=100)
+ self.assertRaises(SyntaxError, eval, "def f(*): pass")
+ self.assertRaises(SyntaxError, eval, "def f(*,): pass")
+ self.assertRaises(SyntaxError, eval, "def f(*, **kwds): pass")
+
# keyword arguments after *arglist
def f(*args, **kwargs):
return args, kwargs
@@ -352,6 +356,23 @@ class GrammarTests(unittest.TestCase):
check_syntax_error(self, "f(*g(1=2))")
check_syntax_error(self, "f(**g(1=2))")
+ # Check trailing commas are permitted in funcdef argument list
+ def f(a,): pass
+ def f(*args,): pass
+ def f(**kwds,): pass
+ def f(a, *args,): pass
+ def f(a, **kwds,): pass
+ def f(*args, b,): pass
+ def f(*, b,): pass
+ def f(*args, **kwds,): pass
+ def f(a, *args, b,): pass
+ def f(a, *, b,): pass
+ def f(a, *args, **kwds,): pass
+ def f(*args, b, **kwds,): pass
+ def f(*, b, **kwds,): pass
+ def f(a, *args, b, **kwds,): pass
+ def f(a, *, b, **kwds,): pass
+
def test_lambdef(self):
### lambdef: 'lambda' [varargslist] ':' test
l1 = lambda : 0
@@ -370,6 +391,23 @@ class GrammarTests(unittest.TestCase):
self.assertEqual(l6(1,2), 1+2+20)
self.assertEqual(l6(1,2,k=10), 1+2+10)
+ # check that trailing commas are permitted
+ l10 = lambda a,: 0
+ l11 = lambda *args,: 0
+ l12 = lambda **kwds,: 0
+ l13 = lambda a, *args,: 0
+ l14 = lambda a, **kwds,: 0
+ l15 = lambda *args, b,: 0
+ l16 = lambda *, b,: 0
+ l17 = lambda *args, **kwds,: 0
+ l18 = lambda a, *args, b,: 0
+ l19 = lambda a, *, b,: 0
+ l20 = lambda a, *args, **kwds,: 0
+ l21 = lambda *args, b, **kwds,: 0
+ l22 = lambda *, b, **kwds,: 0
+ l23 = lambda a, *args, b, **kwds,: 0
+ l24 = lambda a, *, b, **kwds,: 0
+
### stmt: simple_stmt | compound_stmt
# Tested below
diff --git a/Lib/test/test_inspect.py b/Lib/test/test_inspect.py
index 955b2ad..db15b39 100644
--- a/Lib/test/test_inspect.py
+++ b/Lib/test/test_inspect.py
@@ -38,7 +38,7 @@ from test.test_import import _ready_to_import
# ismodule, isclass, ismethod, isfunction, istraceback, isframe, iscode,
# isbuiltin, isroutine, isgenerator, isgeneratorfunction, getmembers,
# getdoc, getfile, getmodule, getsourcefile, getcomments, getsource,
-# getclasstree, getargspec, getargvalues, formatargspec, formatargvalues,
+# getclasstree, getargvalues, formatargspec, formatargvalues,
# currentframe, stack, trace, isdatadescriptor
# NOTE: There are some additional tests relating to interaction with
@@ -628,18 +628,6 @@ class TestClassesAndFunctions(unittest.TestCase):
got = inspect.getmro(D)
self.assertEqual(expected, got)
- def assertArgSpecEquals(self, routine, args_e, varargs_e=None,
- varkw_e=None, defaults_e=None, formatted=None):
- with self.assertWarns(DeprecationWarning):
- args, varargs, varkw, defaults = inspect.getargspec(routine)
- self.assertEqual(args, args_e)
- self.assertEqual(varargs, varargs_e)
- self.assertEqual(varkw, varkw_e)
- self.assertEqual(defaults, defaults_e)
- if formatted is not None:
- self.assertEqual(inspect.formatargspec(args, varargs, varkw, defaults),
- formatted)
-
def assertFullArgSpecEquals(self, routine, args_e, varargs_e=None,
varkw_e=None, defaults_e=None,
kwonlyargs_e=[], kwonlydefaults_e=None,
@@ -658,23 +646,6 @@ class TestClassesAndFunctions(unittest.TestCase):
kwonlyargs, kwonlydefaults, ann),
formatted)
- def test_getargspec(self):
- self.assertArgSpecEquals(mod.eggs, ['x', 'y'], formatted='(x, y)')
-
- self.assertArgSpecEquals(mod.spam,
- ['a', 'b', 'c', 'd', 'e', 'f'],
- 'g', 'h', (3, 4, 5),
- '(a, b, c, d=3, e=4, f=5, *g, **h)')
-
- self.assertRaises(ValueError, self.assertArgSpecEquals,
- mod2.keyworded, [])
-
- self.assertRaises(ValueError, self.assertArgSpecEquals,
- mod2.annotated, [])
- self.assertRaises(ValueError, self.assertArgSpecEquals,
- mod2.keyword_only_arg, [])
-
-
def test_getfullargspec(self):
self.assertFullArgSpecEquals(mod2.keyworded, [], varargs_e='arg1',
kwonlyargs_e=['arg2'],
@@ -688,20 +659,19 @@ class TestClassesAndFunctions(unittest.TestCase):
kwonlyargs_e=['arg'],
formatted='(*, arg)')
- def test_argspec_api_ignores_wrapped(self):
+ def test_fullargspec_api_ignores_wrapped(self):
# Issue 20684: low level introspection API must ignore __wrapped__
@functools.wraps(mod.spam)
def ham(x, y):
pass
# Basic check
- self.assertArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
self.assertFullArgSpecEquals(ham, ['x', 'y'], formatted='(x, y)')
self.assertFullArgSpecEquals(functools.partial(ham),
['x', 'y'], formatted='(x, y)')
# Other variants
def check_method(f):
- self.assertArgSpecEquals(f, ['self', 'x', 'y'],
- formatted='(self, x, y)')
+ self.assertFullArgSpecEquals(f, ['self', 'x', 'y'],
+ formatted='(self, x, y)')
class C:
@functools.wraps(mod.spam)
def ham(self, x, y):
@@ -779,11 +749,11 @@ class TestClassesAndFunctions(unittest.TestCase):
with self.assertRaises(TypeError):
inspect.getfullargspec(builtin)
- def test_getargspec_method(self):
+ def test_getfullargspec_method(self):
class A(object):
def m(self):
pass
- self.assertArgSpecEquals(A.m, ['self'])
+ self.assertFullArgSpecEquals(A.m, ['self'])
def test_classify_newstyle(self):
class A(object):
diff --git a/Lib/test/test_itertools.py b/Lib/test/test_itertools.py
index fcd8869..81e1711 100644
--- a/Lib/test/test_itertools.py
+++ b/Lib/test/test_itertools.py
@@ -613,6 +613,56 @@ class TestBasicOps(unittest.TestCase):
for proto in range(pickle.HIGHEST_PROTOCOL + 1):
self.pickletest(proto, cycle('abc'))
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ # test with partial consumed input iterable
+ it = iter('abcde')
+ c = cycle(it)
+ _ = [next(c) for i in range(2)] # consume 2 of 5 inputs
+ p = pickle.dumps(c, proto)
+ d = pickle.loads(p) # rebuild the cycle object
+ self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab'))
+
+ # test with completely consumed input iterable
+ it = iter('abcde')
+ c = cycle(it)
+ _ = [next(c) for i in range(7)] # consume 7 of 5 inputs
+ p = pickle.dumps(c, proto)
+ d = pickle.loads(p) # rebuild the cycle object
+ self.assertEqual(take(20, d), list('cdeabcdeabcdeabcdeab'))
+
+ def test_cycle_setstate(self):
+ # Verify both modes for restoring state
+
+ # Mode 0 is efficient. It uses an incompletely consumed input
+ # iterator to build a cycle object and then passes in state with
+ # a list of previously consumed values. There is no data
+ # overlap bewteen the two.
+ c = cycle('defg')
+ c.__setstate__((list('abc'), 0))
+ self.assertEqual(take(20, c), list('defgabcdefgabcdefgab'))
+
+ # Mode 1 is inefficient. It starts with a cycle object built
+ # from an iterator over the remaining elements in a partial
+ # cycle and then passes in state with all of the previously
+ # seen values (this overlaps values included in the iterator).
+ c = cycle('defg')
+ c.__setstate__((list('abcdefg'), 1))
+ self.assertEqual(take(20, c), list('defgabcdefgabcdefgab'))
+
+ # The first argument to setstate needs to be a tuple
+ with self.assertRaises(SystemError):
+ cycle('defg').__setstate__([list('abcdefg'), 0])
+
+ # The first argument in the setstate tuple must be a list
+ with self.assertRaises(TypeError):
+ c = cycle('defg')
+ c.__setstate__((dict.fromkeys('defg'), 0))
+ take(20, c)
+
+ # The first argument in the setstate tuple must be a list
+ with self.assertRaises(TypeError):
+ cycle('defg').__setstate__((list('abcdefg'), 'x'))
+
def test_groupby(self):
# Check whether it accepts arguments correctly
self.assertEqual([], list(groupby([])))
diff --git a/Lib/test/test_linecache.py b/Lib/test/test_linecache.py
index 21ef738..240db7f 100644
--- a/Lib/test/test_linecache.py
+++ b/Lib/test/test_linecache.py
@@ -3,6 +3,8 @@
import linecache
import unittest
import os.path
+import tempfile
+import tokenize
from test import support
@@ -10,8 +12,6 @@ FILENAME = linecache.__file__
NONEXISTENT_FILENAME = FILENAME + '.missing'
INVALID_NAME = '!@$)(!@#_1'
EMPTY = ''
-TESTS = 'inspect_fodder inspect_fodder2 mapping_tests'
-TESTS = TESTS.split()
TEST_PATH = os.path.dirname(__file__)
MODULES = "linecache abc".split()
MODULE_PATH = os.path.dirname(FILENAME)
@@ -37,6 +37,65 @@ def f():
return 3''' # No ending newline
+class TempFile:
+
+ def setUp(self):
+ super().setUp()
+ with tempfile.NamedTemporaryFile(delete=False) as fp:
+ self.file_name = fp.name
+ fp.write(self.file_byte_string)
+ self.addCleanup(support.unlink, self.file_name)
+
+
+class GetLineTestsGoodData(TempFile):
+ # file_list = ['list\n', 'of\n', 'good\n', 'strings\n']
+
+ def setUp(self):
+ self.file_byte_string = ''.join(self.file_list).encode('utf-8')
+ super().setUp()
+
+ def test_getline(self):
+ with tokenize.open(self.file_name) as fp:
+ for index, line in enumerate(fp):
+ if not line.endswith('\n'):
+ line += '\n'
+
+ cached_line = linecache.getline(self.file_name, index + 1)
+ self.assertEqual(line, cached_line)
+
+ def test_getlines(self):
+ lines = linecache.getlines(self.file_name)
+ self.assertEqual(lines, self.file_list)
+
+
+class GetLineTestsBadData(TempFile):
+ # file_byte_string = b'Bad data goes here'
+
+ def test_getline(self):
+ self.assertRaises((SyntaxError, UnicodeDecodeError),
+ linecache.getline, self.file_name, 1)
+
+ def test_getlines(self):
+ self.assertRaises((SyntaxError, UnicodeDecodeError),
+ linecache.getlines, self.file_name)
+
+
+class EmptyFile(GetLineTestsGoodData, unittest.TestCase):
+ file_list = []
+
+
+class SingleEmptyLine(GetLineTestsGoodData, unittest.TestCase):
+ file_list = ['\n']
+
+
+class GoodUnicode(GetLineTestsGoodData, unittest.TestCase):
+ file_list = ['á\n', 'b\n', 'abcdef\n', 'ááááá\n']
+
+
+class BadUnicode(GetLineTestsBadData, unittest.TestCase):
+ file_byte_string = b'\x80abc'
+
+
class LineCacheTests(unittest.TestCase):
def test_getline(self):
@@ -53,13 +112,6 @@ class LineCacheTests(unittest.TestCase):
self.assertEqual(getline(EMPTY, 1), EMPTY)
self.assertEqual(getline(INVALID_NAME, 1), EMPTY)
- # Check whether lines correspond to those from file iteration
- for entry in TESTS:
- filename = os.path.join(TEST_PATH, entry) + '.py'
- with open(filename) as file:
- for index, line in enumerate(file):
- self.assertEqual(line, getline(filename, index + 1))
-
# Check module loading
for entry in MODULES:
filename = os.path.join(MODULE_PATH, entry) + '.py'
@@ -80,12 +132,13 @@ class LineCacheTests(unittest.TestCase):
def test_clearcache(self):
cached = []
- for entry in TESTS:
- filename = os.path.join(TEST_PATH, entry) + '.py'
+ for entry in MODULES:
+ filename = os.path.join(MODULE_PATH, entry) + '.py'
cached.append(filename)
linecache.getline(filename, 1)
# Are all files cached?
+ self.assertNotEqual(cached, [])
cached_empty = [fn for fn in cached if fn not in linecache.cache]
self.assertEqual(cached_empty, [])
diff --git a/Lib/test/test_operator.py b/Lib/test/test_operator.py
index da9c8ef..27501c2 100644
--- a/Lib/test/test_operator.py
+++ b/Lib/test/test_operator.py
@@ -120,63 +120,63 @@ class OperatorTestCase:
operator = self.module
self.assertRaises(TypeError, operator.add)
self.assertRaises(TypeError, operator.add, None, None)
- self.assertTrue(operator.add(3, 4) == 7)
+ self.assertEqual(operator.add(3, 4), 7)
def test_bitwise_and(self):
operator = self.module
self.assertRaises(TypeError, operator.and_)
self.assertRaises(TypeError, operator.and_, None, None)
- self.assertTrue(operator.and_(0xf, 0xa) == 0xa)
+ self.assertEqual(operator.and_(0xf, 0xa), 0xa)
def test_concat(self):
operator = self.module
self.assertRaises(TypeError, operator.concat)
self.assertRaises(TypeError, operator.concat, None, None)
- self.assertTrue(operator.concat('py', 'thon') == 'python')
- self.assertTrue(operator.concat([1, 2], [3, 4]) == [1, 2, 3, 4])
- self.assertTrue(operator.concat(Seq1([5, 6]), Seq1([7])) == [5, 6, 7])
- self.assertTrue(operator.concat(Seq2([5, 6]), Seq2([7])) == [5, 6, 7])
+ self.assertEqual(operator.concat('py', 'thon'), 'python')
+ self.assertEqual(operator.concat([1, 2], [3, 4]), [1, 2, 3, 4])
+ self.assertEqual(operator.concat(Seq1([5, 6]), Seq1([7])), [5, 6, 7])
+ self.assertEqual(operator.concat(Seq2([5, 6]), Seq2([7])), [5, 6, 7])
self.assertRaises(TypeError, operator.concat, 13, 29)
def test_countOf(self):
operator = self.module
self.assertRaises(TypeError, operator.countOf)
self.assertRaises(TypeError, operator.countOf, None, None)
- self.assertTrue(operator.countOf([1, 2, 1, 3, 1, 4], 3) == 1)
- self.assertTrue(operator.countOf([1, 2, 1, 3, 1, 4], 5) == 0)
+ self.assertEqual(operator.countOf([1, 2, 1, 3, 1, 4], 3), 1)
+ self.assertEqual(operator.countOf([1, 2, 1, 3, 1, 4], 5), 0)
def test_delitem(self):
operator = self.module
a = [4, 3, 2, 1]
self.assertRaises(TypeError, operator.delitem, a)
self.assertRaises(TypeError, operator.delitem, a, None)
- self.assertTrue(operator.delitem(a, 1) is None)
- self.assertTrue(a == [4, 2, 1])
+ self.assertIsNone(operator.delitem(a, 1))
+ self.assertEqual(a, [4, 2, 1])
def test_floordiv(self):
operator = self.module
self.assertRaises(TypeError, operator.floordiv, 5)
self.assertRaises(TypeError, operator.floordiv, None, None)
- self.assertTrue(operator.floordiv(5, 2) == 2)
+ self.assertEqual(operator.floordiv(5, 2), 2)
def test_truediv(self):
operator = self.module
self.assertRaises(TypeError, operator.truediv, 5)
self.assertRaises(TypeError, operator.truediv, None, None)
- self.assertTrue(operator.truediv(5, 2) == 2.5)
+ self.assertEqual(operator.truediv(5, 2), 2.5)
def test_getitem(self):
operator = self.module
a = range(10)
self.assertRaises(TypeError, operator.getitem)
self.assertRaises(TypeError, operator.getitem, a, None)
- self.assertTrue(operator.getitem(a, 2) == 2)
+ self.assertEqual(operator.getitem(a, 2), 2)
def test_indexOf(self):
operator = self.module
self.assertRaises(TypeError, operator.indexOf)
self.assertRaises(TypeError, operator.indexOf, None, None)
- self.assertTrue(operator.indexOf([4, 3, 2, 1], 3) == 1)
+ self.assertEqual(operator.indexOf([4, 3, 2, 1], 3), 1)
self.assertRaises(ValueError, operator.indexOf, [4, 3, 2, 1], 0)
def test_invert(self):
@@ -189,21 +189,21 @@ class OperatorTestCase:
operator = self.module
self.assertRaises(TypeError, operator.lshift)
self.assertRaises(TypeError, operator.lshift, None, 42)
- self.assertTrue(operator.lshift(5, 1) == 10)
- self.assertTrue(operator.lshift(5, 0) == 5)
+ self.assertEqual(operator.lshift(5, 1), 10)
+ self.assertEqual(operator.lshift(5, 0), 5)
self.assertRaises(ValueError, operator.lshift, 2, -1)
def test_mod(self):
operator = self.module
self.assertRaises(TypeError, operator.mod)
self.assertRaises(TypeError, operator.mod, None, 42)
- self.assertTrue(operator.mod(5, 2) == 1)
+ self.assertEqual(operator.mod(5, 2), 1)
def test_mul(self):
operator = self.module
self.assertRaises(TypeError, operator.mul)
self.assertRaises(TypeError, operator.mul, None, None)
- self.assertTrue(operator.mul(5, 2) == 10)
+ self.assertEqual(operator.mul(5, 2), 10)
def test_matmul(self):
operator = self.module
@@ -227,7 +227,7 @@ class OperatorTestCase:
operator = self.module
self.assertRaises(TypeError, operator.or_)
self.assertRaises(TypeError, operator.or_, None, None)
- self.assertTrue(operator.or_(0xa, 0x5) == 0xf)
+ self.assertEqual(operator.or_(0xa, 0x5), 0xf)
def test_pos(self):
operator = self.module
@@ -250,8 +250,8 @@ class OperatorTestCase:
operator = self.module
self.assertRaises(TypeError, operator.rshift)
self.assertRaises(TypeError, operator.rshift, None, 42)
- self.assertTrue(operator.rshift(5, 1) == 2)
- self.assertTrue(operator.rshift(5, 0) == 5)
+ self.assertEqual(operator.rshift(5, 1), 2)
+ self.assertEqual(operator.rshift(5, 0), 5)
self.assertRaises(ValueError, operator.rshift, 2, -1)
def test_contains(self):
@@ -266,15 +266,15 @@ class OperatorTestCase:
a = list(range(3))
self.assertRaises(TypeError, operator.setitem, a)
self.assertRaises(TypeError, operator.setitem, a, None, None)
- self.assertTrue(operator.setitem(a, 0, 2) is None)
- self.assertTrue(a == [2, 1, 2])
+ self.assertIsNone(operator.setitem(a, 0, 2))
+ self.assertEqual(a, [2, 1, 2])
self.assertRaises(IndexError, operator.setitem, a, 4, 2)
def test_sub(self):
operator = self.module
self.assertRaises(TypeError, operator.sub)
self.assertRaises(TypeError, operator.sub, None, None)
- self.assertTrue(operator.sub(5, 2) == 3)
+ self.assertEqual(operator.sub(5, 2), 3)
def test_truth(self):
operator = self.module
@@ -292,7 +292,7 @@ class OperatorTestCase:
operator = self.module
self.assertRaises(TypeError, operator.xor)
self.assertRaises(TypeError, operator.xor, None, None)
- self.assertTrue(operator.xor(0xb, 0xc) == 0x7)
+ self.assertEqual(operator.xor(0xb, 0xc), 0x7)
def test_is(self):
operator = self.module
@@ -596,5 +596,38 @@ class CCOperatorPickleTestCase(OperatorPickleTestCase, unittest.TestCase):
module2 = c_operator
+class SubscriptTestCase:
+ def test_subscript(self):
+ subscript = self.module.subscript
+ self.assertIsNone(subscript[None])
+ self.assertEqual(subscript[0], 0)
+ self.assertEqual(subscript[0:1:2], slice(0, 1, 2))
+ self.assertEqual(
+ subscript[0, ..., :2, ...],
+ (0, Ellipsis, slice(2), Ellipsis),
+ )
+
+ def test_pickle(self):
+ from operator import subscript
+ for proto in range(pickle.HIGHEST_PROTOCOL + 1):
+ with self.subTest(proto=proto):
+ self.assertIs(
+ pickle.loads(pickle.dumps(subscript, proto)),
+ subscript,
+ )
+
+ def test_singleton(self):
+ with self.assertRaises(TypeError):
+ type(self.module.subscript)()
+
+ def test_immutable(self):
+ with self.assertRaises(AttributeError):
+ self.module.subscript.attr = None
+
+
+class PySubscriptTestCase(SubscriptTestCase, PyOperatorTestCase):
+ pass
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_os.py b/Lib/test/test_os.py
index d91f58c..b3cf207 100644
--- a/Lib/test/test_os.py
+++ b/Lib/test/test_os.py
@@ -213,15 +213,10 @@ class FileTests(unittest.TestCase):
# Test attributes on return values from os.*stat* family.
class StatAttributeTests(unittest.TestCase):
def setUp(self):
- os.mkdir(support.TESTFN)
- self.fname = os.path.join(support.TESTFN, "f1")
- f = open(self.fname, 'wb')
- f.write(b"ABC")
- f.close()
-
- def tearDown(self):
- os.unlink(self.fname)
- os.rmdir(support.TESTFN)
+ self.fname = support.TESTFN
+ self.addCleanup(support.unlink, self.fname)
+ with open(self.fname, 'wb') as fp:
+ fp.write(b"ABC")
@unittest.skipUnless(hasattr(os, 'stat'), 'test needs os.stat()')
def check_stat_attributes(self, fname):
@@ -413,7 +408,11 @@ class StatAttributeTests(unittest.TestCase):
0)
# test directory st_file_attributes (FILE_ATTRIBUTE_DIRECTORY set)
- result = os.stat(support.TESTFN)
+ dirname = support.TESTFN + "dir"
+ os.mkdir(dirname)
+ self.addCleanup(os.rmdir, dirname)
+
+ result = os.stat(dirname)
self.check_file_attributes(result)
self.assertEqual(
result.st_file_attributes & stat.FILE_ATTRIBUTE_DIRECTORY,
diff --git a/Lib/test/test_pydoc.py b/Lib/test/test_pydoc.py
index ec5c31b..0533a03 100644
--- a/Lib/test/test_pydoc.py
+++ b/Lib/test/test_pydoc.py
@@ -811,6 +811,22 @@ class TestDescriptions(unittest.TestCase):
self.assertEqual(self._get_summary_line(t.wrap),
"wrap(text) method of textwrap.TextWrapper instance")
+ def test_field_order_for_named_tuples(self):
+ Person = namedtuple('Person', ['nickname', 'firstname', 'agegroup'])
+ s = pydoc.render_doc(Person)
+ self.assertLess(s.index('nickname'), s.index('firstname'))
+ self.assertLess(s.index('firstname'), s.index('agegroup'))
+
+ class NonIterableFields:
+ _fields = None
+
+ class NonHashableFields:
+ _fields = [[]]
+
+ # Make sure these doesn't fail
+ pydoc.render_doc(NonIterableFields)
+ pydoc.render_doc(NonHashableFields)
+
@requires_docstrings
def test_bound_builtin_method(self):
s = StringIO()
diff --git a/Lib/test/test_set.py b/Lib/test/test_set.py
index 54de508..ade39fb 100644
--- a/Lib/test/test_set.py
+++ b/Lib/test/test_set.py
@@ -10,6 +10,8 @@ import sys
import warnings
import collections
import collections.abc
+import itertools
+import string
class PassThru(Exception):
pass
@@ -711,6 +713,28 @@ class TestFrozenSet(TestJointOps, unittest.TestCase):
addhashvalue(hash(frozenset([e for e, m in elemmasks if m&i])))
self.assertEqual(len(hashvalues), 2**n)
+ def letter_range(n):
+ return string.ascii_letters[:n]
+
+ def zf_range(n):
+ # https://en.wikipedia.org/wiki/Set-theoretic_definition_of_natural_numbers
+ nums = [frozenset()]
+ for i in range(n-1):
+ num = frozenset(nums)
+ nums.append(num)
+ return nums[:n]
+
+ def powerset(s):
+ for i in range(len(s)+1):
+ yield from map(frozenset, itertools.combinations(s, i))
+
+ for n in range(18):
+ t = 2 ** n
+ mask = t - 1
+ for nums in (range, letter_range, zf_range):
+ u = len({h & mask for h in map(hash, powerset(nums(n)))})
+ self.assertGreater(4*u, t)
+
class FrozenSetSubclass(frozenset):
pass
diff --git a/Lib/test/test_symbol.py b/Lib/test/test_symbol.py
new file mode 100644
index 0000000..2dcb9de
--- /dev/null
+++ b/Lib/test/test_symbol.py
@@ -0,0 +1,55 @@
+import unittest
+from test import support
+import filecmp
+import os
+import sys
+import subprocess
+
+
+SYMBOL_FILE = support.findfile('symbol.py')
+GRAMMAR_FILE = os.path.join(os.path.dirname(__file__),
+ '..', '..', 'Include', 'graminit.h')
+TEST_PY_FILE = 'symbol_test.py'
+
+
+class TestSymbolGeneration(unittest.TestCase):
+
+ def _copy_file_without_generated_symbols(self, source_file, dest_file):
+ with open(source_file) as fp:
+ lines = fp.readlines()
+ with open(dest_file, 'w') as fp:
+ fp.writelines(lines[:lines.index("#--start constants--\n") + 1])
+ fp.writelines(lines[lines.index("#--end constants--\n"):])
+
+ def _generate_symbols(self, grammar_file, target_symbol_py_file):
+ proc = subprocess.Popen([sys.executable,
+ SYMBOL_FILE,
+ grammar_file,
+ target_symbol_py_file], stderr=subprocess.PIPE)
+ stderr = proc.communicate()[1]
+ return proc.returncode, stderr
+
+ def compare_files(self, file1, file2):
+ with open(file1) as fp:
+ lines1 = fp.readlines()
+ with open(file2) as fp:
+ lines2 = fp.readlines()
+ self.assertEqual(lines1, lines2)
+
+ @unittest.skipIf(not os.path.exists(GRAMMAR_FILE),
+ 'test only works from source build directory')
+ def test_real_grammar_and_symbol_file(self):
+ output = support.TESTFN
+ self.addCleanup(support.unlink, output)
+
+ self._copy_file_without_generated_symbols(SYMBOL_FILE, output)
+
+ exitcode, stderr = self._generate_symbols(GRAMMAR_FILE, output)
+ self.assertEqual(b'', stderr)
+ self.assertEqual(0, exitcode)
+
+ self.compare_files(SYMBOL_FILE, output)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/Lib/test/test_time.py b/Lib/test/test_time.py
index 6bcd212..d68dc4f 100644
--- a/Lib/test/test_time.py
+++ b/Lib/test/test_time.py
@@ -30,8 +30,11 @@ class _PyTime(enum.IntEnum):
ROUND_FLOOR = 0
# Round towards infinity (+inf)
ROUND_CEILING = 1
+ # Round to nearest with ties going away from zero
+ ROUND_HALF_UP = 2
-ALL_ROUNDING_METHODS = (_PyTime.ROUND_FLOOR, _PyTime.ROUND_CEILING)
+ALL_ROUNDING_METHODS = (_PyTime.ROUND_FLOOR, _PyTime.ROUND_CEILING,
+ _PyTime.ROUND_HALF_UP)
class TimeTestCase(unittest.TestCase):
@@ -616,65 +619,115 @@ class TestPytime(unittest.TestCase):
@support.cpython_only
def test_time_t(self):
from _testcapi import pytime_object_to_time_t
+
+ # Conversion giving the same result for all rounding methods
+ for rnd in ALL_ROUNDING_METHODS:
+ for obj, seconds in (
+ # int
+ (-1, -1),
+ (0, 0),
+ (1, 1),
+
+ # float
+ (-1.0, -1),
+ (1.0, 1),
+ ):
+ with self.subTest(obj=obj, round=rnd, seconds=seconds):
+ self.assertEqual(pytime_object_to_time_t(obj, rnd),
+ seconds)
+
+ # Conversion giving different results depending on the rounding method
+ FLOOR = _PyTime.ROUND_FLOOR
+ CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
for obj, time_t, rnd in (
- # Round towards minus infinity (-inf)
- (0, 0, _PyTime.ROUND_FLOOR),
- (-1, -1, _PyTime.ROUND_FLOOR),
- (-1.0, -1, _PyTime.ROUND_FLOOR),
- (-1.9, -2, _PyTime.ROUND_FLOOR),
- (1.0, 1, _PyTime.ROUND_FLOOR),
- (1.9, 1, _PyTime.ROUND_FLOOR),
- # Round towards infinity (+inf)
- (0, 0, _PyTime.ROUND_CEILING),
- (-1, -1, _PyTime.ROUND_CEILING),
- (-1.0, -1, _PyTime.ROUND_CEILING),
- (-1.9, -1, _PyTime.ROUND_CEILING),
- (1.0, 1, _PyTime.ROUND_CEILING),
- (1.9, 2, _PyTime.ROUND_CEILING),
+ (-1.9, -2, FLOOR),
+ (-1.9, -1, CEILING),
+ (-1.9, -2, HALF_UP),
+
+ (1.9, 1, FLOOR),
+ (1.9, 2, CEILING),
+ (1.9, 2, HALF_UP),
+
+ # half up
+ (-0.999, -1, HALF_UP),
+ (-0.510, -1, HALF_UP),
+ (-0.500, -1, HALF_UP),
+ (-0.490, 0, HALF_UP),
+ ( 0.490, 0, HALF_UP),
+ ( 0.500, 1, HALF_UP),
+ ( 0.510, 1, HALF_UP),
+ ( 0.999, 1, HALF_UP),
):
self.assertEqual(pytime_object_to_time_t(obj, rnd), time_t)
+ # Test OverflowError
rnd = _PyTime.ROUND_FLOOR
for invalid in self.invalid_values:
self.assertRaises(OverflowError,
pytime_object_to_time_t, invalid, rnd)
@support.cpython_only
- def test_timespec(self):
+ def test_object_to_timespec(self):
from _testcapi import pytime_object_to_timespec
+
+ # Conversion giving the same result for all rounding methods
+ for rnd in ALL_ROUNDING_METHODS:
+ for obj, timespec in (
+ # int
+ (0, (0, 0)),
+ (-1, (-1, 0)),
+
+ # float
+ (-1/2**7, (-1, 992187500)),
+ (-1.0, (-1, 0)),
+ (-1e-9, (-1, 999999999)),
+ (1e-9, (0, 1)),
+ (1.0, (1, 0)),
+ ):
+ with self.subTest(obj=obj, round=rnd, timespec=timespec):
+ self.assertEqual(pytime_object_to_timespec(obj, rnd), timespec)
+
+ # Conversion giving different results depending on the rounding method
+ FLOOR = _PyTime.ROUND_FLOOR
+ CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
for obj, timespec, rnd in (
# Round towards minus infinity (-inf)
- (0, (0, 0), _PyTime.ROUND_FLOOR),
- (-1, (-1, 0), _PyTime.ROUND_FLOOR),
- (-1.0, (-1, 0), _PyTime.ROUND_FLOOR),
- (1e-9, (0, 1), _PyTime.ROUND_FLOOR),
- (1e-10, (0, 0), _PyTime.ROUND_FLOOR),
- (-1e-9, (-1, 999999999), _PyTime.ROUND_FLOOR),
- (-1e-10, (-1, 999999999), _PyTime.ROUND_FLOOR),
- (-1.2, (-2, 800000000), _PyTime.ROUND_FLOOR),
- (0.9999999999, (0, 999999999), _PyTime.ROUND_FLOOR),
- (1.1234567890, (1, 123456789), _PyTime.ROUND_FLOOR),
- (1.1234567899, (1, 123456789), _PyTime.ROUND_FLOOR),
- (-1.1234567890, (-2, 876543211), _PyTime.ROUND_FLOOR),
- (-1.1234567891, (-2, 876543210), _PyTime.ROUND_FLOOR),
+ (-1e-10, (0, 0), CEILING),
+ (-1e-10, (-1, 999999999), FLOOR),
+ (-1e-10, (0, 0), HALF_UP),
+ (1e-10, (0, 0), FLOOR),
+ (1e-10, (0, 1), CEILING),
+ (1e-10, (0, 0), HALF_UP),
+
+ (0.9999999999, (0, 999999999), FLOOR),
+ (0.9999999999, (1, 0), CEILING),
+
+ (1.1234567890, (1, 123456789), FLOOR),
+ (1.1234567899, (1, 123456789), FLOOR),
+ (-1.1234567890, (-2, 876543210), FLOOR),
+ (-1.1234567891, (-2, 876543210), FLOOR),
# Round towards infinity (+inf)
- (0, (0, 0), _PyTime.ROUND_CEILING),
- (-1, (-1, 0), _PyTime.ROUND_CEILING),
- (-1.0, (-1, 0), _PyTime.ROUND_CEILING),
- (1e-9, (0, 1), _PyTime.ROUND_CEILING),
- (1e-10, (0, 1), _PyTime.ROUND_CEILING),
- (-1e-9, (-1, 999999999), _PyTime.ROUND_CEILING),
- (-1e-10, (0, 0), _PyTime.ROUND_CEILING),
- (-1.2, (-2, 800000000), _PyTime.ROUND_CEILING),
- (0.9999999999, (1, 0), _PyTime.ROUND_CEILING),
- (1.1234567890, (1, 123456790), _PyTime.ROUND_CEILING),
- (1.1234567899, (1, 123456790), _PyTime.ROUND_CEILING),
- (-1.1234567890, (-2, 876543211), _PyTime.ROUND_CEILING),
- (-1.1234567891, (-2, 876543211), _PyTime.ROUND_CEILING),
+ (1.1234567890, (1, 123456790), CEILING),
+ (1.1234567899, (1, 123456790), CEILING),
+ (-1.1234567890, (-2, 876543211), CEILING),
+ (-1.1234567891, (-2, 876543211), CEILING),
+
+ # half up
+ (-0.6e-9, (-1, 999999999), HALF_UP),
+ # skipped, 0.5e-6 is inexact in base 2
+ #(-0.5e-9, (-1, 999999999), HALF_UP),
+ (-0.4e-9, (0, 0), HALF_UP),
+
+ (0.4e-9, (0, 0), HALF_UP),
+ (0.5e-9, (0, 1), HALF_UP),
+ (0.6e-9, (0, 1), HALF_UP),
):
with self.subTest(obj=obj, round=rnd, timespec=timespec):
self.assertEqual(pytime_object_to_timespec(obj, rnd), timespec)
+ # Test OverflowError
rnd = _PyTime.ROUND_FLOOR
for invalid in self.invalid_values:
self.assertRaises(OverflowError,
@@ -737,6 +790,9 @@ class TestPytime(unittest.TestCase):
@unittest.skipUnless(_testcapi is not None,
'need the _testcapi module')
class TestPyTime_t(unittest.TestCase):
+ """
+ Test the _PyTime_t API.
+ """
def test_FromSeconds(self):
from _testcapi import PyTime_FromSeconds
for seconds in (0, 3, -456, _testcapi.INT_MAX, _testcapi.INT_MIN):
@@ -766,11 +822,11 @@ class TestPyTime_t(unittest.TestCase):
(123.0, 123 * SEC_TO_NS),
(-7.0, -7 * SEC_TO_NS),
- # nanosecond are kept for value <= 2^23 seconds
+ # nanosecond are kept for value <= 2^23 seconds,
+ # except 2**23-1e-9 with HALF_UP
(2**22 - 1e-9, 4194303999999999),
(2**22, 4194304000000000),
(2**22 + 1e-9, 4194304000000001),
- (2**23 - 1e-9, 8388607999999999),
(2**23, 8388608000000000),
# start loosing precision for value > 2^23 seconds
@@ -803,24 +859,38 @@ class TestPyTime_t(unittest.TestCase):
# Conversion giving different results depending on the rounding method
FLOOR = _PyTime.ROUND_FLOOR
CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
for obj, ts, rnd in (
# close to zero
( 1e-10, 0, FLOOR),
( 1e-10, 1, CEILING),
+ ( 1e-10, 0, HALF_UP),
(-1e-10, -1, FLOOR),
(-1e-10, 0, CEILING),
+ (-1e-10, 0, HALF_UP),
# test rounding of the last nanosecond
( 1.1234567899, 1123456789, FLOOR),
( 1.1234567899, 1123456790, CEILING),
+ ( 1.1234567899, 1123456790, HALF_UP),
(-1.1234567899, -1123456790, FLOOR),
(-1.1234567899, -1123456789, CEILING),
+ (-1.1234567899, -1123456790, HALF_UP),
# close to 1 second
( 0.9999999999, 999999999, FLOOR),
( 0.9999999999, 1000000000, CEILING),
+ ( 0.9999999999, 1000000000, HALF_UP),
(-0.9999999999, -1000000000, FLOOR),
(-0.9999999999, -999999999, CEILING),
+ (-0.9999999999, -1000000000, HALF_UP),
+
+ # close to 2^23 seconds
+ (2**23 - 1e-9, 8388607999999999, FLOOR),
+ (2**23 - 1e-9, 8388607999999999, CEILING),
+ # Issue #23517: skip HALF_UP test because the result is different
+ # depending on the FPU and how the compiler optimize the code :-/
+ #(2**23 - 1e-9, 8388608000000000, HALF_UP),
):
with self.subTest(obj=obj, round=rnd, timestamp=ts):
self.assertEqual(PyTime_FromSecondsObject(obj, rnd), ts)
@@ -888,18 +958,33 @@ class TestPyTime_t(unittest.TestCase):
FLOOR = _PyTime.ROUND_FLOOR
CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
for ns, tv, rnd in (
# nanoseconds
(1, (0, 0), FLOOR),
(1, (0, 1), CEILING),
+ (1, (0, 0), HALF_UP),
(-1, (-1, 999999), FLOOR),
(-1, (0, 0), CEILING),
+ (-1, (0, 0), HALF_UP),
# seconds + nanoseconds
(1234567001, (1, 234567), FLOOR),
(1234567001, (1, 234568), CEILING),
+ (1234567001, (1, 234567), HALF_UP),
(-1234567001, (-2, 765432), FLOOR),
(-1234567001, (-2, 765433), CEILING),
+ (-1234567001, (-2, 765433), HALF_UP),
+
+ # half up
+ (499, (0, 0), HALF_UP),
+ (500, (0, 1), HALF_UP),
+ (501, (0, 1), HALF_UP),
+ (999, (0, 1), HALF_UP),
+ (-499, (0, 0), HALF_UP),
+ (-500, (0, 0), HALF_UP),
+ (-501, (-1, 999999), HALF_UP),
+ (-999, (-1, 999999), HALF_UP),
):
with self.subTest(nanoseconds=ns, timeval=tv, round=rnd):
self.assertEqual(PyTime_AsTimeval(ns, rnd), tv)
@@ -942,18 +1027,33 @@ class TestPyTime_t(unittest.TestCase):
FLOOR = _PyTime.ROUND_FLOOR
CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
for ns, ms, rnd in (
# nanoseconds
(1, 0, FLOOR),
(1, 1, CEILING),
+ (1, 0, HALF_UP),
(-1, 0, FLOOR),
(-1, -1, CEILING),
+ (-1, 0, HALF_UP),
# seconds + nanoseconds
(1234 * MS_TO_NS + 1, 1234, FLOOR),
(1234 * MS_TO_NS + 1, 1235, CEILING),
+ (1234 * MS_TO_NS + 1, 1234, HALF_UP),
(-1234 * MS_TO_NS - 1, -1234, FLOOR),
(-1234 * MS_TO_NS - 1, -1235, CEILING),
+ (-1234 * MS_TO_NS - 1, -1234, HALF_UP),
+
+ # half up
+ (499999, 0, HALF_UP),
+ (499999, 0, HALF_UP),
+ (500000, 1, HALF_UP),
+ (999999, 1, HALF_UP),
+ (-499999, 0, HALF_UP),
+ (-500000, -1, HALF_UP),
+ (-500001, -1, HALF_UP),
+ (-999999, -1, HALF_UP),
):
with self.subTest(nanoseconds=ns, milliseconds=ms, round=rnd):
self.assertEqual(PyTime_AsMilliseconds(ns, rnd), ms)
@@ -979,22 +1079,207 @@ class TestPyTime_t(unittest.TestCase):
FLOOR = _PyTime.ROUND_FLOOR
CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
for ns, ms, rnd in (
# nanoseconds
(1, 0, FLOOR),
(1, 1, CEILING),
+ (1, 0, HALF_UP),
(-1, 0, FLOOR),
(-1, -1, CEILING),
+ (-1, 0, HALF_UP),
# seconds + nanoseconds
(1234 * US_TO_NS + 1, 1234, FLOOR),
(1234 * US_TO_NS + 1, 1235, CEILING),
+ (1234 * US_TO_NS + 1, 1234, HALF_UP),
(-1234 * US_TO_NS - 1, -1234, FLOOR),
(-1234 * US_TO_NS - 1, -1235, CEILING),
+ (-1234 * US_TO_NS - 1, -1234, HALF_UP),
+
+ # half up
+ (1499, 1, HALF_UP),
+ (1500, 2, HALF_UP),
+ (1501, 2, HALF_UP),
+ (-1499, -1, HALF_UP),
+ (-1500, -2, HALF_UP),
+ (-1501, -2, HALF_UP),
):
with self.subTest(nanoseconds=ns, milliseconds=ms, round=rnd):
self.assertEqual(PyTime_AsMicroseconds(ns, rnd), ms)
+@unittest.skipUnless(_testcapi is not None,
+ 'need the _testcapi module')
+class TestOldPyTime(unittest.TestCase):
+ """
+ Test the old _PyTime_t API: _PyTime_ObjectToXXX() functions.
+ """
+ def setUp(self):
+ self.invalid_values = (
+ -(2 ** 100), 2 ** 100,
+ -(2.0 ** 100.0), 2.0 ** 100.0,
+ )
+
+ @support.cpython_only
+ def test_time_t(self):
+ from _testcapi import pytime_object_to_time_t
+
+ # Conversion giving the same result for all rounding methods
+ for rnd in ALL_ROUNDING_METHODS:
+ for obj, time_t in (
+ # int
+ (0, 0),
+ (-1, -1),
+
+ # float
+ (1.0, 1),
+ (-1.0, -1),
+ ):
+ self.assertEqual(pytime_object_to_time_t(obj, rnd), time_t)
+
+
+ # Conversion giving different results depending on the rounding method
+ FLOOR = _PyTime.ROUND_FLOOR
+ CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
+ for obj, time_t, rnd in (
+ (-1.9, -2, FLOOR),
+ (-1.9, -2, HALF_UP),
+ (-1.9, -1, CEILING),
+
+ (1.9, 1, FLOOR),
+ (1.9, 2, HALF_UP),
+ (1.9, 2, CEILING),
+
+ (-0.6, -1, HALF_UP),
+ (-0.5, -1, HALF_UP),
+ (-0.4, 0, HALF_UP),
+
+ (0.4, 0, HALF_UP),
+ (0.5, 1, HALF_UP),
+ (0.6, 1, HALF_UP),
+ ):
+ self.assertEqual(pytime_object_to_time_t(obj, rnd), time_t)
+
+ # Test OverflowError
+ rnd = _PyTime.ROUND_FLOOR
+ for invalid in self.invalid_values:
+ self.assertRaises(OverflowError,
+ pytime_object_to_time_t, invalid, rnd)
+
+ def test_object_to_timeval(self):
+ from _testcapi import pytime_object_to_timeval
+
+ # Conversion giving the same result for all rounding methods
+ for rnd in ALL_ROUNDING_METHODS:
+ for obj, timeval in (
+ # int
+ (0, (0, 0)),
+ (-1, (-1, 0)),
+
+ # float
+ (-1.0, (-1, 0)),
+ (1/2**6, (0, 15625)),
+ (-1/2**6, (-1, 984375)),
+ (-1e-6, (-1, 999999)),
+ (1e-6, (0, 1)),
+ ):
+ with self.subTest(obj=obj, round=rnd, timeval=timeval):
+ self.assertEqual(pytime_object_to_timeval(obj, rnd),
+ timeval)
+
+ # Conversion giving different results depending on the rounding method
+ FLOOR = _PyTime.ROUND_FLOOR
+ CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
+ for obj, timeval, rnd in (
+ (-1e-7, (-1, 999999), FLOOR),
+ (-1e-7, (0, 0), CEILING),
+ (-1e-7, (0, 0), HALF_UP),
+
+ (1e-7, (0, 0), FLOOR),
+ (1e-7, (0, 1), CEILING),
+ (1e-7, (0, 0), HALF_UP),
+
+ (0.9999999, (0, 999999), FLOOR),
+ (0.9999999, (1, 0), CEILING),
+ (0.9999999, (1, 0), HALF_UP),
+
+ (-0.6e-6, (-1, 999999), HALF_UP),
+ # skipped, -0.5e-6 is inexact in base 2
+ #(-0.5e-6, (-1, 999999), HALF_UP),
+ (-0.4e-6, (0, 0), HALF_UP),
+
+ (0.4e-6, (0, 0), HALF_UP),
+ # skipped, 0.5e-6 is inexact in base 2
+ #(0.5e-6, (0, 1), HALF_UP),
+ (0.6e-6, (0, 1), HALF_UP),
+ ):
+ with self.subTest(obj=obj, round=rnd, timeval=timeval):
+ self.assertEqual(pytime_object_to_timeval(obj, rnd), timeval)
+
+ rnd = _PyTime.ROUND_FLOOR
+ for invalid in self.invalid_values:
+ self.assertRaises(OverflowError,
+ pytime_object_to_timeval, invalid, rnd)
+
+ @support.cpython_only
+ def test_timespec(self):
+ from _testcapi import pytime_object_to_timespec
+
+ # Conversion giving the same result for all rounding methods
+ for rnd in ALL_ROUNDING_METHODS:
+ for obj, timespec in (
+ # int
+ (0, (0, 0)),
+ (-1, (-1, 0)),
+
+ # float
+ (-1.0, (-1, 0)),
+ (-1e-9, (-1, 999999999)),
+ (1e-9, (0, 1)),
+ (-1/2**9, (-1, 998046875)),
+ ):
+ with self.subTest(obj=obj, round=rnd, timespec=timespec):
+ self.assertEqual(pytime_object_to_timespec(obj, rnd),
+ timespec)
+
+ # Conversion giving different results depending on the rounding method
+ FLOOR = _PyTime.ROUND_FLOOR
+ CEILING = _PyTime.ROUND_CEILING
+ HALF_UP = _PyTime.ROUND_HALF_UP
+ for obj, timespec, rnd in (
+ (-1e-10, (-1, 999999999), FLOOR),
+ (-1e-10, (0, 0), CEILING),
+ (-1e-10, (0, 0), HALF_UP),
+
+ (1e-10, (0, 0), FLOOR),
+ (1e-10, (0, 1), CEILING),
+ (1e-10, (0, 0), HALF_UP),
+
+ (0.9999999999, (0, 999999999), FLOOR),
+ (0.9999999999, (1, 0), CEILING),
+ (0.9999999999, (1, 0), HALF_UP),
+
+ (-0.6e-9, (-1, 999999999), HALF_UP),
+ # skipped, 0.5e-6 is inexact in base 2
+ #(-0.5e-9, (-1, 999999999), HALF_UP),
+ (-0.4e-9, (0, 0), HALF_UP),
+
+ (0.4e-9, (0, 0), HALF_UP),
+ (0.5e-9, (0, 1), HALF_UP),
+ (0.6e-9, (0, 1), HALF_UP),
+ ):
+ with self.subTest(obj=obj, round=rnd, timespec=timespec):
+ self.assertEqual(pytime_object_to_timespec(obj, rnd), timespec)
+
+ # Test OverflowError
+ rnd = FLOOR
+ for invalid in self.invalid_values:
+ self.assertRaises(OverflowError,
+ pytime_object_to_timespec, invalid, rnd)
+
+
if __name__ == "__main__":
unittest.main()
diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py
index 0552f90..fcf5082 100644
--- a/Lib/test/test_urlparse.py
+++ b/Lib/test/test_urlparse.py
@@ -554,29 +554,27 @@ class UrlParseTestCase(unittest.TestCase):
self.assertEqual(p.port, 80)
self.assertEqual(p.geturl(), url)
- # Verify an illegal port is returned as None
+ # Verify an illegal port raises ValueError
url = b"HTTP://WWW.PYTHON.ORG:65536/doc/#frag"
p = urllib.parse.urlsplit(url)
- self.assertEqual(p.port, None)
+ with self.assertRaisesRegex(ValueError, "out of range"):
+ p.port
def test_attributes_bad_port(self):
- """Check handling of non-integer ports."""
- p = urllib.parse.urlsplit("http://www.example.net:foo")
- self.assertEqual(p.netloc, "www.example.net:foo")
- self.assertRaises(ValueError, lambda: p.port)
-
- p = urllib.parse.urlparse("http://www.example.net:foo")
- self.assertEqual(p.netloc, "www.example.net:foo")
- self.assertRaises(ValueError, lambda: p.port)
-
- # Once again, repeat ourselves to test bytes
- p = urllib.parse.urlsplit(b"http://www.example.net:foo")
- self.assertEqual(p.netloc, b"www.example.net:foo")
- self.assertRaises(ValueError, lambda: p.port)
-
- p = urllib.parse.urlparse(b"http://www.example.net:foo")
- self.assertEqual(p.netloc, b"www.example.net:foo")
- self.assertRaises(ValueError, lambda: p.port)
+ """Check handling of invalid ports."""
+ for bytes in (False, True):
+ for parse in (urllib.parse.urlsplit, urllib.parse.urlparse):
+ for port in ("foo", "1.5", "-1", "0x10"):
+ with self.subTest(bytes=bytes, parse=parse, port=port):
+ netloc = "www.example.net:" + port
+ url = "http://" + netloc
+ if bytes:
+ netloc = netloc.encode("ascii")
+ url = url.encode("ascii")
+ p = parse(url)
+ self.assertEqual(p.netloc, netloc)
+ with self.assertRaises(ValueError):
+ p.port
def test_attributes_without_netloc(self):
# This example is straight from RFC 3261. It looks like it
diff --git a/Lib/test/test_warnings/data/import_warning.py b/Lib/test/test_warnings/data/import_warning.py
index d6ea2ce..32daec1 100644
--- a/Lib/test/test_warnings/data/import_warning.py
+++ b/Lib/test/test_warnings/data/import_warning.py
@@ -1,3 +1,3 @@
import warnings
-warnings.warn('module-level warning', DeprecationWarning, stacklevel=2) \ No newline at end of file
+warnings.warn('module-level warning', DeprecationWarning, stacklevel=2)
diff --git a/Lib/test/test_zipimport.py b/Lib/test/test_zipimport.py
index a97a778..4f19535 100644
--- a/Lib/test/test_zipimport.py
+++ b/Lib/test/test_zipimport.py
@@ -214,7 +214,8 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
packdir2 = packdir + TESTPACK2 + os.sep
files = {packdir + "__init__" + pyc_ext: (NOW, test_pyc),
packdir2 + "__init__" + pyc_ext: (NOW, test_pyc),
- packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc)}
+ packdir2 + TESTMOD + pyc_ext: (NOW, test_pyc),
+ "spam" + pyc_ext: (NOW, test_pyc)}
z = ZipFile(TEMP_ZIP, "w")
try:
@@ -228,6 +229,14 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
zi = zipimport.zipimporter(TEMP_ZIP)
self.assertEqual(zi.archive, TEMP_ZIP)
self.assertEqual(zi.is_package(TESTPACK), True)
+
+ find_mod = zi.find_module('spam')
+ self.assertIsNotNone(find_mod)
+ self.assertIsInstance(find_mod, zipimport.zipimporter)
+ self.assertFalse(find_mod.is_package('spam'))
+ load_mod = find_mod.load_module('spam')
+ self.assertEqual(find_mod.get_filename('spam'), load_mod.__file__)
+
mod = zi.load_module(TESTPACK)
self.assertEqual(zi.get_filename(TESTPACK), mod.__file__)
@@ -287,6 +296,16 @@ class UncompressedZipImportTestCase(ImportHooksBaseTestCase):
self.assertEqual(
zi.is_package(TESTPACK2 + os.sep + TESTMOD), False)
+ pkg_path = TEMP_ZIP + os.sep + packdir + TESTPACK2
+ zi2 = zipimport.zipimporter(pkg_path)
+ find_mod_dotted = zi2.find_module(TESTMOD)
+ self.assertIsNotNone(find_mod_dotted)
+ self.assertIsInstance(find_mod_dotted, zipimport.zipimporter)
+ self.assertFalse(zi2.is_package(TESTMOD))
+ load_mod = find_mod_dotted.load_module(TESTMOD)
+ self.assertEqual(
+ find_mod_dotted.get_filename(TESTMOD), load_mod.__file__)
+
mod_path = TESTPACK2 + os.sep + TESTMOD
mod_name = module_path_to_dotted_name(mod_path)
__import__(mod_name)