self.errorLog(): str object is not callable

Posted on
Fri May 15, 2020 4:32 pm
howartp offline
Posts: 4559
Joined: Jan 09, 2014
Location: West Yorkshire, UK

self.errorLog(): str object is not callable

Is there a coding/parsing difference between debugLog() and errorLog() behind the scenes?

I have several lines of code which (purely whilst fixing and testing a complex bit of code) i've interchangeably and unintentionally switched between debugLog() and errorLog().

Code: Select all
self.debugLog("Validating slots {}".format(slotID))         #Line 118
self.debugLog("Validating slotx {}".format(type(slotID)))   #Line 119
self.errorLog("Validating slotz {}".format(slotID))         #Line 120

self.debugLog(type(slotID))                                 #Line 122

self.debugLog("self.tSlot {} = type(slotID) of type {}".format(self.tSlot[slotID],type(self.tSlot[slotID])))   #Line 124
self.errorLog("Slot {} is occupied by device ".format(self.tSlot[slotID]))                                     #Line 125
When I execute this part of the routine I get:
Code: Select all
2020-05-15 23:19:07.474   EnergyLink Debug   Validating slot 6                 #Line 106
2020-05-15 23:19:17.449   EnergyLink Debug   Validating slot 2                 #Line 106
2020-05-15 23:19:17.453   EnergyLink Debug   Validating slots 2                #Line 118
2020-05-15 23:19:17.453   EnergyLink Debug   Validating slotx <type 'int'>     #Line 119

2020-05-15 23:19:17.454   EnergyLink Error   Error in plugin execution UiValidate:

Traceback (most recent call last):
  File "plugin.py", line 120, in validateDeviceConfigUi
TypeError: 'str' object is not callable
#Line no's added for readability, they're not in the code

I've been going round and round with working out why slotID was causing such errors, then I realised it's actually errorLog() that doesn't like it - debugLog() is fine with it.

Any thoughts?

Posted on
Fri May 15, 2020 5:04 pm
matt (support) offline
Site Admin
User avatar
Posts: 21417
Joined: Jan 27, 2003
Location: Texas

Re: self.errorLog(): str object is not callable

Off the top of my head I cannot think of why debugLog would work bug errorLog doesn't.

Try adding a u before the begin quote on each log line so the string is unicode. Example for line 120:

Code: Select all
self.errorLog(u"Validating slotz {}".format(slotID))         #Line 120

Does that prevent the error?

Image

Posted on
Fri May 15, 2020 9:40 pm
jay (support) offline
Site Admin
User avatar
Posts: 18220
Joined: Mar 19, 2008
Location: Austin, Texas

Re: self.errorLog(): str object is not callable

I wonder if the actual error is somewhere else in the code, because here are the debugLog and errorLog function definitions:

Code: Select all
   def debugLog(self, msg):
      if not hasattr(self, 'logger'):
         return
      self.logger.debug(msg)

   def errorLog(self, msg):
      if not hasattr(self, 'logger'):
         return
      self.logger.error(msg)


Basically, they are just wrappers around the standard python logger methods. The only thing that occurs to me is that there is a handler attached to the logger that's only set to log errors and the handler is the one throwing the exception since it's not getting called for debug messages.

Try creating the string using the format() method first, then passing it to self.errorLog(). I've seen circumstances where trying to do it in the same method call has introduced odd errors. And the formatters that we create automatically do string formatting as well, so I suppose it's possible that the nested substitutions are causing a problem.

Jay (Indigo Support)
Twitter | Facebook | LinkedIn

Posted on
Sat May 16, 2020 3:15 am
howartp offline
Posts: 4559
Joined: Jan 09, 2014
Location: West Yorkshire, UK

Re: self.errorLog(): str object is not callable

Damn, damn, damn, damn, damn!

:oops:

I've spent half an hour recording a screencast of Indigo showing you the exact situation that causes it and getting the accompanying logs together so you see what's going on.

Then I've found my stupid mistake.

Code: Select all
   def validateDeviceConfigUi(self, valuesDict, typeId, devId):
      errorsDict = indigo.Dict()
      slotID = self.zint(valuesDict["address"])
      self.debugLog("Validating slot {}".format(slotID))
      if slotID == 0:
         if self.tSlot[0] == 6:
            slotID = 6
            valuesDict['address'] = 6
      if 1 <= slotID <= 5:
         if self.tSlot[slotID] == None:
            pass #Empty so ok
         elif self.tSlot[slotID] == devId:
            pass #Itself so ok
         else:
            errString = u"Validating slots {}".format(slotID)
            self.debugLog("Validating slots {}".format(slotID))
            self.debugLog("Validating slotx {}".format(type(slotID)))
            self.errorLog(errString)

            self.debugLog("118")

            self.debugLog(type(slotID))

            self.debugLog("120")

            self.debugLog("self.tSlot {} = type(slotID) of type {}".format(self.tSlot[slotID],type(self.tSlot[slotID])))
            self.errorLog("Slot {} is occupied by device ".format(self.tSlot[slotID]))
            errorsDict['address'] = "Slot {} is occupied by device {}".format(slotID,self.tSlot[slotID])
            errorsDict['showAlertText'] = "Each tariff in this plugin is assigned a slot 1-5.\r\n\r\nSlot {} is already occupied by device {}".format(slotID,self.tSlot[slotID])
      elif slotID == 0:
         self.errorLog = "Please select a tariff slot"
         errorsDict['address'] = "This plugin supports 5 tariffs."
         errorsDict['showAlertText'] = "Each tariff in this plugin is assigned a slot 1-5.\r\n\r\Please select a tariff slot to continue."
      elif slotID == 6:
         self.errorLog = "This plugin only supports 5 tariffs."
         errorsDict['address'] = "This plugin only supports 5 tariffs."
         errorsDict['showAlertText'] = "This plugin only supports 5 tariffs.\r\n\r\nPlease disable or delete a tariff device to continue."
      if len(errorsDict) > 0:
         return (False, valuesDict, errorsDict)
      else:
         return True

See how long it takes you to spot whilst I go and dig a hole to hide in. :cry:

Peter

Posted on
Sat May 16, 2020 11:10 am
matt (support) offline
Site Admin
User avatar
Posts: 21417
Joined: Jan 27, 2003
Location: Texas

Re: self.errorLog(): str object is not callable

Code: Select all
self.errorLog("this works")
self.errorLog = "foo"
self.errorLog("this no longer works")

:shock:

Happens to all of us. Python can be dangerous at times. :)

Image

Posted on
Sat May 16, 2020 11:33 am
howartp offline
Posts: 4559
Joined: Jan 09, 2014
Location: West Yorkshire, UK

Re: self.errorLog(): str object is not callable

:cry: :cry: :cry:

Page 1 of 1

Who is online

Users browsing this forum: No registered users and 9 guests