title: Maximum Recursion Depth Exceeded py2App
body: <p>I've searched google pretty thoroughly, but can't find an answer to this. When I try to build with py2app I get this error: 
    Would it possibly be caused by using a module such as 'gspread' in the code? Or because I'm using wxpython? The troubling thing is that 'python setup.py py2app -A' runs without issue.</p>
  
  <pre><code>running py2app
  creating /Users/Bailejor/Desktop/build/bdist.macosx-10.5-x86_64/python2.7-standalone/app
  creating /Users/Bailejor/Desktop/build/bdist.macosx-10.5-x86_64/python2.7-standalone/app/collect
  creating /Users/Bailejor/Desktop/build/bdist.macosx-10.5-x86_64/python2.7-standalone/app/temp
  creating build/bdist.macosx-10.5-x86_64/python2.7-standalone/app/lib-dynload
  creating build/bdist.macosx-10.5-x86_64/python2.7-standalone/app/Frameworks
  *** using recipe: virtualenv ***
  *** using recipe: ftplib ***
  *** using recipe: lxml ***
  *** using recipe: PIL ***
  *** using recipe: xml ***
  *** using recipe: sip ***
  *** using recipe: matplotlib ***
  *** using recipe: pydoc ***
  *** using recipe: docutils ***
  *** using recipe: scipy ***
  Traceback (most recent call last):
    File "setup.py", line 18, in &lt;module&gt;
      setup_requires=['py2app'],
    File "//anaconda/lib/python2.7/distutils/core.py", line 151, in setup
      dist.run_commands()
    File "//anaconda/lib/python2.7/distutils/dist.py", line 953, in run_commands
      self.run_command(cmd)
    File "//anaconda/lib/python2.7/distutils/dist.py", line 972, in run_command
      cmd_obj.run()
    File "//anaconda/lib/python2.7/site-packages/py2app-0.9-py2.7.egg/py2app/build_app.py", line 659, in run
      self._run()
    File "//anaconda/lib/python2.7/site-packages/py2app-0.9-py2.7.egg/py2app/build_app.py", line 865, in _run
      self.run_normal()
    File "//anaconda/lib/python2.7/site-packages/py2app-0.9-py2.7.egg/py2app/build_app.py", line 943, in run_normal
      self.process_recipes(mf, filters, flatpackages, loader_files)
    File "//anaconda/lib/python2.7/site-packages/py2app-0.9-py2.7.egg/py2app/build_app.py", line 833, in process_recipes
      find_needed_modules(mf, packages=rval['packages'])
    File "//anaconda/lib/python2.7/site-packages/modulegraph/find_modules.py", line 289, in find_needed_modules
      m = mf.import_hook(package, None, ["*"])
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 927, in import_hook
      for s in self._ensure_fromlist(m, fromlist):
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 1053, in _ensure_fromlist
      submod = self._import_module(sub, fullname, m)
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 1260, in _scan_ast
      visitor.visit(co)
    File "//anaconda/lib/python2.7/ast.py", line 241, in visit
      return visitor(node)
    File "//anaconda/lib/python2.7/ast.py", line 249, in generic_visit
      self.visit(item)
    File "//anaconda/lib/python2.7/ast.py", line 241, in visit
      return visitor(node)
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 615, in visit_ImportFrom
      self._process_import(node.module or '', _ast_names(node.names), level)
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 1029, in _load_tail
      result = self._import_module(head, mname, result)
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 1105, in _import_module
      m = self._load_module(fqname, fp, pathname, stuff)
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 1178, in _load_module
      self._scan_code(co, m)
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 1251, in _scan_code
      self._scan_ast(co, m)
    File "//anaconda/lib/python2.7/site-packages/modulegraph/modulegraph.py", line 1260, in _scan_ast
      visitor.visit(co)
    File "//anaconda/lib/python2.7/ast.py", line 241, in visit
      return visitor(node)
    File "//anaconda/lib/python2.7/ast.py", line 249, in generic_visit
      self.visit(item)
    File "//anaconda/lib/python2.7/ast.py", line 241, in visit
      return visitor(node)
    File "//anaconda/lib/python2.7/ast.py", line 251, in generic_visit
      self.visit(value)
    File "//anaconda/lib/python2.7/ast.py", line 241, in visit
      return visitor(node)
    File "//anaconda/lib/python2.7/ast.py", line 245, in generic_visit
      for field, value in iter_fields(node):
  RuntimeError: maximum recursion depth exceeded
  </code></pre>
  
  <p>Here is my code as suggested (Thanks for the suggestion): </p>
  
  <pre><code>import wx
  import wx.grid as gridlib
  import numpy as np
  import pandas as pd
  import csv
  import matplotlib.pyplot as plt
  import os
  import itertools
  from itertools import chain
  import getpass
  import gspread
  from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas
  from matplotlib.figure import Figure
  import sys
  
  ####################################################################################################
  class TopPanel(wx.Panel):
      """"""
      #Top PANEL
      #----------------------------------------------------------------------
      def __init__(self, parent):
          """Constructor"""
          wx.Panel.__init__(self, parent=parent)
  
          grid = gridlib.Grid(self)
          grid.CreateGrid(25,12)
          grid.SetColLabelValue(0, "Index")
          self.buttonPlus = wx.Button(self, wx.NewId(), "+", size=(50, 28))
          sizer = wx.BoxSizer(wx.VERTICAL)
          sizer.Add(grid, 0, wx.EXPAND)
          self.SetSizer(sizer)
  
  
  ########################################################################################################
  class BottomPanel(wx.Panel):
      """"""
      #Bottom PANEL
      #----------------------------------------------------------------------
      def __init__(self, parent):
          """Constructor"""
          wx.Panel.__init__(self, parent=parent)
          #Sizers------------------------------------------------------------
          self.sizer = wx.BoxSizer(wx.HORIZONTAL)
          self.sizer2=wx.BoxSizer(wx.VERTICAL)
          self.sizer3=wx.BoxSizer(wx.VERTICAL)
          self.sizer4=wx.BoxSizer(wx.VERTICAL)
          #-----------------------------------------------------------------
          self.figure = Figure(figsize=(1,2))
          self.axe = self.figure.add_subplot(111)
          self.figurecanvas = FigureCanvas(self, -1, self.figure)
          self.barseries = wx.TextCtrl(self, size=(140, -1))
          self.lblname = wx.StaticText(self, label="Enter Series to Bar:")
          self.buttonUpdate = wx.Button(self, label="Update Figure")
          self.buttonPlot = wx.Button(self, wx.NewId(), "Plot", size=(60,28))
          self.buttonClear = wx.Button(self, wx.NewId(), "Clear", size=(60,28))
          self.buttonSave=wx.Button(self, wx.NewId(), "Save", size=(60, 28))
          self.buttonNext=wx.Button(self, wx.NewId(), "Next", size=(60, 28))
          self.buttonPrev=wx.Button(self, wx.NewId(), "Last", size=(60, 28))
          self.buttonGplot=wx.Button(self, wx.NewId(), "Gplot", size=(60, 28))
          sampleList = ['Yes', 'No']
          self.rb = wx.RadioBox(self, wx.ID_ANY, "Secondary Vertical Axis", wx.DefaultPosition, wx.DefaultSize, sampleList, 2, wx.RA_SPECIFY_COLS)
          #Button Binders------------------------------------------------------
          self.buttonSave.Bind(wx.EVT_BUTTON, self.saveFig)
          self.buttonPlot.Bind(wx.EVT_BUTTON, self.plotFig)
          self.buttonClear.Bind(wx.EVT_BUTTON, self.clearFig)
          self.buttonGplot.Bind(wx.EVT_BUTTON, self.googlefunc)
          self.buttonNext.Bind(wx.EVT_BUTTON, self.nextButtonFunc)
          self.buttonPrev.Bind(wx.EVT_BUTTON, self.prevButtonFunc)
          #--------------------------------------------------------------------
          #Add to Sizers-------------------------------------------------------
          self.sizer.Add(self.figurecanvas, proportion=2, border=1, flag=wx.ALL | wx.EXPAND)
          self.sizer2.Add(self.rb, proportion=0, border=2, flag=wx.ALL)
          self.sizer2.Add(self.lblname, proportion=0, border=2, flag=wx.ALL)
          self.sizer2.Add(self.barseries, proportion=0, border=2, flag=wx.ALL)
          self.sizer2.Add(self.buttonUpdate, proportion=0, border=2, flag=wx.ALL)
  
          self.sizer3.Add(self.buttonGplot, proportion=0, border=2, flag=wx.ALL)
          self.sizer3.Add(self.buttonPrev, proportion=0, border=2, flag=wx.ALL)
          self.sizer3.Add(self.buttonPlot, proportion=0, border=2, flag=wx.ALL)
          self.sizer4.Add(self.buttonSave, proportion=0, border=2, flag=wx.ALL)
          self.sizer4.Add(self.buttonNext, proportion=0, border=2, flag=wx.ALL)
          self.sizer4.Add(self.buttonClear, proportion=0, border=2, flag=wx.ALL)
  
          self.sizer.Add(self.sizer2, 0, wx.TOP)
          self.sizer.Add(self.sizer3, 0)
          self.sizer.Add(self.sizer4, 0)
          self.SetSizer(self.sizer)
          self.sheetcounter=[]
  
  #Begin Google Sheets Function-------------------------------------------------------------
      def googlefunc(self, e):
          usernam = wx.TextEntryDialog(None, "Enter Novel Responses Username")
          if usernam.ShowModal()==wx.ID_OK:
              usernm=usernam.GetValue()
              usernam.Destroy()
          else:
              usernam.Destroy()
          convert=usernm + "@gmail.com"
  
          dlg1 = wx.PasswordEntryDialog(parent=None,message="Please enter your password")
          if dlg1.ShowModal()==wx.ID_OK:
              pw=dlg1.GetValue()
              dlg1.Destroy
  
          gc = gspread.login(convert, pw)
          dlg2 = wx.TextEntryDialog(None, "Which client would you like to view progress of?")
          if dlg2.ShowModal()==wx.ID_OK:
              self.client=dlg2.GetValue()
              dlg2.Destroy()
  
          wks = gc.open(self.client)
  
          for i, worksheet in enumerate(wks.worksheets()):
              filename = self.client + '-worksheet' + str(i) + '.csv'
              with open(filename, 'wb') as f:
                  writer = csv.writer(f)
                  writer.writerows(worksheet.get_all_values())
              self.sheetcount = i + 1
          print "There are "+str(self.sheetcount)+" client goals that have been charted."
          self.gplot(jor=0, currentsheet=0)
  
      def gplot(self, jor, currentsheet):
          lst = ["Bar Series", "Multiple Vertical Axes"]
          if  jor &lt; (self.sheetcount):
              df = pd.read_csv((self.client+'-worksheet'+str(currentsheet)+'.csv'), index_col=0, header=0, sep=',')
              phasechange = df['Phase Change'].dropna()
              phaselabel=df['Phase Label'].values
              phaselabel1=phaselabel
              print phaselabel1
              get_title=str(df['Title'].iloc[0])
              get_y=str(df['Y-Axis Title'].iloc[0])
              get_x=df.index.name
              df=df.dropna(axis=1)
              markers=itertools.cycle(('o', 's', 'D', 's', 'h', '8'))
              markercolor=itertools.cycle(('k', 'w'))
              max_value=(df.values.max()) * 1.5
              print max_value
              fig=plt.figure(1)
              ax=self.axe
              ax.spines['top'].set_visible(False)
              ax.spines['right'].set_visible(False)
              ax.yaxis.set_ticks_position('left')
              ax.xaxis.set_ticks_position('bottom')
              ax.set_ylabel(get_y)
              ax.axes.set_ylim([0, max_value])
              fig.set_tight_layout(True)
              for col in (df):
                  df[col].plot(x=get_x, grid=False, marker=markers.next(), markerfacecolor=markercolor.next(), title=get_title, color='k', ax=ax)
                  for phase in phasechange:
                      ax.axvline(x=phase, ymin=0, ymax=1.0, linewidth=12, color='w')
                      ax.axvline(x=phase, ymin=0, ymax=1.0, linewidth=1, color='k')
              phasechange = phasechange + 1
              self.figurecanvas.draw()
  
  
  
  
          #dlg3 = wx.MultiChoiceDialog( self, "Choose Specific Options for your plot", "Plot Options", lst)
          #if (dlg3.ShowModal() == wx.ID_OK):
              #selections = dlg3.GetSelections()
              #strings = [lst[x] for x in selections]
              #if "Bar Series" and "Multiple Vertical Axes" in strings:
                  #print "You selected Bar series and multi vert axis"
                  #dlg4 = wx.TextEntryDialog(None, "Which series would you like to bar?")
                  #if dlg4.ShowModal()==wx.ID_OK:
                      #get_bar=dlg2.GetValue()
                      #dlg4.Destroy()
                  #use Recursion here call gplot again"
                  #dlg3.Destroy()
              #elif "Bar Series" in strings:
              #print "You selected Bar Series"
          #else:
              #dlg3.Destroy()
  
          return (jor, currentsheet)
  
                  #self.deletecsv(sheetcount, currentsheet, client)
  
      #def deletecsv(self, sheetcount, currentsheet, client):
      #currentsheet=0
      #for _ in xrange(sheetcount):
      #os.remove(client+'-worksheet'+str(currentsheet)+'.csv')
      #currentsheet=currentsheet + 1
  #--END Gplot Function-------------------------------------------------------------------------
  
  
  #--Next Button Function-----------------------------------------------------------------------
      def nextButtonFunc(self, event):
          if len(self.sheetcounter) &lt; (self.sheetcount):
              self.sheetcounter.append('l')
              i2=len(self.sheetcounter)
              jor, currentsheet = self.gplot(jor=i2, currentsheet=i2)
              self.axe.clear()
              print jor, currentsheet
              self.gplot(jor, currentsheet)
  
  #--Prev Button Function-----------------------------------------------------------------------
      def prevButtonFunc(self, event):
          if 0&lt; len(self.sheetcounter) &lt;= (self.sheetcount):
              del self.sheetcounter[-1]
              i2=len(self.sheetcounter)
              jor, currentsheet = self.gplot(jor=i2, currentsheet=i2)
              self.axe.clear()
              print jor, currentsheet
              self.gplot(jor, currentsheet)
  #--Save Figure Function--------------------------------------------------------------------
      def saveFig(self, event):
          filename=wx.TextEntryDialog(None, "Please enter a name to save figure", "Save")
          if filename.ShowModal()==wx.ID_OK:
              filename=filename.GetValue()
              self.figure.savefig(filename+".png")
  #--Plot Figure Function--------------------------------------------------------------------
      def plotFig(self, event):
  
          self.axe.plot(range(10), color='green')
          self.figurecanvas.draw()
  #--Clear Figure Function------------------------------------------------------------------
      def clearFig(self, event):
          del self.sheetcounter[:]
          self.figure.set_canvas(self.figurecanvas)
          self.axe.clear()
          self.figurecanvas.draw()
          self.SetSize((self.Size[0],self.figurecanvas.Size[1]))
          currentsheet=0
          for _ in xrange(self.sheetcount):
              os.remove(self.client+'-worksheet'+str(currentsheet)+'.csv')
              currentsheet=currentsheet +1
  #########################################################################################################
  class MyForm(wx.Frame):
      #MAIN FRAME
      #-------------------------------------------------------------------------------------
      def __init__(self):
          wx.Frame.__init__(self, None, title="SSD-Single Subject Designs", size=(1100, 650))
  
          splitter = wx.SplitterWindow(self)
          topP = TopPanel(splitter)
          bottomP = BottomPanel(splitter)
  #----Start Menubar-----------------------------------------------------------------------
          menubar=wx.MenuBar()
          first=wx.Menu()
          second=wx.Menu()
          third=wx.Menu()
          fourth=wx.Menu()
  
          first.Append(wx.NewId(),"New Window", "This is a new window")
          first.Append(wx.NewId(),"Open...", "This will open a new window")
          first.Append(wx.NewId(), "Save Dataframe", "")
          first.Append(wx.NewId(), "Save As", "")
          first.AppendSeparator()
          quitter=first.Append(wx.NewId(),"Exit", "This will close the program")
  
          second.Append(wx.NewId(), "Cut", "This will cut the selection")
          second.Append(wx.NewId(), "Copy", "This will copy the selection")
          second.Append(wx.NewId(), "Paste", "This will paste the selection")
  
          mbl=wx.Menu()
          mbl.Append(wx.ID_ANY, "Two Baselines")
          mbl.Append(wx.ID_ANY, "Three Baselines")
          mbl.Append(wx.ID_ANY, "Four Baselines")
          mbl.Append(wx.ID_ANY, "Five Baselines")
          mbl.Append(wx.ID_ANY, "Six Baselines")
  
          third.Append(wx.NewId(), "Analyze IOA", "Analyze Interobserver Agreement Data")
  
          third.Append(wx.NewId(), "AB.. Design", "A simple baseline, intervention design with x phases.")
          third.AppendMenu(wx.ID_ANY, "Multiple Baseline Design", mbl)
          third.Append(wx.NewId(), "Changing Criterion Design", "A design with several subphases within the treatment phase.")
          third.Append(wx.NewId(), "Multiple-Treatment Design", "A design with 2 or more treatments in an intervention phase.")
          googler=fourth.Append(wx.NewId(), "Import from Google Sheets", "Import a data set from Google")
          fourth.Append(wx.NewId(), "Import from Excel", "Import a data set from Microsoft Excel")
          menubar.Append(first, "File")
          menubar.Append(second, "Edit")
          menubar.Append(third, "Analyze")
          menubar.Append(fourth, "Import")
          self.SetMenuBar(menubar)
  
          self.Bind(wx.EVT_MENU, self.Quit, quitter)
          #self.Bind(wx.EVT_MENU, self.googlefunc, googler)
  #--ENDMENUBAR-----------------------------------------------------------------------------
          # split the window
          splitter.SplitHorizontally(topP, bottomP)
          splitter.SetMinimumPaneSize(200)
  
          sizer = wx.BoxSizer(wx.VERTICAL)
          sizer.Add(splitter, 1, wx.EXPAND)
          self.SetSizer(sizer)
  #--QUIT FUNCTION-------------------------------------------------------------------------
      def Quit(self, e):
          yesNoBox=wx.MessageDialog(None, "Are you sure you want to quit?", "Exit?", wx.YES_NO)
          yesNoAnswer=yesNoBox.ShowModal()
          print yesNoAnswer
          if yesNoAnswer == 5103:
              self.Close()
              yesNoBox.Destroy()
          else:
              yesNoBox.Destroy()
  #End of Quit Function---------------------------------------------------------------------
  ########################################################################################################
  # Run the program
  if __name__ == "__main__":
      app = wx.App(False)
      frame = MyForm()
      frame.Show()
      app.MainLoop()
  </code></pre>