Source code for commandio.fileio

# -*- coding: utf-8 -*-
"""File IO methods, functions and operations for the ``commandio`` package.

.. autosummary::
    :nosignatures:

    File

.. autoclass:: File
    :members:
"""
import os
from typing import List, Optional, Tuple, Union

from commandio.iobase import IOBaseObj, file, directory


[docs]class File(IOBaseObj): """This class creates a ``File`` object that encapsulates a number of methods and properites for file and filename handling, and file manipulation. File object base class that inherits from the ``IOBaseObj`` abstract base class. Attributes: src: Input file. ext: File extension of input file. If no extension is provided, it is inferred. Usage example: >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... file.touch() ... file.write_txt("some text") ... >>> # or >>> >>> file = File("file_name.txt") >>> file "file_name.txt" Args: src: Input file (need not exist at runtime/instantiated). ext: File extension of input file. If no extension is provided, it is inferred. assert_exists: Asserts that the specified input file must exist. """ __slots__ = ("src", "ext") def __init__( self, src: Union[file, str], ext: Optional[str] = "", assert_exists: bool = False, ) -> None: """Initialization method for the File base class. Usage example: >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... file.touch() ... file.write_txt("some text") ... print(file.src) ... "file_name.txt" >>> >>> # or >>> >>> file = File("file_name.txt") >>> file "file_name.txt" Args: src: Input file (need not exist at runtime/instantiated). ext: File extension of input file. If no extension is provided, it is inferred. assert_exists: Asserts that the specified input file must exist. """ self.src: str = src if ext: self.ext: str = ext else: self.ext: str = None super(File, self).__init__(src) if ext: self.ext: str = ext elif self.src.endswith(".gz"): self.ext: str = self.src[-7:] else: _, self.ext = os.path.splitext(self.src) if assert_exists: assert os.path.exists( self.src ), f"Input file {self.src} does not exist."
[docs] def copy(self, dst: Union[file, directory, str]) -> str: """Copies file to some source destination. Usage example: >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... new_file: str = file.copy("file2.txt") ... >>> new_file "/abs/path/to/file2.txt" >>> >>> # or >>> >>> file = File("file_name.txt") >>> file.copy("file2.txt") "/abs/path/to/file2.txt" Args: dst: Destination file path. relative: Symbolically link the file using a relative path. Returns: String that corresponds to the copied file. """ return super().copy(dst)
[docs] def touch(self) -> None: """Creates an empty file. This class method is analagous to UNIX's ``touch`` command. Usage example: >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... file.touch() ... >>> # or >>> >>> file = File("file_name.txt") >>> file.touch() """ if os.path.exists(self.src): print(f"The file: {self.src} already exists.") else: with open(self.src, "w") as _: pass return None
[docs] def rm_ext(self, ext: str = "") -> str: """Removes file extension from the file. Usage example: >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... file.touch() ... print(file.rm_ext()) ... "file_name" >>> >>> # or >>> >>> file = File("file_name.txt") >>> file.rm_ext() "file_name" Args: ext: File extension. Returns: Filename as string with no extension. """ if ext: ext_len: int = len(ext) return self.src[:-(ext_len)] elif self.ext: ext_len = len(self.ext) return self.src[:-(ext_len)] else: return self.src
[docs] def write(self, txt: str = "") -> None: """Writes/appends text to file. NOTE: Text written to file is ALWAYS ``utf-8`` encoded. Usage example: >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... file.write("<Text to be written>") ... >>> # or >>> >>> file = File("file_name.txt") >>> file.write("<Text to be written>") Args: txt: Text/string to be written to file. """ with open(self.src, mode="a", encoding="utf-8") as file: file.write(txt) file.close() return None
[docs] def file_parts(self, ext: str = "") -> Tuple[directory, file, str]: """Similar to MATLAB's ``fileparts``, this function splits a file and its path into its constituent parts: * file path * filename * extension Usage example: >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... print(file.file_parts()) ... ("path/to/file", "filename", ".txt") >>> >>> # or >>> >>> file = File("file_name.txt") >>> file.file_parts() ("path/to/file", "filename", ".txt") Args: ext: File extension, needed if the file extension of file object is longer than 4 characters. Returns: * Absolute file path, excluding filename. * Filename, excluding extension. * File extension. """ file: str = self.src file: str = os.path.abspath(file) path, _filename = os.path.split(file) if ext: ext_num: int = len(ext) _filename: str = _filename[:-(ext_num)] [filename, _] = os.path.splitext(_filename) elif self.ext: ext: str = self.ext ext_num: int = len(ext) _filename: str = _filename[:-(ext_num)] [filename, _] = os.path.splitext(_filename) else: [filename, ext] = os.path.splitext(_filename) return path, filename, ext
[docs] def remove(self) -> None: """Removes file. Usage example: >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... file.remove() ... >>> >>> # or >>> >>> file = File("file_name.txt") >>> file.remove() """ return os.remove(self.abspath())
[docs] def read(self, remove_newline: bool = False) -> List[str]: """Reads input file text. Usage example: >>> from typing import Lines >>> >>> # Using class object as context manager >>> with File("file_name.txt") as file: ... lines: List[str] = file.read(remove_newline=True) ... >>> lines ['These are the file contents','new lines are separate elements'] >>> >>> # or >>> >>> file = File("file_name.txt") >>> lines: List[str] = file.read(remove_newline=True) >>> lines ['These are the file contents','new lines are separate elements'] Args: remove_newline: Strip newline characters. Defaults to False. Returns: List of strings, with each element corresponding to a newline in the file. """ with open(self.abspath()) as f: text_lines: List[str] = f.readlines() if remove_newline: text_lines: List[str] = [x.strip("\n") for x in text_lines] return text_lines