Cannot import X

Asked

Viewed 742 times

2

I have two files inside a project of which one has the import of the other and vice versa, in this case the main_server.py has the import from Servidor.skeletons.Threads import Thread to be able to create an instance of the Threads class and Threads.py has the import from Servidor.skeletons.main_server import Server, to be able to modify the attribute via the server self._server = server. However, probably due to the redundancy of Imports, I cannot 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

Import: cannot import name 'Server' from 'Server.skeletons.main_server'

As I see no other way for the classes to access each other, I found myself in turns and turns without ever fixing the mistake. 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")

Py threads.

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 checked the Imports several times but they are correct the error occurs after the compilation.

1 answer

1

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 module main_server just 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 its class. If you really need that import there, why haven’t I found any use of Thread in that file. If so, simply remove that line.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.