Skip to content

Commit 3965f0d

Browse files
authored
Accept bytes as filename arg to compile (#1480)
1 parent 2dffbc1 commit 3965f0d

4 files changed

Lines changed: 26 additions & 17 deletions

File tree

Src/IronPython/Modules/Builtin.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -162,47 +162,51 @@ public static object chr(int value) {
162162
"eval compiles the code as if were an expression\n" +
163163
"single compiles a single statement\n\n" +
164164
"source can either be a string, bytes or an AST object")]
165-
public static object compile(CodeContext/*!*/ context, [NotNone] _ast.AST source, [NotNone] string filename, [NotNone] string mode, object? flags = null, bool dont_inherit = false, int optimize = -1) {
165+
public static object compile(CodeContext/*!*/ context, [NotNone] _ast.AST source, [NotNone] object filename, [NotNone] string mode, object? flags = null, bool dont_inherit = false, int optimize = -1) {
166166
// TODO: implement optimize
167167

168+
string sfilename = PythonOps.FsPathDecoded(context, filename);
168169
ValidateCompileMode(mode);
169170

170171
bool astOnly = flags != null && (Converter.ConvertToInt32(flags) & _ast.PyCF_ONLY_AST) != 0;
171172

172173
if (astOnly) {
173174
return source;
174175
} else {
175-
PythonAst ast = _ast.ConvertToPythonAst(context, (_ast.AST)source, filename);
176+
PythonAst ast = _ast.ConvertToPythonAst(context, (_ast.AST)source, sfilename);
176177
ast.Bind();
177178
ScriptCode code = ast.ToScriptCode();
178179
return ((RunnableScriptCode)code).GetFunctionCode(true);
179180
}
180181
}
181182

182183
[Documentation("")] // provided by first overload
183-
public static object compile(CodeContext/*!*/ context, [NotNone] IBufferProtocol source, [NotNone] string filename, [NotNone] string mode, object? flags = null, bool dont_inherit = false, int optimize = -1) {
184+
public static object compile(CodeContext/*!*/ context, [NotNone] IBufferProtocol source, [NotNone] object filename, [NotNone] string mode, object? flags = null, bool dont_inherit = false, int optimize = -1) {
184185
// TODO: implement optimize
186+
187+
string sfilename = PythonOps.FsPathDecoded(context, filename);
185188
var sourceCodeKind = ValidateCompileMode(mode);
186189

187190
using var buffer = source.GetBuffer();
188191
byte[] bytes = buffer.AsUnsafeArray() ?? buffer.ToArray();
189-
var contentProvider = new MemoryStreamContentProvider(context.LanguageContext, bytes, filename);
190-
var sourceUnit = context.LanguageContext.CreateSourceUnit(contentProvider, filename, sourceCodeKind);
192+
var contentProvider = new MemoryStreamContentProvider(context.LanguageContext, bytes, sfilename);
193+
var sourceUnit = context.LanguageContext.CreateSourceUnit(contentProvider, sfilename, sourceCodeKind);
191194

192195
return CompileHelper(context, sourceUnit, mode, flags, dont_inherit);
193196
}
194197

195198
[Documentation("")] // provided by first overload
196-
public static object compile(CodeContext/*!*/ context, [NotNone] string source, [NotNone] string filename, [NotNone] string mode, object? flags = null, bool dont_inherit = false, int optimize = -1) {
199+
public static object compile(CodeContext/*!*/ context, [NotNone] string source, [NotNone] object filename, [NotNone] string mode, object? flags = null, bool dont_inherit = false, int optimize = -1) {
197200
// TODO: implement optimize
198201

202+
string sfilename = PythonOps.FsPathDecoded(context, filename);
199203
var sourceCodeKind = ValidateCompileMode(mode);
200204

201205
if (source.IndexOf('\0') != -1) {
202206
throw PythonOps.TypeError("compile() expected string without null bytes");
203207
}
204208

205-
var sourceUnit = context.LanguageContext.CreateSnippet(source, filename, sourceCodeKind);
209+
var sourceUnit = context.LanguageContext.CreateSnippet(source, sfilename, sourceCodeKind);
206210

207211
return CompileHelper(context, sourceUnit, mode, flags, dont_inherit);
208212
}

Src/IronPython/Modules/_io.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2794,13 +2794,7 @@ public static _IOBase open(
27942794
string fname = null;
27952795
if (!Converter.TryConvertToIndex(file, out int fd, false, false)) {
27962796
fd = -1;
2797-
var path = PythonOps.FsPath(file);
2798-
fname = path switch {
2799-
string s => s,
2800-
Extensible<string> es => es,
2801-
Bytes b => b.decode(context, SysModule.getfilesystemencoding(), SysModule.getfilesystemencodeerrors()),
2802-
_ => throw new InvalidOperationException(),
2803-
};
2797+
fname = PythonOps.FsPathDecoded(context, file);
28042798
}
28052799

28062800
HashSet<char> modes = MakeSet(mode);

Src/IronPython/Runtime/Operations/PythonOps.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -342,6 +342,15 @@ internal static object FsPath(object? path) {
342342
throw PythonOps.TypeError("expected str, bytes or os.PathLike object, not {0}", PythonOps.GetPythonTypeName(path));
343343
}
344344

345+
internal static string FsPathDecoded(CodeContext context, object? path) {
346+
return PythonOps.FsPath(path) switch {
347+
string s => s,
348+
Extensible<string> es => es,
349+
Bytes b => b.decode(context, SysModule.getfilesystemencoding(), SysModule.getfilesystemencodeerrors()),
350+
_ => throw new InvalidOperationException(),
351+
};
352+
}
353+
345354
public static object Plus(object? o) {
346355
if (o is int) return o;
347356
else if (o is double) return o;

Tests/test_builtinfunc.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -671,9 +671,11 @@ def f():
671671
f()
672672

673673
def test_compile(self):
674-
for x in ['exec', 'eval', 'single']:
675-
c = compile('2', 'foo', x)
676-
self.assertEqual(c.co_filename, 'foo')
674+
for mode in ['exec', 'eval', 'single']:
675+
for filename in ['foo', b'foo']:
676+
for source in ['2', b'2']:
677+
c = compile(source, filename, mode)
678+
self.assertEqual(c.co_filename, 'foo')
677679

678680
class mystdout(object):
679681
def __init__(self):

0 commit comments

Comments
 (0)