Skip to content
This repository was archived by the owner on Mar 23, 2023. It is now read-only.

Allow sys.stdout to be replaced #302

Open
wants to merge 11 commits into
base: master
Choose a base branch
from
39 changes: 39 additions & 0 deletions lib/_gomodulehacks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# coding: utf-8

from __go__.grumpy import SysModules
import errno

# For some reason, importing and extending grumpy.Module does not work.
Module = type(errno)


def hybrid_module(modulename, modulefile, moduledict, all_attrs, globals_):
"""
Augment native 'moduledict' with Python-sourced parts

Allows 'modulename' to use 'moduledict' from outside,
for example a Grumpy dict from native module.

And does include the resulting module on sys.modules at the end.

Should be called as:
hybrid_module(__name__, __file__, YourmoduleDict, __all__, globals())
On the last line of the Python-part of the module
"""
class HybridModule(Module):
def __init__(self):
moduledict['__name__'] = modulename
moduledict['__file__'] = modulefile
for k in all_attrs:
moduledict[k] = globals_[k]
def __setattr__(self, name, value):
moduledict[name] = value
def __getattribute__(self, name): # TODO: replace w/ __getattr__ when implemented
resp = moduledict.get(name)
if resp is None and name not in moduledict:
return super(HybridModule, self).__getattribute__(name)
return resp

finalmodule = HybridModule()
SysModules[modulename] = finalmodule
return finalmodule
68 changes: 43 additions & 25 deletions lib/sys.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,43 +15,57 @@
"""System-specific parameters and functions."""

from __go__.os import Args
from __go__.grumpy import SysModules, MaxInt, Stdin as stdin, Stdout as stdout, Stderr as stderr # pylint: disable=g-multiple-import
from __go__.grumpy import SysmoduleDict, SysModules, MaxInt # pylint: disable=g-multiple-import
from __go__.runtime import (GOOS as platform, Version)
from __go__.unicode import MaxRune
import _gomodulehacks


__all__ = ('stdin', 'stdout', 'stderr', 'argv', 'goversion',
'maxint', 'maxsize', 'maxunicode', 'modules', 'platform', 'py3kwarning',
'warnoptions', 'byteorder', 'flags', 'exc_info', 'exit')


argv = []
for arg in Args:
argv.append(arg)
argv.append(arg)

goversion = Version()

stdin = SysmoduleDict['stdin']
stdout = SysmoduleDict['stdout']
stderr = SysmoduleDict['stderr']

maxint = MaxInt
maxsize = maxint
maxunicode = MaxRune
modules = SysModules

py3kwarning = False
warnoptions = []
# TODO: Support actual byteorder
byteorder = 'little'
version = '2.7.13'


class _Flags(object):
"""Container class for sys.flags."""
debug = 0
py3k_warning = 0
division_warning = 0
division_new = 0
inspect = 0
interactive = 0
optimize = 0
dont_write_bytecode = 0
no_user_site = 0
no_site = 0
ignore_environment = 0
tabcheck = 0
verbose = 0
unicode = 0
bytes_warning = 0
hash_randomization = 0
"""Container class for sys.flags."""
debug = 0
py3k_warning = 0
division_warning = 0
division_new = 0
inspect = 0
interactive = 0
optimize = 0
dont_write_bytecode = 0
no_user_site = 0
no_site = 0
ignore_environment = 0
tabcheck = 0
verbose = 0
unicode = 0
bytes_warning = 0
hash_randomization = 0


flags = _Flags()
Expand All @@ -62,12 +76,16 @@ def exc_clear():


def exc_info():
e, tb = __frame__().__exc_info__() # pylint: disable=undefined-variable
t = None
if e:
t = type(e)
return t, e, tb
e, tb = __frame__().__exc_info__() # pylint: disable=undefined-variable
t = None
if e:
t = type(e)
return t, e, tb


def exit(code=None): # pylint: disable=redefined-builtin
raise SystemExit(code)
raise SystemExit(code)


# Should be the last line of the python part of hybrid stuff
_gomodulehacks.hybrid_module(__name__, __file__, SysmoduleDict, __all__, globals())
26 changes: 26 additions & 0 deletions runtime/sysmodule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package grumpy

var (
// SysmoduleDict is the __dict__ of the native part of sys.py.
SysmoduleDict = newStringDict(map[string]*Object{
"__file__": NewStr("<native>").ToObject(),
"__name__": NewStr("_sys").ToObject(),
"stdin": Stdin.ToObject(),
"stdout": Stdout.ToObject(),
"stderr": Stderr.ToObject(),
})
)
15 changes: 15 additions & 0 deletions testing/sysmodule_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from StringIO import StringIO
import sys

print 'To sys.stdout'

old_stdout = sys.stdout
sio = StringIO()
sys.stdout = sio

print 'To replaced sys.stdout'

sys.stdout = old_stdout
print 'To original sys.stdout'

assert sio.tell() == len('To replaced sys.stdout')+1, 'Should had printed to StringIO, not STDOUT'