<commit_before>require 'forwardable'

module MemFs
  class File
    extend SingleForwardable

    OriginalFile.constants.grep(/^[A-Z_]+$/).each do |const|
      const_set const, OriginalFile.const_get(const)
    end

    MODE_MAP = {
      'r'  => RDONLY,
      'r+' => RDWR,
      'w'  => CREAT|TRUNC|WRONLY,
      'w+' => CREAT|TRUNC|RDWR,
      'a'  => CREAT|APPEND|WRONLY,
      'a+' => CREAT|APPEND|RDWR
    }

    SUCCESS = 0

    def_delegators :original_file_class,
                   :basename,
                   :dirname,
                   :path

    def self.chmod(mode_int, *paths)
      paths.each do |path|
        fs.chmod mode_int, path
      end
    end

    def self.lchmod(mode_int, *file_names)
      file_names.each do |file_name|
        fs.chmod mode_int, file_name
      end
    end

    def self.directory?(path)
      fs.directory? path
    end

    def self.utime(atime, mtime, *file_names)
      file_names.each do |file_name|
        fs.find!(file_name).atime = atime
        fs.find!(file_name).mtime = mtime
      end
      file_names.size
    end

    def self.symlink(old_name, new_name)
      fs.symlink old_name, new_name
      SUCCESS
    end

    def self.symlink?(path)
      fs.symlink? path
    end

    def self.stat(path)
      Stat.new(path, true)
    end

    def self.lstat(path)
      Stat.new(path)
    end

    def self.umask(integer = nil)
      old_value = @umask

      if integer
        @umask = integer
      end

      old_value
    end

    def self.atime(path)
      stat(path).atime
    end

    def self.mtime(path)
      stat(path).mtime
    end

    def self.reset!
      @umask = original_file_class.umask
    end

    def self.open(filename, mode = RDONLY, *perm_and_opt)
      file = self.new(filename, mode, *perm_and_opt)

      if block_given?
        yield file
      else
        file
      end
    ensure
      file.close if file && block_given?
    end

    def self.join(*args)
      original_file_class.join(*args)
    end

    def self.chown(uid, gid, *paths)
      paths.each do |path|
        fs.chown(uid, gid, path)
      end
      paths.size
    end

    def self.lchown(uid, gid, *paths)
      chown uid, gid, *paths
    end

    def self.size(path)
      fs.find!(path).content.size
    end

    def self.identical?(path1, path2)
      fs.find!(path1).dereferenced === fs.find!(path2).dereferenced
    rescue Errno::ENOENT
      false
    end

    def self.read(path, length = nil, offset = 0, mode: RDONLY, encoding: nil, open_args: nil)
      open_args ||= [mode, encoding: encoding]

      file = open(path, *open_args)
      file.seek(offset)
      file.read(length)
    ensure
      file.close if file
    end

    def self.expand_path(file_name, dir_string = fs.pwd)
      OriginalFile.expand_path(file_name, dir_string)
    end

    def self.exists?(path)
      not fs.find(path).nil?
    end
    class << self; alias :exist? :exists?; end

    def self.link(old_name, new_name)
      fs.link old_name, new_name
      SUCCESS
    end

    def self.unlink(*paths)
      paths.each do |path|
        fs.unlink(path)
      end
      paths.size
    end
    class << self; alias :delete :unlink; end

    def self.rename(old_name, new_name)
      fs.rename(old_name, new_name)
      SUCCESS
    end

    def self.file?(path)
      fs.find(path).is_a?(Fake::File)
    end

    def self.readlink(path)
      fs.find!(path).target
    end

    attr_accessor :closed
    attr_accessor :entry
    attr_accessor :opening_mode
    attr_reader :path

    def initialize(filename, mode = RDONLY, perm = nil, opt = nil)
      unless opt.nil? || opt.is_a?(Hash)
        raise ArgumentError, "wrong number of arguments (4 for 1..3)"
      end

      @path = filename

      self.opening_mode = str_to_mode_int(mode)

      fs.touch(filename) if create_file?

      self.entry = fs.find(filename)
    end

    def close<commit_msg>Sorting File class methods by name<commit_after>require 'forwardable'

module MemFs
  class File
    extend SingleForwardable

    OriginalFile.constants.grep(/^[A-Z_]+$/).each do |const|
      const_set const, OriginalFile.const_get(const)
    end

    MODE_MAP = {
      'r'  => RDONLY,
      'r+' => RDWR,
      'w'  => CREAT|TRUNC|WRONLY,
      'w+' => CREAT|TRUNC|RDWR,
      'a'  => CREAT|APPEND|WRONLY,
      'a+' => CREAT|APPEND|RDWR
    }

    SUCCESS = 0

    def_delegators :original_file_class,
                   :basename,
                   :dirname,
                   :path

    def self.atime(path)
      stat(path).atime
    end

    def self.chmod(mode_int, *paths)
      paths.each do |path|
        fs.chmod mode_int, path
      end
    end

    def self.chown(uid, gid, *paths)
      paths.each do |path|
        fs.chown(uid, gid, path)
      end
      paths.size
    end

    def self.directory?(path)
      fs.directory? path
    end

    def self.exists?(path)
      not fs.find(path).nil?
    end
    class << self; alias :exist? :exists?; end

    def self.expand_path(file_name, dir_string = fs.pwd)
      OriginalFile.expand_path(file_name, dir_string)
    end

    def self.file?(path)
      fs.find(path).is_a?(Fake::File)
    end

    def self.identical?(path1, path2)
      fs.find!(path1).dereferenced === fs.find!(path2).dereferenced
    rescue Errno::ENOENT
      false
    end

    def self.join(*args)
      original_file_class.join(*args)
    end

    def self.lchmod(mode_int, *file_names)
      file_names.each do |file_name|
        fs.chmod mode_int, file_name
      end
    end

    def self.lchown(uid, gid, *paths)
      chown uid, gid, *paths
    end

    def self.link(old_name, new_name)
      fs.link old_name, new_name
      SUCCESS
    end

    def self.lstat(path)
      Stat.new(path)
    end

    def self.mtime(path)
      stat(path).mtime
    end

    def self.open(filename, mode = RDONLY, *perm_and_opt)
      file = self.new(filename, mode, *perm_and_opt)

      if block_given?
        yield file
      else
        file
      end
    ensure
      file.close if file && block_given?
    end

    def self.read(path, length = nil, offset = 0, mode: RDONLY, encoding: nil, open_args: nil)
      open_args ||= [mode, encoding: encoding]

      file = open(path, *open_args)
      file.seek(offset)
      file.read(length)
    ensure
      file.close if file
    end

    def self.readlink(path)
      fs.find!(path).target
    end

    def self.rename(old_name, new_name)
      fs.rename(old_name, new_name)
      SUCCESS
    end

    def self.reset!
      @umask = original_file_class.umask
    end

    def self.size(path)
      fs.find!(path).content.size
    end

    def self.stat(path)
      Stat.new(path, true)
    end

    def self.symlink(old_name, new_name)
      fs.symlink old_name, new_name
      SUCCESS
    end

    def self.symlink?(path)
      fs.symlink? path
    end

    def self.umask(integer = nil)
      old_value = @umask

      if integer
        @umask = integer
      end

      old_value
    end

    def self.unlink(*paths)
      paths.each do |path|
        fs.unlink(path)
      end
      paths.size
    end
    class << self; alias :delete :unlink; end

    def self.utime(atime, mtime, *file_names)
      file_names.each do |file_name|
        fs.find!(file_name).atime = atime
        fs.find!(file_name).mtime = mtime
      end
      file_names.size
    end

    attr_accessor :closed
    attr_accessor :entry
    attr_accessor :opening_mode
    attr_reader :path

    def initialize(filename, mode = RDONLY, perm = nil, opt = nil)
      unless opt.nil? || opt.is_a?(Hash)
        raise ArgumentError, "wrong number of arguments (4 for 1..3)"
      end

      @path = filename

      self.opening_mode = str_to_mode_int(mode)

      fs.touch(filename) if create_file?

      self.entry = fs.find(filename)
    end

    def close
{'fraction_non_alphanumeric': 0.1037434521528044, 'fraction_numerical': 0.0022997316979685703, 'mean_word_length': 2.079464988198269, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 15, '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': '1256417', 'n_tokens_mistral': 2807, 'n_tokens_neox': 2688, 'n_words': 618}