Skip to content

Commit 03d633f

Browse files
committed
For stdpy.file wrapper, handle mode more consistently with Python.
For Python 2, ignore unknown characters in the mode rather than silently failing to open. For Python 3, fail if unknown characters appear.
1 parent 888efc1 commit 03d633f

File tree

1 file changed

+47
-23
lines changed

1 file changed

+47
-23
lines changed

direct/src/stdpy/file.py

Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
]
1212

1313
from panda3d import core
14+
import sys
1415
import types
1516

1617
_vfs = core.VirtualFileSystem.getGlobalPtr()
@@ -65,12 +66,27 @@ def __init__(self, filename, mode = 'r', bufsize = None,
6566
self.filename = filename
6667
self.name = filename.toOsSpecific()
6768

69+
if sys.version_info >= (3, 0):
70+
# Python 3 is much stricter than Python 2, which lets
71+
# unknown flags fall through.
72+
for ch in mode:
73+
if not ch in 'rwxabt+U':
74+
raise IOError("invalid mode: " + mode)
75+
6876
binary = False
77+
if 'b' in mode and 't' in mode:
78+
raise IOError("can't have text and binary mode at once")
79+
6980
if 'b' in mode:
7081
# Strip 'b'. This means a binary file.
7182
i = mode.index('b')
7283
mode = mode[:i] + mode[i + 1:]
7384
binary = True
85+
elif 't' in mode:
86+
# Strip 't'. This means a text file (redundant, yes).
87+
i = mode.index('t')
88+
mode = mode[:i] + mode[i + 1:]
89+
binary = False
7490

7591
if 'U' in mode:
7692
# Strip 'U'. We don't use it; universal-newline support
@@ -83,61 +99,69 @@ def __init__(self, filename, mode = 'r', bufsize = None,
8399
mode = 'r'
84100

85101
# Per Python docs, we insist this is true.
86-
assert mode[0] in 'rwa'
102+
modeType = mode[0]
103+
assert modeType in 'rwa'
87104

88105
if binary:
89106
filename.setBinary()
90107
else:
91108
filename.setText()
92-
93-
# Actually open the streams.
94-
if mode == 'w':
95-
self.__stream = _vfs.openWriteFile(filename, autoUnwrap, True)
109+
110+
# Actually open the streams, taking care to
111+
# ignore unknown chars in the mode string.
112+
# We already asserted that it starts with a mode
113+
# char above, so locate the '+'
114+
if modeType == 'w' and '+' in mode:
115+
self.__stream = _vfs.openReadWriteFile(filename, True)
96116
if not self.__stream:
97117
message = 'Could not open %s for writing' % (filename)
98-
raise IOError, message
118+
raise IOError(message)
119+
readMode = True
99120
writeMode = True
100121

101-
elif mode == 'a':
102-
self.__stream = _vfs.openAppendFile(filename)
122+
elif modeType == 'a' and '+' in mode:
123+
self.__stream = _vfs.openReadAppendFile(filename)
103124
if not self.__stream:
104125
message = 'Could not open %s for writing' % (filename)
105-
raise IOError, message
126+
raise IOError(message)
127+
readMode = True
106128
writeMode = True
107129

108-
elif mode == 'w+':
109-
self.__stream = _vfs.openReadWriteFile(filename, True)
130+
elif modeType == 'r' and '+' in mode:
131+
self.__stream = _vfs.openReadWriteFile(filename, False)
110132
if not self.__stream:
111133
message = 'Could not open %s for writing' % (filename)
112-
raise IOError, message
134+
raise IOError(message)
113135
readMode = True
114136
writeMode = True
115-
116-
elif mode == 'a+':
117-
self.__stream = _vfs.openReadAppendFile(filename)
137+
138+
elif modeType == 'w':
139+
self.__stream = _vfs.openWriteFile(filename, autoUnwrap, True)
118140
if not self.__stream:
119141
message = 'Could not open %s for writing' % (filename)
120-
raise IOError, message
121-
readMode = True
142+
raise IOError(message)
122143
writeMode = True
123144

124-
elif mode == 'r+':
125-
self.__stream = _vfs.openReadWriteFile(filename, False)
145+
elif modeType == 'a':
146+
self.__stream = _vfs.openAppendFile(filename)
126147
if not self.__stream:
127148
message = 'Could not open %s for writing' % (filename)
128-
raise IOError, message
129-
readMode = True
149+
raise IOError(message)
130150
writeMode = True
131151

132-
elif mode == 'r':
152+
elif modeType == 'r':
133153
self.__stream = _vfs.openReadFile(filename, autoUnwrap)
134154
if not self.__stream:
135155
if not _vfs.exists(filename):
136156
message = 'No such file: %s' % (filename)
137157
else:
138158
message = 'Could not open %s for reading' % (filename)
139-
raise IOError, message
159+
raise IOError(message)
140160
readMode = True
161+
162+
else:
163+
# should not get here unless there's a bug above
164+
raise IOError("Unhandled mode flags: " + mode)
141165

142166
self.__needsVfsClose = True
143167

0 commit comments

Comments
 (0)