Adding regression test for issue6727

This commit is contained in:
Jason R. Coombs 2012-01-15 11:45:27 -05:00
parent 0737b7281e
commit 4a24283272
1 changed files with 116 additions and 2 deletions

View File

@ -7,9 +7,11 @@ import random
import stat import stat
import sys import sys
import unittest import unittest
import textwrap
import shutil
from test.test_support import (unlink, TESTFN, unload, run_unittest, rmtree, from test.test_support import (unlink, TESTFN, unload, run_unittest, rmtree,
is_jython, check_warnings, EnvironmentVarGuard) is_jython, check_warnings, EnvironmentVarGuard)
import textwrap
from test import script_helper from test import script_helper
def remove_files(name): def remove_files(name):
@ -488,8 +490,120 @@ class RelativeImportTests(unittest.TestCase):
"implicit absolute import") "implicit absolute import")
class TestSymbolicallyLinkedPackage(unittest.TestCase):
package_name = 'sample'
def setUp(self):
if os.path.exists('sample-tagged'): shutil.rmtree('sample-tagged')
self.orig_sys_path = sys.path[:]
symlink = getattr(os, 'symlink', None) or self._symlink_win32
# create a sample package; imagine you have a package with a tag and
# you want to symbolically link it from its untagged name.
os.mkdir(self.tagged)
init_file = os.path.join(self.tagged, '__init__.py')
open(init_file, 'w').close()
assert os.path.exists(init_file)
# now create a symlink to the tagged package
# sample -> sample-tagged
symlink(self.tagged, self.package_name)
assert os.path.isdir(self.package_name)
assert os.path.isfile(os.path.join(self.package_name, '__init__.py'))
@property
def tagged(self):
return self.package_name + '-tagged'
@classmethod
def _symlink_win32(cls, target, link, target_is_directory=False):
"""
Ctypes symlink implementation since Python doesn't support
symlinks in windows yet. Borrowed from jaraco.windows project.
"""
import ctypes.wintypes
CreateSymbolicLink = ctypes.windll.kernel32.CreateSymbolicLinkW
CreateSymbolicLink.argtypes = (
ctypes.wintypes.LPWSTR,
ctypes.wintypes.LPWSTR,
ctypes.wintypes.DWORD,
)
CreateSymbolicLink.restype = ctypes.wintypes.BOOLEAN
def format_system_message(errno):
"""
Call FormatMessage with a system error number to retrieve
the descriptive error message.
"""
# first some flags used by FormatMessageW
ALLOCATE_BUFFER = 0x100
ARGUMENT_ARRAY = 0x2000
FROM_HMODULE = 0x800
FROM_STRING = 0x400
FROM_SYSTEM = 0x1000
IGNORE_INSERTS = 0x200
# Let FormatMessageW allocate the buffer (we'll free it below)
# Also, let it know we want a system error message.
flags = ALLOCATE_BUFFER | FROM_SYSTEM
source = None
message_id = errno
language_id = 0
result_buffer = ctypes.wintypes.LPWSTR()
buffer_size = 0
arguments = None
bytes = ctypes.windll.kernel32.FormatMessageW(
flags,
source,
message_id,
language_id,
ctypes.byref(result_buffer),
buffer_size,
arguments,
)
# note the following will cause an infinite loop if GetLastError
# repeatedly returns an error that cannot be formatted, although
# this should not happen.
handle_nonzero_success(bytes)
message = result_buffer.value
ctypes.windll.kernel32.LocalFree(result_buffer)
return message
def handle_nonzero_success(result):
if result == 0:
value = ctypes.windll.kernel32.GetLastError()
strerror = format_system_message(value)
raise WindowsError(value, strerror)
target_is_directory = target_is_directory or os.path.isdir(target)
handle_nonzero_success(CreateSymbolicLink(link, target, target_is_directory))
# regression test for issue6727
@unittest.skipUnless(
not hasattr(sys, 'getwindowsversion')
or sys.getwindowsversion() >= (6,0),
"Windows Vista or later required")
def test_symlinked_dir_importable(self):
# make sure sample can only be imported from the current directory.
sys.path[:] = ['.']
# and try to import the package
pkg = __import__(self.package_name)
def tearDown(self):
# now cleanup
if os.path.exists(self.package_name):
os.rmdir(self.package_name)
if os.path.exists(self.tagged):
shutil.rmtree(self.tagged)
sys.path[:] = self.orig_sys_path
def test_main(verbose=None): def test_main(verbose=None):
run_unittest(ImportTests, PycRewritingTests, PathsTests, RelativeImportTests) run_unittest(ImportTests, PycRewritingTests, PathsTests,
RelativeImportTests, TestSymbolicallyLinkedPackage)
if __name__ == '__main__': if __name__ == '__main__':
# Test needs to be a package, so we can do relative imports. # Test needs to be a package, so we can do relative imports.