'thread._local' object has no attribute

DoNNie_DarkO picture DoNNie_DarkO · Dec 17, 2013 · Viewed 21.7k times · Source

I was trying to change the logging format by adding a context filter. My Format is like this

FORMAT = "%(asctime)s %(VAL)s %(message)s"

This is the class I use to set the VAL in the format.

class TEST:
  def __init__(self, val):
    self.test_var=threading.local()
    self.test_var.value=val
  def filter(self,record):
    record.VAL=self.test_var.value
    return True
  def setValue(self,val)
    self.test_var.value=CMDID

It works fine in a single threaded environment, but for a certain multi-threaded environment I get the error

<Fault 1: "exceptions.AttributeError:'thread._local' object has no attribute 'value'">

Can anyone tell me what's wrong here ?? and how to rectify?

Answer

twalberg picture twalberg · Dec 17, 2013

Well, the exception is telling you that the thread._local object returned from threading.local() doesn't have a value attribute that you can assign val to. You can confirm that by adding a dir(self.test_var) after the self.test_var=threading.local() line. That returns this for me:

['__class__', '__delattr__', '__dict__', '__doc__', '__getattribute__', '__hash__',
 '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__',
 '__str__']

Indeed, help(threading.local()) will show you the methods and attributes that do exist - value is not among them.

If you are attempting to add a new attribute, then perhaps you want:

self.test_var.__setattr__('value',val)

This will actually create the attribute and assign the value to it.

Instance attributes are not generally created simply by assigning to them, like non-instance variables are...