Python3 - tkinter importing and using module
Question: I am having trouble importing and using a module I have created. I have
patcher.py and I would like to import modules from patches.py but I get an
error when trying to import and use disable_removecd. I am now a little
confused on how to set it up properly and how to import and use it correctly.

patcher.py

    
    
    #import the tkinter module
    from tkinter import *
    from tkinter.filedialog import askopenfilename
    import bsdiff4
    from patches import *
    
    #bsdiff4.file_patch(dst, dst, patch)
    
    #create a new class
    class Application(Frame):
        def __init__(self, master):
            super(Application, self).__init__(master)
            self.grid(row = 2, sticky = W+E+N+S)
            #,padx=300
            cmexecutable = askopenfilename()
            print(cmexecutable)
            self.mainmenu()
    
        def mainmenu(self): 
    
            self.logo = PhotoImage(file='logo.gif')
            self.image = Label(self, image=self.logo)
            self.image.grid(columnspan = 2)
            self.image.configure(background='black')
    
            #self.bttn1 = Button(self, text = 'Country Specific')
            self.bttn1 = Button(self, text = 'Disable Remove CD Message')
            self.bttn1['command'] = disable_removecd(self)
            self.bttn1.grid(columnspan = 2 ,sticky = W+E+N+S) 
    

patches.py

    
    
    from patcher import *
    
    def disable_removecd():
    
        offset1 = 0x42a98b
        offset2 = 0x42a98c
        offset3 = 0x42a98d
        offset4 = 0x42a98e
        offset5 = 0x42a98f
        offset6 = 0x42e400
        offset7 = 0x42e401
        offset8 = 0x42e402
        offset9 = 0x42e403
        offset10 = 0x42e404
    
        newvalue1 = b'\x90'
        newvalue2 = b'\x90'
        newvalue3 = b'\x90'
        newvalue4 = b'\x90'
        newvalue5 = b'\x90'
        newvalue6 = b'\x90'
        newvalue7 = b'\x90'
        newvalue8 = b'\x90'
        newvalue9 = b'\x90'
        newvalue10 = b'\x90'
    
        with open(cmexecutable, 'r+b') as victim:
            victim.seek(offset1)
            victim.write(newvalue1)
            victim.seek(offset2)
            victim.write(newvalue2)
            victim.seek(offset3)
            victim.write(newvalue3)
            victim.seek(offset4)
            victim.write(newvalue4)
            victim.seek(offset5)
            victim.write(newvalue5)
            victim.seek(offset6)
            victim.write(newvalue6)
            victim.seek(offset7)
            victim.write(newvalue7)
            victim.seek(offset8)
            victim.write(newvalue8)
            victim.seek(offset9)
            victim.write(newvalue9)
            victim.seek(offset10)
            victim.write(newvalue10)
    

When I run patcher.py I get this error:

    
    
    self.bttn1['command'] = disable_removecd(self)
    NameError: name 'disable_removecd' is not defined
    

What am I doing wrong?


Answer: The following line in `patches.py` causes a cyclic import.

    
    
    from patcher import *
    

I think you used that line to use `cmexecutable` in the `disable_removecd`
function. Remove the above line. And pass the value of `cmexecutable`
explicitly.

_patcher.py_ :

    
    
    ...
    
    class Application(Frame):
    
        def __init__(self, master):
            super(Application, self).__init__(master)
            self.grid(row=2, sticky=W+E+N+S)
            cmexecutable = askopenfilename()
            self.mainmenu(cmexecutable)
    
        def mainmenu(self, cmexecutable): 
            self.logo = PhotoImage(file='logo.gif')
            self.image = Label(self, image=self.logo)
            self.image.grid(columnspan=2)
            self.image.configure(background='black')
    
            self.bttn1 = Button(self, text = 'Disable Remove CD Message')
            self.bttn1['command'] = lambda: disable_removecd(cmexecutable)
            # ^^ set up callback instead of calling it immediately using `lambda`.
            self.bttn1.grid(columnspan=2 ,sticky=W+E+N+S)
    

* * *

The function `disable_removecd` in `patches.py` should be modified to accept
`cmexecutable` as a parameter:

    
    
    def disable_removecd(cmexecutable):
        ....
    

