Click here to Skip to main content
14,870,687 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
Hello forum,

there's a background thread in my python program that reads from a virtual serial port. Bytes start to trickle in. Whenever a byte sequence looks like a meaningful message to the parser, that message shall be stuffed into a FIFO. And here's the problem:
Python
class Dongle:
    # This one is for all the dongles
    NewMessageEvt = signal("NewMessageEvt")

    def __init__(self, commPort:Serial):
        self._commPort = commPort
        self._inputMessageQueue = Queue
        self._commThread = threading.Thread(daemon=True, target=self._ObserveComm)
        self._commThread.start()

    def _ObserveComm(self):
        while(True):
            oneByte = bytearray(self._commPort.read(1))
            if(len(oneByte) > 0):
                oneMessage = Message.Parse(oneByte)
                if(issubclass(type(oneMessage), Message)):
# We have a properly parsed message now.
#   Store it in a FIFO and fire an event so
#   main thread can come and deal with the message.
                    self._inputMessageQueue.put(self._inputMessageQueue, item=oneMessage)
                    Dongle.NewMessageEvt.send(self._inputMessageQueue)


But the call to Queue.put() throws an exception
Exception has occurred: AttributeError
type object 'Queue' has no attribute 'not_full'
  File "D:\sw\dev\Python38\Lib\queue.py", line 132, in put
    with self.not_full:
  File "$projectPath$\dongle.py", line 27, in _ObserveComm
    self._inputMessageQueue.put(self._inputMessageQueue, item=oneMessage)
  File "D:\sw\dev\Python38\Lib\threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "D:\sw\dev\Python38\Lib\threading.py", line 932, in _bootstrap_inner
    self.run()
  File "D:\sw\dev\Python38\Lib\threading.py", line 890, in _bootstrap
    self._bootstrap_inner()


And I don't understand how Queue can not have an attribute not_full since the exception points right at the source code for the Queue class:
Python
class Queue:
        # Notify not_full whenever an item is removed from the queue;
        # a thread waiting to put is notified then.
        self.not_full = threading.Condition(self.mutex)

    def put(self, item, block=True, timeout=None):
        '''Put an item into the queue.

        If optional args 'block' is true and 'timeout' is None (the default),
        block if necessary until a free slot is available. If 'timeout' is
        a non-negative number, it blocks at most 'timeout' seconds and raises
        the Full exception if no free slot was available within that time.
        Otherwise ('block' is false), put an item on the queue if a free slot
        is immediately available, else raise the Full exception ('timeout'
        is ignored in that case).
        '''
        with self.not_full:
            if self.maxsize > 0:
                if not block:
                    if self._qsize() >= self.maxsize:
                        raise Full
                elif timeout is None:
                    while self._qsize() >= self.maxsize:
                        self.not_full.wait()
                elif timeout < 0:
                    raise ValueError("'timeout' must be a non-negative number")
                else:
                    endtime = time() + timeout
                    while self._qsize() >= self.maxsize:
                        remaining = endtime - time()
                        if remaining <= 0.0:
                            raise Full
                        self.not_full.wait(remaining)
            self._put(item)
            self.unfinished_tasks += 1
            self.not_empty.notify()


What can possibly go wrong here?

What I have tried:

Coded, ran in debugger, read error message and looked at code pointed to by that error message.
Posted
Updated 27-Mar-21 4:56am
Comments
Richard MacCutchan 16-Feb-21 11:05am
   
I think that initialisation line should be inside the __init__ method of the class.
lukeer 16-Feb-21 11:26am
   
Which one do you mean?
If it's the signal constructor, that does work quite well.

No, the other one. The call to the Queue() constructor lacks parentheses.

Wooohoo! I can push a button in the real world to make the program stop at a breakpoint! Yesss!

Thank you so much.

1 solution

Queue was never initialized.

Change:
self._inputMessageQueue = Queue

To:
self._inputMessageQueue = Queue()
   
Comments
lukeer 16-Apr-21 8:32am
   
Thank you. You pinned it.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900