Skip to content

Commit fda1751

Browse files
committed
stdlib/os: implement fdopen
Signed-off-by: Sebastien Binet <binet@cern.ch>
1 parent 88633c0 commit fda1751

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

stdlib/os/os.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import (
99
"os"
1010
"os/exec"
1111
"runtime"
12+
"strconv"
1213
"strings"
1314

1415
"github.com/go-python/gpython/py"
@@ -45,6 +46,7 @@ func init() {
4546

4647
methods := []*py.Method{
4748
py.MustNewMethod("_exit", _exit, 0, "Immediate program termination."),
49+
py.MustNewMethod("fdopen", fdopen, 0, fdopen_doc),
4850
py.MustNewMethod("getcwd", getCwd, 0, "Get the current working directory"),
4951
py.MustNewMethod("getcwdb", getCwdb, 0, "Get the current working directory in a byte slice"),
5052
py.MustNewMethod("chdir", chdir, 0, "Change the current working directory"),
@@ -96,6 +98,53 @@ func getEnvVariables() py.StringDict {
9698
return dict
9799
}
98100

101+
const fdopen_doc = `# Supply os.fdopen()`
102+
103+
func fdopen(self py.Object, args py.Tuple, kwargs py.StringDict) (py.Object, error) {
104+
var (
105+
pyfd py.Object
106+
pymode py.Object = py.String("r")
107+
pybuffering py.Object = py.Int(-1)
108+
pyencoding py.Object = py.None
109+
)
110+
err := py.ParseTupleAndKeywords(
111+
args, kwargs,
112+
"i|s#is#", []string{"fd", "mode", "buffering", "encoding"},
113+
&pyfd, &pymode, &pybuffering, &pyencoding,
114+
)
115+
if err != nil {
116+
return nil, err
117+
}
118+
119+
// FIXME(sbinet): handle buffering
120+
// FIXME(sbinet): handle encoding
121+
122+
var (
123+
fd = uintptr(pyfd.(py.Int))
124+
name = strconv.Itoa(int(fd))
125+
mode string
126+
)
127+
128+
switch v := pymode.(type) {
129+
case py.String:
130+
mode = string(v)
131+
case py.Bytes:
132+
mode = string(v)
133+
}
134+
135+
perm, _, _, err := py.FileModeFrom(mode)
136+
if err != nil {
137+
return nil, err
138+
}
139+
140+
f := os.NewFile(fd, name)
141+
if f == nil {
142+
return nil, py.ExceptionNewf(py.OSError, "Bad file descriptor")
143+
}
144+
145+
return &py.File{f, perm}, nil
146+
}
147+
99148
// getCwd returns the current working directory.
100149
func getCwd(self py.Object, args py.Tuple) (py.Object, error) {
101150
dir, err := os.Getwd()

stdlib/os/testdata/test.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,15 @@
118118
else:
119119
print("os."+k+": [OK]")
120120

121+
## fdopen
122+
import tempfile
123+
fd, tmp = tempfile.mkstemp()
124+
f = os.fdopen(fd, "w+")
125+
## if f.name != str(fd):
126+
## print("invalid fd-name:", f.name)
127+
f.close()
128+
os.remove(tmp)
129+
121130
## mkdir,rmdir,remove,removedirs
122131
import tempfile
123132
try:

0 commit comments

Comments
 (0)