'ToastNotifier' object has no attribute 'classAtom' - python

I ran the code below;
from win10toast import ToastNotifier
toaster = ToastNotifier()
toaster.show_toast("Hello World!!!",
"Python is 10 seconds awsm!",
icon_path="custom.ico",
duration=10)
I am getting below error :
File "C:\Users\jnp\AppData\Local\Continuum\anaconda3\lib\site-packages\win10toast\__init__.py", line 83, in _show_toast
self.hwnd = CreateWindow(self.classAtom, "Taskbar", style,
AttributeError: 'ToastNotifier' object has no attribute 'classAtom'

What was causing this for me was creating multiple instances of ToastNotifier(). Reusing the same instance fixed the error.

As mentioned by #InAFlash, The classAtom is returning nothing and the reason is because there is already a registered notification. Messing with the source, I added an exception print to the except block as below:
try:
self.classAtom = RegisterClass(self.wc)
except Exception as e:
print(e)
I am running my notifications in threads and when the code comes across this point it prints out the below error:
(1410, 'RegisterClass', 'Class already exists.')
Looking through it I think I found a solution, though it kind of takes away from the idea of "spamming" the notifications. By adding to the self.wc.lpszClassName variable the title, it makes it a different notification. So overall the code should look something like this:
self.wc = WNDCLASS()
self.hinst = self.wc.hInstance = GetModuleHandle(None)
self.wc.lpszClassName = str(f"PythonTaskbar{title}") # must be a string
self.wc.lpfnWndProc = message_map # could also specify a wndproc.
try:
self.classAtom = RegisterClass(self.wc)
except Exception as e:
print(e)
This solution worked for my scenario so not sure if this is the best fix but I'm rolling with it.
Hope this helps.

Looks like the problem is with the source code itself.
if you see the image, if there is an exception happening at self.classAtom = RegisterClass(self.wc) they did not handle it which will leave classAtom variable not declared. That is the cause of your problem. So, to fix it, just make classAtom = "" or some thing. But, this wont actually fix it.

Considering the accepted answer might break more things down the line, I'll post this.
It is, as inAFlash mentioned in his comment, a dependency issue. Updating setuptools will fix the problem.
To do so, simply run: python -m pip install setuptools --upgrade

Related

Try/Except not working with BeautifulSoup

I am trying to loop over a series of pages and extract some info. However, in certain pages some exceptions occur and I need to deal with them. I created the following function to try to deal with them. See below:
def iferr(x):
try:
x
except (Exception, TypeError, AttributeError) as e:
pass
I intend to use as part of code like this:
articles = [[iferr(dp[0].find('span', class_='citation')),\
iferr(dp[0].find('div', class_='abstract')),\
iferr(dp[0].find('a', rel='nofollow')['href'])] for dp in data]
The idea is that if, for example, dp[0].find('a', rel='nofollow')['href'] leads to an error (fails), it will simply ignore it (fill it with a blank or a None).
However, whenever an error/exception occurs in one of the three elements it does not 'pass'. It just tells me that the error has occurred. There errors it displays are those I listed in the 'except' command which I assume would be dealt with.
EDIT:
Per Michael's suggestion, I was able to see that the order in which iferr processes what is going on would always prompt the error before he try. So I worked on workaround:
def fndwoerr(d,x,y,z,h):
try:
if not h:
d.find('x',y = 'z')
else:
d.find('x',y = 'z')['h']
except (Exception, TypeError, AttributeError) as e:
pass
...
articles = [[fndwoerr(dp[0],'span','class_','citation',None),\
fndwoerr(dp[0],'div','class_','abstract',None),\
fndwoerr(dp[0], 'a', 'rel','nofollow','href')] for dp in data]
Now it runs without prompting an error. However, everything returned becomes None. I am pretty sure it has to do with he way the parameters are entered. y should not be displayed as a string in the find function, whereas z has. However, I input both as string when i call the function. How can I go about this?
Example looks a bit strange, so it would be a good idea to improve the question, so that we can reproduce your issue easily. May read how to create minimal, reproducible example
The idea is that if, for example, dp[0].find('a',
rel='nofollow')['href'] leads to an error (fails), it will simply
ignore it (fill it with a blank or a None).
What about checking if element is available with an if-statement?
dp[0].find('a', rel='nofollow').get('href']) if dp[0].find('a', rel='nofollow') else None
or with walrus operator from python 3.8:
l.get('href']) if (l:=dp[0].find('a', rel='nofollow')) else None
Example
from bs4 import BeautifulSoup
soup = BeautifulSoup('<h1>This is a Heading</h1>', 'html.parser')
for e in soup.select('h1'):
print(e.find('a').get('href') if e.find('a') else None)

Python / Spyder - Undefined variable error, when variable is defined and shown in the environment. Code works even with the error

I am getting a strange error when defining variables in Python 4.1.5 (IDE:Spyder). However, even with the error, the code runs without any issues!
As you can see, the variable social_cost_of_carbon is stored as a variable, but I keep getting that error as show in picture 1 (the error writes: Undefined name 'social_cost_of_carbon' (Pyflakes E)
I feel that the way that i declare those variables might be the reason:
def convert_to_var(df):
desc = []
val = []
for i,row in df.iterrows():
desc.append(i)
val.append(row)
return dict(val)
val_dict = convert_to_var(IA)
locals().update(val_dict)
Since the code runs without any problems, I am not doing anything to resolve this. Do I need to worry and fix this, or do I just let it be and continue without dealing with the error since the code runs smoothly?
Thanking you in advance.
(Spyder maintainer here) As you guessed, the problem is that you're creating your variable dynamically with this line in your code:
locals().update(val_dict)
Since our linter can't find where that variable is properly declared, it reports that it's undefined. But it's safe for you to ignore that message.
Note: For now it's not possible to hide linter warnings. However, in a future version we'll provide a way to do that by adding a comment at the end of a line of the form # noqa.

ReceivedTime of the mail is not showing in python

I am trying to read my mail and see the received time in outlook 2016 using MAPI.
I am able to see the subject of the mail not able to see the receivedTime of the mail. I know that "Receivedtime" is there to get the received time of the mail, but while the program is executed,
a popup is coming, telling that python has stopped working
I know it is not due to any machine problem rather some problem in my code.
Here is my code.
def arrange(mailbox):
global spam
timeperiod() # stores required date in spam[] list
msgs=mailbox.Items
msgs.Sort("[ReceivedTime]", True)
p=msgs.restrict(" [ReceivedTime] >= '"+spam[2]+"'") #and [ReceivedTime] >= '" +spam[1]+"'
print(len(p))
'''
for m in list1:
if m.Unread:
m.Unread=False
'''
return p
#Calling it
ctm1=arrange(ctm)
print(len(ctm1)) #Working fine
for message in ctm1:
print (message.subject) #Also works good
print (message.receivedTime) # Here is the problem, it's not showing
]1
i have tried Senton property as well, but it's not working . So any guesses why the senton or receivedTime properties are not working???
updated code :
def printlist(box1) :
print(len(box1))
for message in box1:
if message.Class==43 :
# print('true')
print (message)
#.senderEmailAddress) #working
#print(message.SentOn.strftime("%d-%m-%y")) #not working
#print(message.body)
#print(message.UnRead)
#print (message.receivedTime) #not working
#print('-----------')
I was also having trouble with the .ReceivedTime breaking the program when I compile the .py script to an .exe using auto-py-to-exe.
Here's where the error occurs underneath this try: statement
try:
received_year = str(email.ReceivedTime)[0:4]
received_month = str(email.ReceivedTime)[5:7]
received_day = str(email.ReceivedTime)[8:10]
This works PERFECTLY well inside of my IDE (PyCharm), but once I've compiled it to .exe, it breaks here.
I've updated pywin32 to the most up-to-date version (228) and also tried using 224 to see if it was a version issue (it wasn't).
BUT!! Going through this, I FOUND THE BUG! When you compile to .exe with auto-py-to-exe, it does not include the package "win32timezone" which the .ReceivedTime portion needs to run correctly. So you need to import this package for it to work.
All you have to do to fix this is include this at the top of your .py script before compiling to .exe:
import win32timezone
Let me know if this works for anyone else facing this issue!
Most likely you run into an item other than MailItem - you can also have ReportItem and MeetingItem objects in your Inbox; none of them expose the ReceivedTime property.
Check that message.Class property == 43 (olMail) before accessing any other MailItem specific properties.
Please try the below:
print([x.ReceivedTime for x in messages])

how to change the yapsy plugin default file format?

I want to change the default file format extension of the yapsy plugin that looks like name.yapsy-plugin to simply name.info
I have even found the documentation here http://yapsy.sourceforge.net/PluginFileLocator.html But I am confused how to really implement it.
For now I am just working with the default file format and working well. I just want to make a change in extension. Can anyone make me understand the documentation and thus in the future I can tackle such problems.
try:
simplePluginManager = PluginManager()
simplePluginManager.setPluginPlaces(["plugins/"])
simplePluginManager.collectPlugins()
pluginlist = {}
for plugininfo in simplePluginManager.getAllPlugins():
print "Running the plugin--", plugininfo.name
# running the plugins
pluginlist[plugininfo.name] = plugininfo.plugin_object.run(
cons.PLUGIN_CONFIG_PATH, outputpath, finallogs, plugininfo.name)
except Exception as error:
print "Plugin Configuration Error", error
traceback.print_exc(error)
you need to change
simplePluginManager = PluginManager()
to
simplePluginManager = PluginManager(plugin_info_ext="info")

Registering an Object on DBus using pythons Gio-Bindings

I'm working on a Python-Clone of an existing C-Project. The C-Project Connects to a custom DBus and offers a Object there for getting Callbacks.
I tried to replicate this using Python with code that basically boils down to:
def vtable_method_call_cb(connection, sender, object_path, interface_name, method_name, parameters, invocation, user_data):
print('vtable_method_call_cb: %s' % method_name)
connection = Gio.DBusConnection.new_for_address_sync(
"unix:abstract=gstswitch",
Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT,
None,
None)
node_info = Gio.DBusNodeInfo.new_for_xml(introspection_xml)
vtable = Gio.DBusInterfaceVTable()
vtable.method_call(vtable_method_call_cb)
vtable.get_property(None)
vtable.set_property(None)
connection.register_object(
"/info/duzy/gst/switch/SwitchUI",
node_info.interfaces[0],
vtable,
None,
None)
The code fails when creating the vtable at the vtable.method_call call (but get_property fails, too, when I comment one call out) the following log/traceback:
** (process:18062): WARNING **: Field method_call: Interface type 2 should have is_pointer set
Traceback (most recent call last):
File "moo.py", line 69, in <module>
vtable.method_call(vtable_method_call_cb)
RuntimeError: unable to get the value
I was not able to find code using register_object() in python, so I'm unsure if this part of Gio should be usable or if it's just not complete.
This certainly not what you'll want to hear, but you have hit a 4 year old bug in the GDBus Python bindings that makes it impossible to register objects on the bus. A patch had been proposed quite some time ago, but every time it looked like it was actually going to land, some GNOME developer found something he/she did not like something about it, a new patch was proposed... and nothing happend for most of the next year. This cycle has already happend 3 times and I do not know if there is much hope that it will be broken anytime soon...
Basically the GNOME developers themselves more or less suggested that people use dbus-python until this issue is finally fixed, so I guess you should be heading here instead. :-/
BTW: I think you source code is wrong (aside from the fact that it won't work either way). To create the VTable you would actually be written something like this, I think:
vtable = Gio.DBusInterfaceVTable()
vtable.method_call = vtable_method_call_cb
vtable.get_property = None
vtable.set_property = None
But since the bindings are broken you are just trading an exception with an abort() here... :-(
If the patch actually makes it into python-gi in the current form the vtable would be dumped entirely (YEAH!) and connection.register_object call would become:
connection.register_object_with_closures(
"/info/duzy/gst/switch/SwitchUI",
node_info.interfaces[0],
vtable_method_call_cb, # vtable.method_call
None, # vtable.get_property
None) # vtable.set_property
Update
It appears this has now finally been fixed! You can now export object using g_dbus_connection_register_object_with_closures:
def vtable_method_call_cb(connection, sender, object_path, interface_name, method_name, parameters, invocation, user_data):
print('vtable_method_call_cb: %s' % method_name)
connection = Gio.DBusConnection.new_for_address_sync(
"unix:abstract=gstswitch",
Gio.DBusConnectionFlags.AUTHENTICATION_CLIENT,
None,
None)
node_info = Gio.DBusNodeInfo.new_for_xml(introspection_xml)
connection.register_object(
"/info/duzy/gst/switch/SwitchUI",
node_info.interfaces[0],
vtable_method_call_cb,
None,
None)

Categories