Can not import X

1

I have two files within a project of which one has the import of the other and vice versa, in this case the main_server.py has the from Servidor.skeletons.Threads import Thread to be able to create an instance of the class Threads and in Threads.py has the import from Servidor.skeletons.main_server import Server , to get through the server to modify the self._server = server attribute. However, probably because of the redundancy of imports, I can not seem to run the main giving the following error:

  

File   "C: \ Users \ rosin \ Desktop \ SD_PROJ \ ByR \ Server \ skeletons \ Threads.py",   line 5, in

     

from Server.skeletons.main_server import Server

     

ImportError: can not import name 'Server' from   'Server.skeletons.main_server'

As I see no other way the classes can access each other, I found myself going around and around without ever fixing the error. Below are the files in question.

main_server.py

import socket

from Servidor.dta_server.main_server import MainServer

from Servidor.sockets.sockets import Socket

from Servidor.skeletons.Threads import Thread

class Server(Socket):

    def __init__(self, port: int, server: MainServer) -> None:

        """
        Creates a client given the dta_server dta_server to use
        :param port: The math dta_server port of the host the client will use
        """

        super().__init__()
        self._port = port
        self._server = server

    def add(self,a,z):
        self._server.addPlayer(a,z)

    def run(self) -> None:
        current_socket = socket.socket()
        current_socket.bind(('', self._port))
        current_socket.listen(1)
        print("Waiting for clients to connect on port", self._port)
        keep_running = True
        while keep_running:
            self.current_connection, address = current_socket.accept()
            last_request = False
            thread = Thread(self)  # worker()                         **import needed here**      
            print("Client", address, "just connected")
            thread.start()
        current_socket.close()
        print("Server stopped")

Threads.py

import queue

import threading

import Servidor.dta_server

from Servidor.skeletons.main_server import Server

from Servidor.sockets.sockets import Socket



class Thread(threading.Thread, Server):

        def __init__(self, socket: Socket) -> None:
        super().__init__()
        self.socket = socket
        self.work_queue = queue.Queue()
        self.daemon = True
        self.name = ""
        self.avatar = ""




    def addPlayer(self):
        lenght = self.socket.receive_player_size(1)
        lenght = int(lenght)
        #print("Recebido tamanho do jogador",lenght)
        a = self.socket.receive_player(lenght)
        self.name = a
        z = self.socket.receive_avatar()
        self.avatar = z

        #Recebido da forma nome.avatar então é feito o split para adicionar na clase jogador
        result =  self.add(a,z)        **import need to access add method on main_server.py**

        #print("result",result)


    def worker(self)->None:
        print("Worker",self.work_queue)
        while True:
            comando = self.work_queue.get()
            if comando == Servidor.dta_server.ADD_OP:
                self.addPlayer()

            elif comando == Servidor.dta_server.MOVE_OP:
                self.movePlayer()

            self.work_queue.task_done()



    def run(self) -> (bool, bool):
        request_type = self.socket.receive_command(9)
        keep_running = True
        last_request = False
        print("Chegou aqui")
        print(request_type)
        if request_type == Servidor.dta_server.ADD_OP:
            self.work_queue.put(request_type)
            print("queue",self.work_queue)
            #self.work_queue.join()
            self.worker()

        elif request_type == Servidor.dta_server.MOVE_OP:
            self.work_queue.put(request_type)
            #self.work_queue.join()
            self.worker()

        elif request_type == Servidor.dta_server.STOP_SERVER_OP:
            last_request = True
            keep_running = False

        self.work_queue.join()
        return keep_running, last_request

I have already checked the imports several times but they are correct the error occurs after the compilation.

    
asked by anonymous 25.12.2017 / 22:39

1 answer

0

That's right - it's a classic case of "circular imports". Python tries to do the most intuitive thing possible with imports, but it has its limits.

tl; dr: Your main_server module only needs the name Thread when the class is instantiated and running, not when the class is declared. Simply move the respective import line:

from Servidor.skeletons.Threads import Thread

to the end of the file, after the definition of your class. If I really need this import there, why did not I find any use of Thread in that file. If so, simply remove this line.

    
27.12.2017 / 13:41