RE: "metaclass conflict" error: where is noconflict ?

Discussion in 'Python' started by Barak, Ron, Feb 22, 2009.

  1. Barak, Ron

    Barak, Ron Guest

    Hi Chris,

    > -----Original Message-----
    > From: Chris Rebert [mailto:]
    > Sent: Sunday, February 22, 2009 11:48
    > To: Barak, Ron
    > Cc: ;
    > Subject: Re: "metaclass conflict" error: where is noconflict ?
    >
    > On Sun, Feb 22, 2009 at 1:37 AM, Barak, Ron <> wrote:
    > > Hi Chris,
    > >
    > >> -----Original Message-----
    > >> From: [

    > > mailto:] On
    > >> Behalf Of Chris Rebert
    > >> Sent: Thursday, February 19, 2009 22:58
    > >> To: Barak, Ron
    > >> Cc: ;
    > >> Subject: Re: "metaclass conflict" error: where is noconflict ?
    > >>
    > >> On Thu, Feb 19, 2009 at 5:01 AM, Barak, Ron

    > <> wrote:
    > >> > Hi,
    > >> >
    > >> > I have a class derived from two parents (in blue below),
    > >> which gives
    > >> > me the following error:
    > >> >
    > >> > $ python -u ./failover_pickle_demo09.py Traceback (most

    > recent call
    > >> > last):
    > >> > File "./failover_pickle_demo09.py", line 291, in <module>
    > >> > class ListControl(wx.Frame, CopyAndPaste):
    > >> > TypeError: Error when calling the metaclass bases
    > >> > metaclass conflict: the metaclass of a derived class

    > must be a
    > >> > (non-strict) subclass of the metaclasses of all its

    > bases Googling
    > >> > suggested I should add from noconflict import classmaker and
    > >> >
    > >> > __metaclass__=classmaker()
    > >> > to this class.
    > >> >
    > >> > However, I don't seem able to find where to get the
    > >> noconflict module from.
    > >> >
    > >> > Do any of you where noconflict could be

    > downloaded/installed from ?
    > >>
    > >> From what I could google, you should in theory be able to fix the
    > >> problem (without using any 3rd party module) by doing:
    > >>
    > >> class ListControlMeta(type(wx.Frame), type(CopyAndPaste)):
    > >> pass
    > >>
    > >> class ListControl(wx.Frame, CopyAndPaste):
    > >> __metaclass__ = ListControlMeta
    > >> #rest of class...
    > >>
    > >> Cheers,
    > >> Chris

    > >
    > > Applying your suggestion:
    > >
    > > class ListControlMeta(type(wx.Frame), type(CopyAndPaste)):
    > > pass
    > >
    > > class ListControl(wx.Frame, CopyAndPaste):
    > > def __init__(self, parent, id, title, list, max_list_width,
    > > log_stream,
    > > style=wx.DEFAULT_FRAME_STYLE):
    > >
    > > __metaclass__= ListControlMeta
    > >
    > >
    > > wx.Frame.__init__(self,parent,id,title,size=(max_list_width,-1),
    > > style=style)
    > > self.list = list
    > > self.log_stream = log_stream
    > > self.list_ctrl = wx.ListCtrl(self, -1, style=wx.LC_REPORT |
    > > wx.LC_NO_HEADER)
    > > self.list_ctrl.InsertColumn(0, title)
    > > for i,line_ in enumerate(list):
    > > self.list_ctrl.InsertStringItem(i, line_)
    > > ...
    > >
    > > I get:
    > >
    > > $ python -u ./failover_pickle_demo09.py Traceback (most recent call
    > > last):
    > > File "./failover_pickle_demo09.py", line 319, in <module>
    > > class ListControlMeta(type(wx.Frame), type(CopyAndPaste)):
    > > TypeError: Error when calling the metaclass bases
    > > multiple bases have instance lay-out conflict

    >
    > >From what I recall, that basically means that type(wx.Frame) and

    > type(CopyAndPaste) are both C classes that are are mutually
    > incompatible. It's basically the same reason you can't
    > subclass from both `list` and `dict` or two other built-in
    > types (you get the exact same error).
    >
    > Sounds like the only way to workaround this would be to do
    > some coding in C or to use composition rather than
    > inheritance for one of ListControl's superclasses.


    The wx.Frame may be coded in C, but the CopyAndPaste class, which I wrote, is not (see it's listing below).
    Could you have a look at the CopyAndPaste class, and see if something in its construction strikes you as susspicious ?

    Thanks,
    Ron.

    $ cat ./CopyAndPaste.py
    #!/usr/bin/env python

    import wx

    class CopyAndPaste():
    def __init__(self):
    pass

    def set_copy_and_paste(self):
    """
    Setting clipboard copy-and-pasting (only copying from the application to the
    clipboard is supported).
    The "menu" menu is hidded, and is only there to facilitate the acceleration table.
    Both CTRL-C and CTRL-Ins are supported.
    """
    #print line()+". set_copy_and_paste started"
    #print line()+". self.__dict__:",self.__dict__
    menu = wx.Menu()
    copy_ = menu.Append(-1, "&Copy\tCtrl-Ins") # Copy with accelerator
    minimize_ = menu.Append(-1, "Minimize") #
    close_ = menu.Append(-1, "Close window\tCtrl-W") # Close window
    exit_ = menu.Append(-1, "E&xit application\tCtrl-X") # Close window
    """
    #copy2_ = menu.Append(-1, "&Copy\tCtrl-C") # Copy with accelerator
    paste_ = menu.Append(-1, "&Paste\tShift-Ins") # Paste with accelerator
    paste2_ = menu.Append(-1, "&Paste\tCtrl-V") # Paste with accelerator
    """

    self.Bind(wx.EVT_MENU, self.on_copy, copy_)
    self.Bind(wx.EVT_MENU, self.on_minimize, minimize_)
    self.Bind(wx.EVT_MENU, self.on_close, close_)
    self.Bind(wx.EVT_MENU, self.on_exit, exit_)
    #self.Bind(wx.EVT_MENU, self.on_paste, paste_)

    menuBar = wx.MenuBar()
    self.SetMenuBar(menuBar)

    acceltbl = wx.AcceleratorTable( [
    (wx.ACCEL_CTRL, ord('C'), copy_.GetId()),
    (wx.ACCEL_CTRL, ord('W'), close_.GetId()),
    (wx.ACCEL_CTRL, ord('X'), exit_.GetId()),
    (wx.ACCEL_CTRL, ord('Q'), exit_.GetId()),
    (wx.ACCEL_CTRL, wx.WXK_INSERT, copy_.GetId()),
    (wx.ACCEL_CTRL, wx.WXK_NUMPAD_INSERT, copy_.GetId()),
    #(wx.ACCEL_CTRL, ord('V'), paste_.GetId()),
    #(wx.ACCEL_SHIFT, wx.WXK_INSERT, paste_.GetId()),
    ])
    self.SetAcceleratorTable(acceltbl)

    # Setting popup menu

    self.popupmenu = menu
    self.Bind(wx.EVT_CONTEXT_MENU, self.on_show_popup)

    """
    def on_paste(self, evt):
    wx.MessageBox("You selected 'paste'")
    """


    def on_show_popup(self, evt):
    pos = evt.GetPosition()
    pos = self.list_ctrl.ScreenToClient(pos)
    self.PopupMenu(self.popupmenu, pos)

    def get_data_for_clipboard(self,format="text"):
    """
    Return data ready to be copied to the clipboard.

    This is an abstract method - concrete subclasses must override this..

    Sample implementation of get_data_for_clipboard() is:

    def get_data_for_clipboard(self,format="text"):
    first_selected = self.list_ctrl.GetFirstSelected()
    selected_item_count = self.list_ctrl.GetSelectedItemCount()
    text_for_clipboard = ""
    for i in range(first_selected,first_selected+selected_item_count):
    text_for_clipboard = "%s%s\n" % (text_for_clipboard, self..list_ctrl.GetItemText(i))
    return(text_for_clipboard)
    """
    raise NotImplementedError

    def on_copy(self, evt):
    """
    """
    text_for_clipboard = self.get_data_for_clipboard()

    data = wx.TextDataObject()
    data.SetText(text_for_clipboard)
    if wx.TheClipboard.Open():
    wx.TheClipboard.SetData(data)
    wx.TheClipboard.Close()
    else:
    wx.MessageBox("Unable to copy to the clipboard", "Error")

    def on_minimize(self, evt):
    self.Iconize()
    #self.parent.Iconize()

    def on_close(self, evt):
    self.Close()
    #self.parent.Close()

    def on_exit(self, evt):
    try:
    self.Parent.Close()
    except AttributeError:
    self.Close()


    if __name__ == "__main__":

    app = wx.App(redirect=False)
    copy_and_paste = CopyAndPaste()
    app.MainLoop()

    >
    > Cheers,
    > Chris
    >
    > --
    > Follow the path of the Iguana...
    > http://rebertia.com
    >
    >
     
    Barak, Ron, Feb 22, 2009
    #1
    1. Advertising

  2. "Barak, Ron" <> writes:

    > class CopyAndPaste():


    CopyAndPaste is an old-style class. Make it a new-style class, and
    you'll probably be able to inherit from it and wx.Frame without
    explicitly creating a new metaclass.
     
    Hrvoje Niksic, Feb 22, 2009
    #2
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. hfk0
    Replies:
    2
    Views:
    21,708
  2. JavaQueries
    Replies:
    1
    Views:
    3,716
    John C. Bollinger
    Mar 1, 2005
  3. Balaji
    Replies:
    3
    Views:
    10,142
  4. Chris Rebert
    Replies:
    2
    Views:
    1,497
    Michele Simionato
    Feb 23, 2009
  5. Barak, Ron
    Replies:
    0
    Views:
    300
    Barak, Ron
    Feb 23, 2009
Loading...

Share This Page