[pypy-svn] pypy default: Implement os.mkdir with the Win32 API
amauryfa
commits-noreply at bitbucket.org
Thu Jan 20 19:36:50 CET 2011
Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch:
Changeset: r41070:8cf11c9e2892
Date: 2011-01-20 17:05 +0100
http://bitbucket.org/pypy/pypy/changeset/8cf11c9e2892/
Log: Implement os.mkdir with the Win32 API
diff --git a/pypy/rpython/module/ll_os.py b/pypy/rpython/module/ll_os.py
--- a/pypy/rpython/module/ll_os.py
+++ b/pypy/rpython/module/ll_os.py
@@ -73,6 +73,7 @@
charp2str = staticmethod(rffi.charp2str)
str2charp = staticmethod(rffi.str2charp)
free_charp = staticmethod(rffi.free_charp)
+ scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_buffer)
@staticmethod
def posix_function_name(name):
@@ -89,6 +90,7 @@
charp2str = staticmethod(rffi.wcharp2unicode)
str2charp = staticmethod(rffi.unicode2wcharp)
free_charp = staticmethod(rffi.free_wcharp)
+ scoped_alloc_buffer = staticmethod(rffi.scoped_alloc_unicodebuffer)
@staticmethod
def posix_function_name(name):
@@ -1292,24 +1294,25 @@
@registering_str_unicode(os.mkdir)
def register_os_mkdir(self, traits):
- if os.name == 'nt':
- ARG2 = [] # no 'mode' argument on Windows - just ignored
+ os_mkdir = self.llexternal(traits.posix_function_name('mkdir'),
+ [traits.CCHARP, rffi.MODE_T], rffi.INT)
+
+ if sys.platform == 'win32':
+ from pypy.rpython.module.ll_win32file import make_win32_traits
+ win32traits = make_win32_traits(traits)
+
+ @func_renamer('mkdir_llimpl_%s' % traits.str.__name__)
+ def os_mkdir_llimpl(path, mode):
+ if not win32traits.CreateDirectory(path, None):
+ raise rwin32.lastWindowsError()
else:
- ARG2 = [rffi.MODE_T]
- os_mkdir = self.llexternal(traits.posix_function_name('mkdir'),
- [traits.CCHARP] + ARG2, rffi.INT)
- IGNORE_MODE = len(ARG2) == 0
+ def os_mkdir_llimpl(pathname, mode):
+ res = os_mkdir(pathname, mode)
+ res = rffi.cast(lltype.Signed, res)
+ if res < 0:
+ raise OSError(rposix.get_errno(), "os_mkdir failed")
- def mkdir_llimpl(pathname, mode):
- if IGNORE_MODE:
- res = os_mkdir(pathname)
- else:
- res = os_mkdir(pathname, mode)
- res = rffi.cast(lltype.Signed, res)
- if res < 0:
- raise OSError(rposix.get_errno(), "os_mkdir failed")
-
- return extdef([traits.str, int], s_None, llimpl=mkdir_llimpl,
+ return extdef([traits.str, int], s_None, llimpl=os_mkdir_llimpl,
export_name=traits.ll_os_name('mkdir'))
@registering_str_unicode(os.rmdir)
diff --git a/pypy/rpython/module/ll_win32file.py b/pypy/rpython/module/ll_win32file.py
--- a/pypy/rpython/module/ll_win32file.py
+++ b/pypy/rpython/module/ll_win32file.py
@@ -139,6 +139,11 @@
[traits.CCHARP],
rwin32.BOOL)
+ CreateDirectory = external(
+ 'CreateDirectory' + suffix,
+ [traits.CCHARP, rffi.VOIDP],
+ rwin32.BOOL)
+
SetEnvironmentVariable = external(
'SetEnvironmentVariable' + suffix,
[traits.CCHARP, traits.CCHARP],
@@ -232,14 +237,14 @@
if not win32traits.SetCurrentDirectory(path):
raise rwin32.lastWindowsError()
- with rffi.scoped_alloc_buffer(rwin32.MAX_PATH) as path:
+ with traits.scoped_alloc_buffer(rwin32.MAX_PATH) as path:
res = win32traits.GetCurrentDirectory(rwin32.MAX_PATH + 1, path.raw)
if not res:
raise rwin32.lastWindowsError()
if res <= rwin32.MAX_PATH + 1:
new_path = path.str(rffi.cast(lltype.Signed, res))
else:
- with rffi.scoped_alloc_buffer(rwin32.MAX_PATH) as path:
+ with traits.scoped_alloc_buffer(rwin32.MAX_PATH) as path:
res = win32traits.GetCurrentDirectory(res, path.raw)
if not res:
raise rwin32.lastWindowsError()
diff --git a/pypy/rpython/module/test/test_ll_os.py b/pypy/rpython/module/test/test_ll_os.py
--- a/pypy/rpython/module/test/test_ll_os.py
+++ b/pypy/rpython/module/test/test_ll_os.py
@@ -82,6 +82,14 @@
finally:
os.chdir(pwd)
+def test_mkdir():
+ filename = str(udir.join('test_mkdir.dir'))
+ getllimpl(os.mkdir)(filename, 0)
+ exc = raises(OSError, getllimpl(os.mkdir), filename, 0)
+ assert exc.value.errno == errno.EEXIST
+ if sys.platform == 'win32':
+ assert exc.type is WindowsError
+
def test_strerror():
data = getllimpl(os.strerror)(2)
assert data == os.strerror(2)
More information about the Pypy-commit
mailing list