title: Python Multiprocessing - ApplyResult.get() NameError: global name 'self' is not defined
body: <p>I am currently trying to use the Python multiprocessing package to make a CPU-bound process run more quickly. I have a very large numpy matrix, and would like to split the work using Pool and apply_async to calculate the values that go in the matrix. However, when I run the unit test on the function to test whether it works, I get the error "NameError: global name 'self' is not defined". I couldn't find anything on Google or StackOverflow that helps, either. Any idea why this might be happening?</p>
  
  <p>Pytest output:</p>
  
  <pre><code>_____________________ TestBuildEMMatrix.test_build_em_matrix_simple _____________________
  
  self = &lt;mixemt_master.mixemt2.preprocess_test.TestBuildEMMatrix testMethod=test_build_em_matrix_simple&gt;
  
      def test_build_em_matrix_simple(self):
              reads = ["1:A,2:C", "1:T,2:C", "3:T,4:T", "2:A,4:T"]
              in_mat = preprocess.build_em_matrix(self.ref, self.phy,
  &gt;                                                                                   reads, self.haps, self.args)
  
  preprocess_test.py:272:
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  preprocess.py:239: in build_em_matrix
      results[i] = results[i].get()
  _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
  
  self = &lt;multiprocessing.pool.ApplyResult object at 0x7f4218ea07d0&gt;, timeout = None
  
      def get(self, timeout=None):
          self.wait(timeout)
          if not self._ready:
              raise TimeoutError
          if self._success:
              return self._value
          else:
  &gt;           raise self._value
  E           NameError: global name 'self' is not defined
  
  /vol/hpc/apps/python-anaconda2-4.3.1-abat/install/lib/python2.7/multiprocessing/pool.py:567: NameError
  --------------------------------- Captured stdout call ----------------------------------
  False
  </code></pre>
  
  <p>And the relevant Python functions:</p>
  
  <pre><code>def build_em_matrix_process(markers, haplogroups, pos_obs, mut_prob, column_length, start_index, end_index):
  
      columns = [[prob_for_vars(markers, haplogroups[j], pos_obs, mut_prob) for j in xrange(column_length)]
          for i in xrange(start_index, end_index)]
  
      return columns
  
  def build_em_matrix(refseq, phylo, reads, haplogroups, args):   
      """
      Returns the matrix that describes the probabiliy of each read
      originating in each haplotype.
      """
      hvb_mat = HapVarBaseMatrix(refseq, phylo)
      read_hap_mat = numpy.empty((len(reads), len(haplogroups)))
  
      if args.verbose:
          sys.stderr.write('Building EM input matrix...\n')
  
      num_processors = args.p
  
      pool = Pool(processes = num_processors);
      results = []
      partition_size = int(math.ceil(len(reads) / float(num_processors)))
  
      for i in xrange(num_processors):
          start_index = i * partition_size
          end_index = (i + 1) * partition_size
          pos_obs = pos_obs_from_sig(reads[i])
  
          results.append(pool.apply_async(build_em_matrix_process, (hvb_mat.markers, haplogroups, pos_obs, hvb_mat.mut_prob, len(haplogroups), start_index, end_index)))
  
      column = 0
      for i in xrange(num_processors):
          results[i].wait()
          print results[i].successful()
          results[i] = results[i].get()
          for j in xrange[len(results)]:
              read_hap_mat[column] = results[i][j]
              column += 1
  
      if args.verbose:
          sys.stderr.write('Done.\n\n')
  
      return read_hap_mat
  </code></pre>
  
  <p>After calling 'results[i].wait()] added a statement 'print results[I].successful()', which prints False to stdout. I'm not sure why that's not returning true, as I can't find any errors in build_em_matrix_process.</p>