<commit_before>from __future__ import absolute_import

import os
import time

from rpython.rlib.rfloat import round_double
from rpython.rlib.rstring import assert_str0
from rpython.rlib.streamio import open_file_as_stream

from topaz.error import RubyError
from topaz.module import Module, ModuleDef
from topaz.modules.process import Process
from topaz.objects.exceptionobject import W_ExceptionObject
from topaz.objects.procobject import W_ProcObject
from topaz.objects.stringobject import W_StringObject


class Kernel(Module):
    moduledef = ModuleDef("Kernel", filepath=__file__)

    @moduledef.method("class")
    def function_class(self, space):
        return space.getnonsingletonclass(self)

    @moduledef.method("singleton_methods", all="bool")
    def method_singleton_methods(self, space, all=True):
        methods = []
        w_cls = space.getclass(self)
        if w_cls.is_singleton:
            methods.extend(w_cls.methods_w.keys())
            w_cls = w_cls.superclass
        if all:
            while w_cls and w_cls.is_singleton:
                methods.extend(w_cls.methods_w.keys())
                w_cls = w_cls.superclass
        return space.newarray([space.newsymbol(m) for m in methods])

    @moduledef.method("lambda")
    def function_lambda(self, space, block):
        return space.newproc(block, True)

    @moduledef.method("proc")
    def function_proc(self, space, block):
        return space.newproc(block, False)

    @staticmethod
    def find_feature(space, path):
        assert path is not None
        if os.path.exists(path):
            return path
        if not path.endswith(".rb"):
            path += ".rb"

        if not (path.startswith("/") or path.startswith("./") or path.startswith("../")):
            w_load_path = space.globals.get(space, "$LOAD_PATH")
            for w_base in space.listview(w_load_path):
                base = space.str_w(w_base)
                full = os.path.join(base, path)
                if os.path.exists(assert_str0(full)):
                    path = os.path.join(base, path)
                    break
        return path

    @staticmethod
    def load_feature(space, path, orig_path):
        if not os.path.exists(assert_str0(path)):
            raise space.error(space.w_LoadError, orig_path)

        f = open_file_as_stream(path)
        try:
            contents = f.readall()
        finally:
            f.close()

        space.execute(contents, filepath=path)

    @moduledef.function("require", path="path")
    def function_require(self, space, path):
        assert path is not None
        orig_path = path
        path = Kernel.find_feature(space, path)

        w_loaded_features = space.globals.get(space, '$"')
        w_already_loaded = space.send(
            w_loaded_features, space.newsymbol("include?"), [space.newstr_fromstr(path)]
        )
        if space.is_true(w_already_loaded):
            return space.w_false

        Kernel.load_feature(space, path, orig_path)
        w_loaded_features.method_lshift(space, space.newstr_fromstr(path))<commit_msg>Fixed #473 -- handle low level errors when reading files<commit_after>from __future__ import absolute_import

import os
import time

from rpython.rlib.rfloat import round_double
from rpython.rlib.rstring import assert_str0
from rpython.rlib.streamio import open_file_as_stream

from topaz.error import RubyError, error_for_oserror
from topaz.module import Module, ModuleDef
from topaz.modules.process import Process
from topaz.objects.exceptionobject import W_ExceptionObject
from topaz.objects.procobject import W_ProcObject
from topaz.objects.stringobject import W_StringObject


class Kernel(Module):
    moduledef = ModuleDef("Kernel", filepath=__file__)

    @moduledef.method("class")
    def function_class(self, space):
        return space.getnonsingletonclass(self)

    @moduledef.method("singleton_methods", all="bool")
    def method_singleton_methods(self, space, all=True):
        methods = []
        w_cls = space.getclass(self)
        if w_cls.is_singleton:
            methods.extend(w_cls.methods_w.keys())
            w_cls = w_cls.superclass
        if all:
            while w_cls and w_cls.is_singleton:
                methods.extend(w_cls.methods_w.keys())
                w_cls = w_cls.superclass
        return space.newarray([space.newsymbol(m) for m in methods])

    @moduledef.method("lambda")
    def function_lambda(self, space, block):
        return space.newproc(block, True)

    @moduledef.method("proc")
    def function_proc(self, space, block):
        return space.newproc(block, False)

    @staticmethod
    def find_feature(space, path):
        assert path is not None
        if os.path.exists(path):
            return path
        if not path.endswith(".rb"):
            path += ".rb"

        if not (path.startswith("/") or path.startswith("./") or path.startswith("../")):
            w_load_path = space.globals.get(space, "$LOAD_PATH")
            for w_base in space.listview(w_load_path):
                base = space.str_w(w_base)
                full = os.path.join(base, path)
                if os.path.exists(assert_str0(full)):
                    path = os.path.join(base, path)
                    break
        return path

    @staticmethod
    def load_feature(space, path, orig_path):
        if not os.path.exists(assert_str0(path)):
            raise space.error(space.w_LoadError, orig_path)

        try:
            f = open_file_as_stream(path)
            try:
                contents = f.readall()
            finally:
                f.close()
        except OSError as e:
            raise error_for_oserror(space, e)

        space.execute(contents, filepath=path)

    @moduledef.function("require", path="path")
    def function_require(self, space, path):
        assert path is not None
        orig_path = path
        path = Kernel.find_feature(space, path)

        w_loaded_features = space.globals.get(space, '$"')
        w_already_loaded = space.send(
            w_loaded_features, space.newsymbol("include?"), [space.newstr_fromstr(path)]
        )
        if space.is_true(w_already_loaded):
            return space.w_false

        Kernel.load_feature(space, path, orig_path)
        w_loaded_features.method_lshift(space, space.newstr_fromstr(path))
{'fraction_non_alphanumeric': 0.0990521327014218, 'fraction_numerical': 0.0014218009478672985, 'mean_word_length': 2.570783981951495, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7213875', 'n_tokens_mistral': 1950, 'n_tokens_neox': 1888, 'n_words': 412}