Link to home
Start Free TrialLog in
Avatar of Chad Taddeo
Chad Taddeo

asked on

Python Error

I am trying to run an ansible playbook that is using and I believe failing with this file - https://github.com/HPENetworking/ansible-hpe-cw7/blob/master/library/comware_vlan.py

This is the error I am getting - An exception occurred during task execution. To see the full traceback, use -vvv. The error was: NameError: name 'd' is not defined

I think this may have to do with me having python3 and this being python2 code. I say that because I just got passed another issue that had to do with that. The other tech that helped with that did provide me with a python 2to3 converter after assisting with solve my other issue which I did use on this comware_vlan.py .  Still getting this error though about 'd' not being defined

Avatar of Chad Taddeo
Chad Taddeo

ASKER

it may be worth mentioning to get by the other error previously mentioned we changed one of the entries to - dict((k, v) for k, v in d.items() - instead of having iteritems that python3 no longer supports. And when I run 2to3 to convert to python 3 code, I see this in the output

     args = dict(vlanid=vlanid, name=name, descr=descr)
-    proposed = dict((k, v) for k, v in d.items() if v is not None)
+    proposed = dict((k, v) for k, v in list(d.items()) if v is not None)


Avatar of Norie
Is d the name of your dictionary?
Did you changed only the .iteritems() to .items()? Or did you replace also somedictionary by d unintentionally? My guess is that it was args before you changed it to d.
pepr, did I misunderstand the instruction in the other ticket which was requested I do - Use the for k, v in d.items(): -- no import is necessary. The new .items() works exactly like the older .iteritems().

Prior to instruction the file had.....
proposed = dict((k, v) for k, v in args.iteritems() if v is not None)

What it is now.....proposed = dict((k, v) for k, v in d.items() if v is not None)

ALSO, I see iteritems in the following as well.  Do I change that too??

   if state == 'present':                                                                                                      delta = dict(set(proposed.iteritems()).difference(
            existing.iteritems()))



The part before the dot is the name of the variable (here args) -- here the dictionary object. The part after the dot is the name of the the method (the function inside the object). If the object is of dictionary type, it defines some methods that belong the the type. So, to change Python 2 code, you have to replace only the second part -- the .iteritems() by .items(). The original code uses more dictionaries named like args, proposed, existing -- the names must be preserved.

In other words, the Python 2 dictionary wraps inside the method named .iteritems(). The Python 3 dictionary does not know the .iteritems() method -- because of that if fails when the old code is executed. However, the method was just renamed to .items() -- so you have to rename it also in the code.

Note: I am writing .items() with the dot in front of the name only to emphasize that is is a method name. The dot is not part of the method name. It just separates the object identifier and the method name.
yes you misinterpreted it was merely instructing you to use items()  wherever your found iteritems(), in the documentation in this context whenever you see a d.something something.d()  , D is referin to your dictionary name, not a literal "D"

  • iteritems python 2->3
before:
proposed = dict((k, v) for k, v in args.iteritems() if v is not None)
after: (this is what you must use)
proposed = dict((k, v) for k, v in args.items() if v is not None)

in the later case yes you should also change those iteritems for items

Note: there are some cases when merely replacing iteritems() with items() does not work, as it was not only renamed but also changed its functionality a bit, in those cases you should use iter(d.items())but for both your cases it should work.


  • items python 2->3
list(dict.items()) is required for what was dict.items() in Python 2.x
items() is required for what was iteritems in Python 2.x (there are some exceptions)
This is the error I get now - 'dict' object has no attribute 'iteritems'

This is the code now   - proposed = dict((k, v) for k, v in args.items() if v is not None)

Also below I now have just items instead of iteritems. Even if I didnt modify the below it still fails with the same thing

   if state == 'present':
        delta = dict(set(proposed.items()).difference(
            existing.items()))

Does the code seem correct now? If so, what do you think of the new error?

Adding a little more info from the very large error output that may give more of a clue. ....  - for k, v in key_map.iteritems():\nAttributeError: 'dict' object has no attribute 'iteritems'\n", "module_stdout": "", "msg":

I was wondering if something else is being called that has iteritems in another file as well. This though has me thinking it's specifically referring to the change we did.
ASKER CERTIFIED SOLUTION
Avatar of Arana (G.P.)
Arana (G.P.)

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
That was it Arana!  This time I think that problem is definitely fixed. I do have a separate issue now that I have to start figuring out.  Definitely looks like a different issue. Hopefully I dont need you guys again, haha.  
should you have used 2to3 on this file it would have suggested exactly the same thing.
oh......I did use it actually and thought it automatically converted other stuff on its own.   Didnt realize it gave suggestions. Sorry, I am not a programmer...lol.  Just trying to learn how to implement automation to the network. Thank you though!! 
it depends on the command line options

2to3 file.py -w    will write changes,  if run without the -w switch it just shows them on screen.
Great to know. You guys are awesome!!