I am encountering a small hiccup in the installer I am creating in python. I have a function which returns the value of a key based on it's location.
def CheckRegistryKey(registryConnection, location, softwareName, keyName):
'''
Check the windows registry and return the key value based on location and keyname
'''
try:
if registryConnection == "machine":
aReg = ConnectRegistry(None,HKEY_LOCAL_MACHINE)
elif registryConnection == "user":
aReg = ConnectRegistry(None,HKEY_CURRENT_USER)
aKey = OpenKey(aReg, location)
except Exception, ex:
print ex
return False
try:
aSubKey=OpenKey(aKey,softwareName)
val=QueryValueEx(aSubKey, keyName)
return val
except EnvironmentError:
pass
I get an error if the location does not exist. I want the function to return False so if the location does not exist so I can run the software installer, bit it always lands up in the exception
# check if the machine has .VC++ 2010 Redistributables and install it if needed
try:
hasRegistryKey = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))
if hasRegistryKey != False:
keyCheck = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))[0]
if keyCheck == 1:
print 'vc++ 2010 redist installed'
else:
print 'installing VC++ 2010 Redistributables'
os.system(productsExecutables + 'vcredist_x86.exe /q /norestart')
print 'VC++ 2010 Redistributables installed'
except Exception, ex:
print ex
The exception I get when I run the code is
'NoneType' object has no attribute '___getitem___'
and the error I get from the def CheckRegistryKey function is
[Error 2] The system cannot find the file specified
What I need to do is check if the registry key or location exists, if not direct it to an executable. Any help is appreciated.
Thank you
The reason for the error:
'NoneType' object has no attribute '___getitem___'
Is in the line:
keyCheck = (edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed"))[0]
The fragment edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed") is returning None.
This means you end up with:
keyCheck = (None)[0]
This is what is throwing your error. You are trying to get an item on a object that is None.
The reason that this you are getting None back from your CheckRegistryKey function is that if an error occurs you aren't returning anything. You need to return False when you catch a EnvironmentError:
try:
aSubKey=OpenKey(aKey,softwareName)
val=QueryValueEx(aSubKey, keyName)
return val
except EnvironmentError:
return False
I would also modify your code so that you are only calling CheckRegistryKey once:
registryKey = edit_registry.CheckRegistryKey("machine", r"SOFTWARE\Wow6432Node\Microsoft\VisualStudio\10.0\VC\VCRedist", "x86", "Installed")
if registryKey is not False:
keyCheck = registryKey[0]
Related
I have a Scenario where i want to check file exist at path or not
But if file not exist at path catch the error and log it to file using logging module and then script should break (exit). further code of lines should not be executed which is next function addtion_value if first function falls
Note : my script file contains lots of function one after the other in same file
Below is my code , i was able to code but with error
import path
import logging
logging.basicConfig(filename='log.txt',level=logging.INFO,format='%(asctime)',filemode='w')
def checkfileexist(Pth,Fle):
var=Path(Pth+'/'+Fle)
try :
if var.is_file():
logging.INFO('File found')
return (var)
exception Nofile as er:
logging.error('Not Found file')
else:
sys.exit()
def additionvalue(a,b):
return (a+b)
Is it possible to make use of import os module and create code ?
I have modified your script and it's working
import os
import logging
import sys
logging.basicConfig(filename='log.txt',level=logging.INFO,format='%(asctime)s- %(message)s',filemode='a')
def checkfileexist(Pth,Fle):
var=Pth+'/'+Fle
try :
if (var is None):
logging.error('Path is empty')
raise Exception("empty path")
if os.path.exists(var):
logging.error('File found')
return (var)
else:
raise Exception("File Not found")
except Exception as e:
logging.error('Not Found file')
sys.exit()
def additionvalue(a,b):
return (a+b)
you were not logging the message %(asctime)s- %(message)s as well as instead of 'w' you should use 'a' (append)
You can do it without raising any error:
def checkfileexist(Pth,Fle):
var = Path(Pth+'/'+Fle)
if var.is_file():
logging.info('File found')
return var
else:
logging.error('Not Found file')
But if you insist, you can do something like this:
def checkfileexist(Pth,Fle):
var = Path(Pth+'/'+Fle)
try:
if not var.is_file():
raise FileNotFoundError()
except FileNotFoundError as er:
logging.error('Not Found file')
else:
logging.info('File found')
return var
need to check both the parameter is passed to the function checkfilexist()
When you define a function with required parameters (as the function above), Python will already raise an error if you don't pass all its parameters:
checkfileexist()
# Raises TypeError: checkfileexist() missing 2 required positional arguments: 'Pth' and 'Fle'
checkfileexist('/c/d/',)
# Raises TypeError: checkfileexist() missing 1 required positional argument: 'Fle'
For the third case (raise an error if any argument is empty), you can do something like this:
def checkfileexist(Pth,Fle):
# Same as `if len(Pth) == 0:`
if not Pth:
raise TypeError("parameter Pth must not be empty")
# Same as `if len(Fle) == 0:`
if not Fle:
raise TypeError("parameter Fle must not be empty")
# ...
After all above answers and tried on my editor and prepared this below script
Correct me if any thing wrong in below code
Thanks for helping me with your approach: #lakshika-parihar #enzo & #Joaquim Procopio
But this worked for me
import os
import logging
import sys
logging.basicConfig(filename='C:\\Users\\admin\\Desktop\\JUL\\log.txt', level=logging.INFO,
format='%(asctime)s : %(message)s', filemode='w')
def checkfileexist(file_path, file_name):
try:
var_pth = str(file_path)
var_fle = str(file_name)
var_full = var_pth + var_fle
if var_pth is None or var_pth == '':
logging.error("Path parameter is empty")
raise TypeError('Path parameter is empty')
else:
pass
logging.info(f'Path : {var_pth}')
if var_fle is not None and var_fle != '':
pass
logging.info(f'Full : {var_fle}')
else:
logging.error("File parameter is empty")
raise TypeError('File parameter is empty')
if os.path.exists(var_full):
logging.error(f'File : {var_fle} is found at path : {var_pth} ')
logging.info(f'File : {var_full}')
return var_full
except:
logging.error(f"ERRO : {erron} ")
sys.exit()
try:
# Calling function
# checkfileexist('C:\\Users\\admin\\Desktop\\JUL\\', 'ABX')
# checkfileexist('', 'ABX') #Output : 2021-07-28 22:45:48,307 : Path parameter is empty
# checkfileexist('', '') #Output : 2021-07-28 22:46:53,758 : Path parameter is empty
checkfileexist() #2021-07-29 11:12:46,207 : ERROR : checkfileexist() missing 2 required positional arguments: 'file_path' and 'file_name'
except Exception as er:
logging.error(f"ERROR : {er} ")
sys.exit()
I want to be able to delete all the subkeys under a key but I keep getting the error
[WinError 2] The system cannot find the file specified
Here is the code I used from another answer (python: how to delete registry key (and subkeys) from HKLM (getting error 5)1) :
import winreg
def delete_sub_key(key0, current_key, arch_key=0):
open_key = winreg.OpenKey(key0, current_key, 0, winreg.KEY_ALL_ACCESS)
info_key = winreg.QueryInfoKey(open_key)
for x in range(0, info_key[0]):
# to delete the key and all sub_keys
sub_key = winreg.EnumKey(open_key, 0)
try:
winreg.DeleteKey(open_key, sub_key)
print("Removed %s\\%s " % (current_key, sub_key))
except OSError:
delete_sub_key(key0, "\\".join([current_key,sub_key]), arch_key)
# No extra delete here since each call
# to delete_sub_key will try to delete itself when its empty.
winreg.DeleteKey(open_key, "")
open_key.Close()
print("Removed %s" % current_key)
return
arch_keys = [winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY]
root = winreg.HKEY_LOCAL_MACHINE
# Key to delete
keys = 'Computer\\HKEY_LOCAL_MACHINE\\SOFTWARE\\BlueStacks'
for arch_key in arch_keys:
try:
delete_sub_key(root, keys, arch_key)
except OSError as e:
print(e)
I have this section in my code:
# I/O files
inp_arq = sys.argv[1]
out_arq = sys.argv[2]
pad_ref = "pad_ref03.fasta"
tes_mdl = "model_05_weights.best.hdf5"
and at the end:
try:
results_df.to_csv(out_arq,index = False)
print(f"File saved as: {out_arq}")
except IndexError:
print("No output file created")
If no file is passed in as out_arq (sys.argv[2]) it should run the script and print "No output file created" at the end. But I'm getting the "IndexError: list index out of range."
But if I comment out the "out_arq = sys.argv[2]" line and change the code to:
try:
results_df.to_csv(sys.argv[2],index = False)
print(f"File saved as: {sys.argv[2]}")
except IndexError:
print("No output file created")
It works and I got the message, but I'm not sure why. I'd like to have all my I/O file/vars at the begginig of the script, but with this one (out_arq) I can't.
How can I solve this? And why this happens?
If you look at the stack trace that is printed by the exception, you should see that the exception is raised on this line:
out_arq = sys.argv[2]
This is outside the try block, so the exception is not caught, and causes your program to terminate.
A solution is to check, before indexing the array, whether the element exists:
out_arq = sys.argv[2] if len(sys.argv) >= 3 else None
Then use if instead of try:
if out_arq:
results_df.to_csv(out_arq,index = False)
print(f"File saved as: {out_arq}")
else:
print("No output file created")
The below function parses the cisco command output,stores the output in dictionary and returns the value for a given key. This function works as expected when the dictionary contains the output. However, if the command returns no output at all the length of dictionary is 0 and the function returns a key error . I have used exception KeyError: But this doesn't seem to work.
from qa.ssh import Ssh
import re
class crypto:
def __init__(self, username, ip, password, machinetype):
self.user_name = username
self.ip_address = ip
self.pass_word = password
self.machine_type = machinetype
self.router_ssh = Ssh(ip=self.ip_address,
user=self.user_name,
password=self.pass_word,
machine_type=self.machine_type
)
def session_status(self, interface):
command = 'show crypto session interface '+interface
result = self.router_ssh.cmd(command)
try:
resultDict = dict(map(str.strip, line.split(':', 1))
for line in result.split('\n') if ':' in line)
return resultDict
except KeyError:
return False
test script :
obj = crypto('uname', 'ipaddr', 'password', 'router')
out = obj.session_status('tunnel0')
status = out['Peer']
print(status)
Error
Traceback (most recent call last):
File "./test_parser.py", line 16, in <module>
status = out['Peer']
KeyError: 'Peer'
The KeyError did not happend in the function session_status,it is happend in your script at status = out['Peer'].So your try and except in session_status will not work.you should make a try and except for status = out['Peer']:
try:
status = out['Peer']
except KeyError:
print 'no Peer'
or :
status = out.get('Peer', None)
Your exception is not in the right place. As you said you just return an empty dictionary with your function. The exception is trying to lookup the key on empty dictionary object that is returned status = outertunnel['Peer']. It might be easier to check it with the dict get function. status = outertunnel.get('Peer',False) or improve the test within the function session_status, like testing the length to decide what to return False if len(resultDict) == 0
This explains the problem you're seeing.
The exception happens when you reference out['Peer'] because out is an empty dict. To see where the KeyError exception can come into play, this is how it operates on an empty dict:
out = {}
status = out['Peer']
Throws the error you're seeing. The following shows how to deal with an unfound key in out:
out = {}
try:
status = out['Peer']
except KeyError:
status = False
print('The key you asked for is not here status has been set to False')
Even if the returned object was False, out['Peer'] still fails:
>>> out = False
>>> out['Peer']
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
out['Peer']
TypeError: 'bool' object is not subscriptable
I'm not sure how you should proceed, but dealing with the result of session_status not having the values you need is the way forward, and the try: except: block inside the session_status function isn't doing anything at the moment.
I'm running the following:
for server in server_list:
for item in required_fields:
print item, eval(item)
There is a possibility that some keys may not exist, but worse it's represented on a parent key not the one I'm scanning for.
So I'm scanning the json for the following key:
server['server_management']['server_total_cost_of_ownership']['description']
Which doesn't exist but it's actually the parent that is null:
server['server_management']['server_total_cost_of_ownership']
How do I write my code to account for this? It's not giving a key error. Right now I get the following traceback:
Traceback (most recent call last):
File "C:/projects/blah/scripts/test.py", line 29, in <module>
print item, eval(item)
File "<string>", line 1, in <module>
TypeError: 'NoneType' object has no attribute '__getitem__'
Full code:
import csv
import json
import os
import requests
import sys
required_fields = ["server['server_name']","server['server_info']['asset_type']['display_name']",
"server['asset_status']['display_name']", "server['record_owner']['group_name']",
"server['server_management']['server_total_cost_of_ownership']['description']",
"server['server_management']['primary_business_owner']['name']",
"server['environment']['display_name']", "server['is_virtual']",
"server['managed_by']['display_name']", "server['server_info']['billable_ibm']",
"server['server_info']['billing_sub_type']['display_name']",
"server['server_info']['serial_number']", "server['location']['display_name']",
"server['inception_date']", "server['server_info']['decommission_date']" ]
# Query API for all servers
def get_servers_info():
servers_info = requests.get('url')
return servers_info.json()
def get_server_info(sid):
server_info = requests.get('url')
return server_info.json()
server_list = get_servers_info()
for server in server_list:
for item in required_fields:
print item, eval(item)
In fact you should avoid eval. After the json load since you know the key name, you can use a list to go deeper in the tree.
server['server_management']['primary_business_owner']['name']" => ["server_management', 'primary_business_owner', 'name']
Here a snippet for a json validation against a list of required fields.
data={
"d": {
"p":{
"r":[
"test"
]
}
},
"a": 3
}
def _get_attr(dict_, attrs):
try:
src = attrs[:]
root = attrs.pop(0)
node = dict_[root]
null = object()
for i, attr in enumerate(attrs[:]):
try:
node = node.get(attr, null)
except AttributeError:
node = null
if node is null:
# i+2 pop and last element
raise ValueError("%s not present (level %s)" % (attr, '->'.join(src[: i+2])))
return node
except KeyError:
raise ValueError("%s not present" % root)
# assume list of required field
reqs = [
["d", "p", "r"],
["d"],
["k"],
["d", "p", "r", "e"],
]
for req in reqs:
try:
_get_attr(data, req)
except ValueError as E:
print(E)
# prints
# k not present
# e not present (level d->p->r->e)
Ignoring the context of the code and not understanding the use of eval here, the way to do this is to use .get() and seed it with reasonable defaults.
For example:
server['server_management']['server_total_cost_of_ownership']['description']
Can be:
server.get('server_management', {}).get('server_total_cost_of_ownership', {}).get('description', '')
Then if any of the keys do not exist you will always get back an empty description ''.
Your problem here is totally unrelated to using eval[1]. The exception you get is the same as if the code would have been there directly. What you are running (via eval) is:
a = server['server_management']
b = a['server_total_cost_of_ownership']
c = b['description']
Yet, b is None, so resolving it to c will fail. Like a KeyError, you can also catch a TypeError:
for server in server_list:
for item in required_fields:
try:
print item, eval(item)
except TypeError:
print("Guess you're lucky you didn't include a fork bomb in your own code to eval.")
You may of course alternatively pass, print the offending item, open a browser to some page or do whatever error handling is appropriate given your input data.
[1] While not bickering around, I've made a new answer that works without eval. You can use precisely the same error handling:
for server in server_list:
for item in required_fields:
value = server
for key in parse_fields(field):
try:
value = value[key]
except TypeError:
print("Remember Kiddo: Eval is Evil!")
break
else: # for: else: triggers only if no break was issued
print item, value