class_docstr: Represents a set of CPA rules
docstr: Parse a rules file
  
  fd_or_file - either a filename or a file descriptor. Parse assumes
               that fd_or_file is a file name if it's a string or
               unicode, otherwise it assumes that it's a file descriptor.
docstr_tok: ["Parse","a","rules","file","fd_or_file","-","either","a","filename","or","a","file","descriptor",".","Parse","assumes","that","fd_or_file","is","a","file","name","if","it","'s","a","string","or","unicode",",","otherwise","it","assumes","that","it","'s","a","file","descriptor","."]
code: def parse(self, fd_or_file):
      """Parse a rules file
  
      fd_or_file - either a filename or a file descriptor. Parse assumes
                   that fd_or_file is a file name if it's a string or
                   unicode, otherwise it assumes that it's a file descriptor.
      """
      line_pattern = (
          "^IF\\s+\\((?P<object_name>[^_]+)"
          "_(?P<feature>\\S+)"
          "\\s*(?P<comparitor>[><]=?)"
          "\\s*(?P<threshold>[^,]+)"
          ",\\s*\\[\\s*(?P<true>[^\\]]+)\\s*\\]"
          ",\\s*\\[\\s*(?P<false>[^\\]]+)\\s*\\]\\s*\\)$"
      )
      if isinstance(fd_or_file, str):
          fd = open(fd_or_file, "r")
          needs_close = True
      else:
          fd = fd_or_file
          needs_close = False
      try:
          for line in fd:
              line = line.strip()
              match = re.match(line_pattern, line)
              if match is not None:
                  d = match.groupdict()
                  weights = numpy.array(
                      [
                          [float(w.strip()) for w in d[key].split(",")]
                          for key in ("true", "false")
                      ]
                  )
                  rule = self.Rule(
                      d["object_name"],
                      d["feature"],
                      d["comparitor"],
                      float(d["threshold"]),
                      weights,
                      self.allow_fuzzy,
                      self.fuzzy_value,
                  )
                  self.rules.append(rule)
          if len(self.rules) == 0:
              raise ValueError("No rules found in %s" % str(fd_or_file))
      finally:
          if needs_close:
              fd.close()
  
file_path: CellProfiler/src/frontend/cellprofiler/utilities/rules.py
imports: from difflib import SequenceMatcher
  from rapidfuzz import process
  import re
  from cellprofiler_core.module import Module
  from cellprofiler_core.setting import Binary
  import numpy
label_desc: Use image node_id 4 for calling the Rules obj's underlying member method code with example usage: obj.parse(fd_or_file) without return types