docs: def readData(self, fileName):
          """
          Interprets the specified file as an AMPL data file. As a side effect,
          it invalidates all entities (as the passed file can contain any
          arbitrary command); the lists of entities will be re-populated lazily
          (at first access). After reading the file, the interpreter is put back
          to "model" mode.
  
          Args:
              fileName: Full path to the file.
  
          Raises:
              RuntimeError: in case the file does not exist.
          """
          lock_and_call(
              lambda: self._impl.readData(fileName),
              self._lock
          )
          self._errorhandler_wrapper.check()