-
Notifications
You must be signed in to change notification settings - Fork 286
/
test_standard_library.py
628 lines (541 loc) · 20.6 KB
/
test_standard_library.py
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
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
"""
Tests for the future.standard_library module
"""
from __future__ import absolute_import, print_function
from future import standard_library
from future import utils
from future.tests.base import unittest, CodeHandler, expectedFailurePY2
import sys
import tempfile
import copy
import textwrap
from subprocess import CalledProcessError
class TestStandardLibraryReorganization(CodeHandler):
def setUp(self):
self.interpreter = sys.executable
standard_library.install_aliases()
super(TestStandardLibraryReorganization, self).setUp()
def tearDown(self):
# standard_library.remove_hooks()
pass
def test_can_import_several(self):
"""
This test failed in v0.12-pre if e.g.
future/standard_library/email/header.py contained:
from future import standard_library
standard_library.remove_hooks()
"""
import future.moves.urllib.parse as urllib_parse
import future.moves.urllib.request as urllib_request
import http.server
for m in [urllib_parse, urllib_request, http.server]:
self.assertTrue(m is not None)
def test_is_py2_stdlib_module(self):
"""
Tests whether the internal is_py2_stdlib_module function (called by the
sys.modules scrubbing functions) is reliable.
"""
externalmodules = [standard_library, utils]
self.assertTrue(not any([standard_library.is_py2_stdlib_module(module)
for module in externalmodules]))
py2modules = [sys, tempfile, copy, textwrap]
if utils.PY2:
# Debugging:
for module in py2modules:
if hasattr(module, '__file__'):
print(module.__file__, file=sys.stderr)
self.assertTrue(all([standard_library.is_py2_stdlib_module(module)
for module in py2modules]))
else:
self.assertTrue(
not any ([standard_library.is_py2_stdlib_module(module)
for module in py2modules]))
# @unittest.skip("No longer relevant")
# def test_all_modules_identical(self):
# """
# Tests whether all of the old imports in RENAMES are accessible
# under their new names.
# """
# for (oldname, newname) in standard_library.RENAMES.items():
# if newname == 'winreg' and sys.platform not in ['win32', 'win64']:
# continue
# if newname in standard_library.REPLACED_MODULES:
# # Skip this check for e.g. the stdlib's ``test`` module,
# # which we have replaced completely.
# continue
# oldmod = __import__(oldname)
# newmod = __import__(newname)
# if '.' not in oldname:
# self.assertEqual(oldmod, newmod)
@expectedFailurePY2
def test_suspend_hooks(self):
"""
Code like the try/except block here appears in Pyflakes v0.6.1. This
method tests whether suspend_hooks() works as advertised.
"""
example_PY2_check = False
with standard_library.suspend_hooks():
# An example of fragile import code that we don't want to break:
try:
import builtins
except ImportError:
example_PY2_check = True
if utils.PY2:
self.assertTrue(example_PY2_check)
else:
self.assertFalse(example_PY2_check)
# The import should succeed again now:
import builtins
@expectedFailurePY2
def test_disable_hooks(self):
"""
Tests the old (deprecated) names. These deprecated aliases should be
removed by version 1.0
"""
example_PY2_check = False
standard_library.enable_hooks() # deprecated name
old_meta_path = copy.copy(sys.meta_path)
standard_library.disable_hooks()
standard_library.scrub_future_sys_modules()
if utils.PY2:
self.assertTrue(len(old_meta_path) == len(sys.meta_path) + 1)
else:
self.assertTrue(len(old_meta_path) == len(sys.meta_path))
# An example of fragile import code that we don't want to break:
try:
import builtins
except ImportError:
example_PY2_check = True
if utils.PY2:
self.assertTrue(example_PY2_check)
else:
self.assertFalse(example_PY2_check)
standard_library.install_hooks()
# Imports should succeed again now:
import builtins
import html
if utils.PY2:
self.assertTrue(standard_library.detect_hooks())
self.assertTrue(len(old_meta_path) == len(sys.meta_path))
@expectedFailurePY2
def test_remove_hooks2(self):
"""
As above, but with the new names
"""
example_PY2_check = False
standard_library.install_hooks()
old_meta_path = copy.copy(sys.meta_path)
standard_library.remove_hooks()
standard_library.scrub_future_sys_modules()
if utils.PY2:
self.assertTrue(len(old_meta_path) == len(sys.meta_path) + 1)
else:
self.assertTrue(len(old_meta_path) == len(sys.meta_path))
# An example of fragile import code that we don't want to break:
try:
import builtins
except ImportError:
example_PY2_check = True
if utils.PY2:
self.assertTrue(example_PY2_check)
else:
self.assertFalse(example_PY2_check)
standard_library.install_hooks()
# The import should succeed again now:
import builtins
self.assertTrue(len(old_meta_path) == len(sys.meta_path))
def test_detect_hooks(self):
"""
Tests whether the future.standard_library.detect_hooks is doing
its job.
"""
standard_library.install_hooks()
if utils.PY2:
self.assertTrue(standard_library.detect_hooks())
meta_path = copy.copy(sys.meta_path)
standard_library.remove_hooks()
if utils.PY2:
self.assertEqual(len(meta_path), len(sys.meta_path) + 1)
self.assertFalse(standard_library.detect_hooks())
@unittest.skipIf(utils.PY3, 'not testing for old urllib on Py3')
def test_old_urllib_import(self):
"""
Tests whether an imported module can import the old urllib package.
Importing future.standard_library in a script should be possible and
not disrupt any uses of the old Py2 standard library names in modules
imported by that script.
"""
code1 = '''
from future import standard_library
with standard_library.suspend_hooks():
import module_importing_old_urllib
'''
self._write_test_script(code1, 'runme.py')
code2 = '''
import urllib
assert 'urlopen' in dir(urllib)
print('Import succeeded!')
'''
self._write_test_script(code2, 'module_importing_old_urllib.py')
output = self._run_test_script('runme.py')
print(output)
self.assertTrue(True)
def test_sys_intern(self):
"""
Py2's builtin intern() has been moved to the sys module. Tests
whether sys.intern is available.
"""
from sys import intern
if utils.PY3:
self.assertEqual(intern('hello'), 'hello')
else:
# intern() requires byte-strings on Py2:
self.assertEqual(intern(b'hello'), b'hello')
def test_sys_maxsize(self):
"""
Tests whether sys.maxsize is available.
"""
from sys import maxsize
self.assertTrue(maxsize > 0)
def test_itertools_filterfalse(self):
"""
Tests whether itertools.filterfalse is available.
"""
from itertools import filterfalse
not_div_by_3 = filterfalse(lambda x: x % 3 == 0, range(8))
self.assertEqual(list(not_div_by_3), [1, 2, 4, 5, 7])
def test_itertools_zip_longest(self):
"""
Tests whether itertools.zip_longest is available.
"""
from itertools import zip_longest
a = (1, 2)
b = [2, 4, 6]
self.assertEqual(list(zip_longest(a, b)),
[(1, 2), (2, 4), (None, 6)])
def test_ChainMap(self):
"""
Tests whether collections.ChainMap is available.
"""
from collections import ChainMap
cm = ChainMap()
@unittest.expectedFailure
@unittest.skipIf(utils.PY3, 'generic import tests are for Py2 only')
def test_import_failure_from_module(self):
"""
Tests whether e.g. "import socketserver" succeeds in a module
imported by another module that has used and removed the stdlib hooks.
We want this to fail; the stdlib hooks should not bleed to imported
modules too without their explicitly invoking them.
"""
code1 = '''
from future import standard_library
standard_library.install_hooks()
standard_library.remove_hooks()
import importme2
'''
code2 = '''
import socketserver
print('Uh oh. importme2 should have raised an ImportError.')
'''
self._write_test_script(code1, 'importme1.py')
self._write_test_script(code2, 'importme2.py')
with self.assertRaises(CalledProcessError):
output = self._run_test_script('importme1.py')
# Disabled since v0.16.0:
# def test_configparser(self):
# import configparser
def test_copyreg(self):
import copyreg
def test_pickle(self):
import pickle
def test_profile(self):
import profile
def test_stringio(self):
from io import StringIO
s = StringIO(u'test')
for method in ['tell', 'read', 'seek', 'close', 'flush']:
self.assertTrue(hasattr(s, method))
def test_bytesio(self):
from io import BytesIO
s = BytesIO(b'test')
for method in ['tell', 'read', 'seek', 'close', 'flush', 'getvalue']:
self.assertTrue(hasattr(s, method))
def test_queue(self):
import queue
q = queue.Queue()
q.put('thing')
self.assertFalse(q.empty())
def test_reprlib(self):
import reprlib
self.assertTrue(True)
def test_socketserver(self):
import socketserver
self.assertTrue(True)
@unittest.skip("Not testing tkinter import (it may be installed separately from Python)")
def test_tkinter(self):
import tkinter
self.assertTrue(True)
def test_builtins(self):
import builtins
self.assertTrue(hasattr(builtins, 'tuple'))
@unittest.skip("ssl redirect support on pypi isn't working as expected for now ...")
def test_urllib_request_ssl_redirect(self):
"""
This site redirects to https://...
It therefore requires ssl support.
"""
import future.moves.urllib.request as urllib_request
from pprint import pprint
URL = 'http://pypi.python.org/pypi/{0}/json'
package = 'future'
r = urllib_request.urlopen(URL.format(package))
# pprint(r.read().decode('utf-8'))
self.assertTrue(True)
def test_moves_urllib_request_http(self):
"""
This site (python-future.org) uses plain http (as of 2014-09-23).
"""
import future.moves.urllib.request as urllib_request
from pprint import pprint
URL = 'http://python-future.org'
r = urllib_request.urlopen(URL)
data = r.read()
self.assertTrue(b'</html>' in data)
def test_urllib_request_http(self):
"""
This site (python-future.org) uses plain http (as of 2014-09-23).
"""
import urllib.request as urllib_request
from pprint import pprint
URL = 'http://python-future.org'
r = urllib_request.urlopen(URL)
data = r.read()
self.assertTrue(b'</html>' in data)
def test_html_import(self):
import html
import html.entities
import html.parser
self.assertTrue(True)
def test_http_client_import(self):
import http.client
self.assertTrue(True)
def test_other_http_imports(self):
import http
import http.server
import http.cookies
import http.cookiejar
self.assertTrue(True)
def test_urllib_imports_moves(self):
import future.moves.urllib
import future.moves.urllib.parse
import future.moves.urllib.request
import future.moves.urllib.robotparser
import future.moves.urllib.error
import future.moves.urllib.response
self.assertTrue(True)
def test_urllib_imports_install_aliases(self):
with standard_library.suspend_hooks():
standard_library.install_aliases()
import urllib
import urllib.parse
import urllib.request
import urllib.robotparser
import urllib.error
import urllib.response
self.assertTrue(True)
def test_urllib_imports_cm(self):
with standard_library.hooks():
import urllib
import urllib.parse
import urllib.request
import urllib.robotparser
import urllib.error
import urllib.response
self.assertTrue(True)
def test_urllib_imports_install_hooks(self):
standard_library.remove_hooks()
standard_library.install_hooks()
import urllib
import urllib.parse
import urllib.request
import urllib.robotparser
import urllib.error
import urllib.response
self.assertTrue(True)
def test_underscore_prefixed_modules(self):
import _thread
if sys.version_info < (3, 9):
import _dummy_thread
import _markupbase
self.assertTrue(True)
def test_reduce(self):
"""
reduce has been moved to the functools module
"""
import functools
self.assertEqual(functools.reduce(lambda x, y: x+y, range(1, 6)), 15)
def test_collections_userstuff(self):
"""
UserDict, UserList, and UserString have been moved to the
collections module.
"""
from collections import UserDict
from collections import UserList
from collections import UserString
self.assertTrue(True)
def test_reload(self):
"""
reload has been moved to the imp module
"""
# imp was deprecated in python 3.6
if sys.version_info >= (3, 6):
import importlib as imp
else:
import imp
imp.reload(sys)
self.assertTrue(True)
def test_install_aliases(self):
"""
Does the install_aliases() interface monkey-patch urllib etc. successfully?
"""
from future.standard_library import remove_hooks, install_aliases
remove_hooks()
install_aliases()
from collections import Counter, OrderedDict # backported to Py2.6
from collections import UserDict, UserList, UserString
# Requires Python dbm support:
# import dbm
# import dbm.dumb
# import dbm.gnu
# import dbm.ndbm
from itertools import filterfalse, zip_longest
from subprocess import check_output # backported to Py2.6
from subprocess import getoutput, getstatusoutput
from sys import intern
# test_support may not be available (e.g. on Anaconda Py2.6):
# import test.support
import urllib.error
import urllib.parse
import urllib.request
import urllib.response
import urllib.robotparser
self.assertTrue('urlopen' in dir(urllib.request))
class TestFutureMoves(CodeHandler):
def test_future_moves_urllib_request(self):
from future.moves.urllib import request as urllib_request
functions = ['getproxies',
'pathname2url',
'proxy_bypass',
'quote',
'request_host',
'splitattr',
'splithost',
'splitpasswd',
'splitport',
'splitquery',
'splittag',
'splittype',
'splituser',
'splitvalue',
'thishost',
'to_bytes',
'unquote',
# 'unquote_to_bytes', # Is there an equivalent in the Py2 stdlib?
'unwrap',
'url2pathname',
'urlcleanup',
'urljoin',
'urlopen',
'urlparse',
'urlretrieve',
'urlsplit',
'urlunparse']
self.assertTrue(all(fn in dir(urllib_request) for fn in functions))
def test_future_moves(self):
"""
Ensure everything is available from the future.moves interface that we
claim and expect. (Issue #104).
"""
from future.moves.collections import Counter, OrderedDict # backported to Py2.6
from future.moves.collections import UserDict, UserList, UserString
from future.moves import configparser
from future.moves import copyreg
from future.moves.itertools import filterfalse, zip_longest
from future.moves import html
import future.moves.html.entities
import future.moves.html.parser
from future.moves import http
import future.moves.http.client
import future.moves.http.cookies
import future.moves.http.cookiejar
import future.moves.http.server
from future.moves import queue
from future.moves import socketserver
from future.moves.subprocess import check_output # even on Py2.6
from future.moves.subprocess import getoutput, getstatusoutput
from future.moves.sys import intern
from future.moves import urllib
import future.moves.urllib.error
import future.moves.urllib.parse
import future.moves.urllib.request
import future.moves.urllib.response
import future.moves.urllib.robotparser
try:
# Is _winreg available on Py2? If so, ensure future.moves._winreg is available too:
import _winreg
except ImportError:
pass
else:
from future.moves import winreg
from future.moves import xmlrpc
import future.moves.xmlrpc.client
import future.moves.xmlrpc.server
from future.moves import _dummy_thread
from future.moves import _markupbase
from future.moves import _thread
def test_future_moves_dbm(self):
"""
Do the dbm imports work?
"""
from future.moves import dbm
dbm.ndbm
from future.moves.dbm import dumb
try:
# Is gdbm available on Py2? If so, ensure dbm.gnu is available too:
import gdbm
except ImportError:
pass
else:
from future.moves.dbm import gnu
from future.moves.dbm import ndbm
# Running the following tkinter test causes the following bizarre test failure:
#
# ======================================================================
# FAIL: test_open_default_encoding (future.tests.test_builtins.BuiltinTest)
# ----------------------------------------------------------------------
# Traceback (most recent call last):
# File "/home/user/Install/BleedingEdge/python-future/future/tests/test_builtins.py", line 1219, in test_open_default_encoding
# self.assertEqual(fp.encoding, current_locale_encoding)
# AssertionError: 'ANSI_X3.4-1968' != 'ISO-8859-1'
#
# ----------------------------------------------------------------------
#
# def test_future_moves_tkinter(self):
# """
# Do the tkinter imports work?
# """
# from future.moves import tkinter
# from future.moves.tkinter import dialog
# from future.moves.tkinter import filedialog
# from future.moves.tkinter import scrolledtext
# from future.moves.tkinter import simpledialog
# from future.moves.tkinter import tix
# from future.moves.tkinter import constants
# from future.moves.tkinter import dnd
# from future.moves.tkinter import colorchooser
# from future.moves.tkinter import commondialog
# from future.moves.tkinter import font
# from future.moves.tkinter import messagebox
if __name__ == '__main__':
unittest.main()