text: """Utilities for file handling."""
  import os
  from itertools import repeat, takewhile
  from typing import Sequence
  
  import pandas as pd
  
  
  def count_file_lines(filepath: str, buffer_size: int = 1024 * 1024) -> int:
      """
      Count lines in a file without persisting it in memory.
  
      Args:
          filepath (str): path to the file.
          buffer_size (int): size of the buffer.
  
      Returns:
          int: Number of lines in the file.
      """
      number_of_lines = 0
      new_line = os.linesep.encode()
      with open(filepath, 'rb') as fp:
          raw_fp = fp.raw
          previous_buffer = None
          for buffer in takewhile(
              lambda x: x, (raw_fp.read(buffer_size) for _ in repeat(None))
          ):
              number_of_lines += buffer.count(new_line)
              previous_buffer = buffer
          number_of_lines += int(not previous_buffer.endswith(new_line))
      return number_of_lines
  
  
  def read_smi(
      filepath: str,
      chunk_size: int = None,
      index_col: int = 1,
      names: Sequence[str] = ['SMILES'],
      header: int = None,
      *args,
      **kwargs,
  ) -> pd.DataFrame:
      """
      Read a .smi (or .csv file with tab-separated values) in a pd.DataFrame.
  
      Args:
          filepath (str): path to a .smi file.
          chunk_size (int): size of the chunk. Defaults to None, a.k.a. no
              chunking.
          index_col (int): Data column used for indexing, defaults to 1.
          names (Sequence[str]): User-assigned names given to the columns.
          header (int): Row number to use as column names. Defaults to None.
          args (): Optional arguments for `pd.read_csv`.
          kwargs (): Optional keyword arguments for `pd.read_csv`.
  
      Returns:
          pd.DataFrame: a pd.DataFrame containing the data of the .smi file
              where the index is the index_col column.
      """
      try:
          return pd.read_csv(
              filepath,
              sep='\t',
              header=header,
              index_col=index_col,
              names=names,
              chunksize=chunk_size,
              *args,
              **kwargs,
          )
      except IndexError:
          raise IndexError(
              'Pandas does not understand the .smi file. The most common '
              'reason is a wrong delimiter (has to be \\t)'
          )
  