Python fails silently when moving code in another file - python

I'm pretty new to python and I have a strange issue which I can't manage to understand by my own, I'm sure it's stupid but I can see what it is and never encountered before, even having wiring several python scripts with lots of subfiles
For the record I'm coding and launching my script with Spyder (Python 3.6 version) on Windows but I set #!/usr/lib/python2.7/ at the beginning of each file
My main script is a big file and I wanted to refactor it by externalising code in some other files
The main is like that :
if __name__ == "__main__":
configuration = Conf.loadConf(os.path.join(scriptDir,confFile))
print(configuration)
loadFavs(configuration,bioses,setDict)
When loadFavs is in main script everything works fine
As soon as I move it in fav.py file at same level than my main script adding import fav and modifying fav.loadFavs(configuration,bioses,setDict) it stops working and Spyder just says nothing without any reason :
In [1]: runfile('C:/DevZone/workspaceFX/scripts4recalbox/BestArcade/fav.py', wdir='C:/DevZone/workspaceFX/scripts4recalbox/BestArcade')
In [2] runfile('C:/DevZone/workspaceFX/scripts4recalbox/BestArcade/fav.py', wdir='C:/DevZone/workspaceFX/scripts4recalbox/BestArcade')
The first line configuration = Conf.loadConf(os.path.join(scriptDir,confFile)) should print things on screen and it doesn't even show
As soon as I put back the code in main script my code works again
It happens with several different part of the script I tried to put in different files
I'm at a loss here, what I checked :
having at the beginning of each file
#!/usr/lib/python2.7/
# -- coding: utf-8 --
always end the script on an empty line
creating each file within Spyder and not outside
I don't thing the code I move is the issue has it works fine in main script and I had the issue with several pieces of code but here it is :
def parseSetFile(setFile, setDict) :
file = open(setFile,'r')
genre = None
# Parse iniFile in iniFile dir
for line in file.readlines() :
line = line.rstrip('\n\r ')
if (line.startswith('[') and not line == '[FOLDER_SETTINGS]' and not line == '[ROOT_FOLDER]') :
genre = line
if genre not in setDict :
setDict[genre] = []
else :
if (genre is not None and not line == '' ) :
setDict[genre].append(line)
def loadFavs(configuration, bioses, setDict) :
print("Load favs small set")
parseSetFile(os.path.join(configuration['scriptDir'],dataDir,smallSetFile),setDict)
print("Load favs big set")
parseSetFile(os.path.join(configuration['scriptDir'],dataDir,bigSetFile),setDict)
print('Nb Genre : %s' %len(setDict))
sumGames = 0
for key in setDict.keys() :
# print(key)
# print(setDict[key])
sumGames = sumGames + len(setDict[key])
print('Nb Games : %s' %sumGames)
print('Nb Bios : %s' %len(bioses))

OK i'm effectively massively stupid :
In [1]: runfile('C:/DevZone/workspaceFX/scripts4recalbox/BestArcade/fav.py', wdir='C:/DevZone/workspaceFX/scripts4recalbox/BestArcade')
I'm launching my fav.py subscript not the main one, and off course it doesn't have any main ......

Related

Python3.6 |- Import a module from a list with __import__ -|

I'm creating a really basic program that simulates a terminal with Python3.6, its name is Prosser(The origin is that "Prosser" sounds like "Processer" and Prosser is a command processer).
A problem that I'm having is with command import, this is, all the commands are stored in a folder called "lib" in the root folder of Prosser and inside it can have folders and files, if a folder is in the "lib" dir it can't be named as folder anymore, its name now is package(But this doesn't care for now).
The interface of the program is just a input writed:
Prosser:/home/pedro/documents/projects/prosser/-!
and the user can type a command before the text, like a normal terminal:
Prosser:/home/pedro/documents/projects/prosser/-! console.write Hello World
let's say that inside the "lib" folder exists one folder called "console" and inside it has a file called "write.py" that has the code:
class exec:
def main(args):
print(args)
As you can see the first 2 lines is like a important structure for command execution: The class "exec" is the main class for the command execution and the def "main" is the main and first function that the terminal will read and execute also pass the arguments that the user defined, after that the command will be responsible to catch any error and do what it will be created to do.
At this moment, everything is ok, but now comes the true help that I need of U guys, the command import.
Like I writed the user can type any command, and in the example above I typed a "console.write Hello World" and exists one folder called "console" and one file "write.py". The point is that the packages can be defined by a "dot", this is:
-! write Hello World
Above I only typed "write" and this says that the file is only inside the "lib" folder, it doesn't has a package to storage and separate it, so it is a Freedom command(A command that doesn't has packages or nodes).
-! console.write Hello World
Now I typed above "console.write" and this says that the file has a package or node to storage and separate it, this means that it is a Tied command(A command that has packages or nodes).
With that, a file is separated from the package(s) with a dot, the more dots you put, more folders will be navigated to find the file and proceed to the next execution.
Code
Finnaly the code. With the import statement I tryied this:
import os
import form
curDir = os.path.dirname(os.path.abspath(__file__)) # Returns the current direrctory open
while __name__ == "__main__":
c = input('Prosser:%s-! ' % (os.getcwd())).split() # Think the user typed "task.kill"
path = c[0].split('.') # Returns a list like: ["task", "kill"]
try:
args = c[1:] # Try get the command arguments
format = form.formater(args) # Just a text formatation like create a new line with "$n"
except:
args = None # If no arguments the args will just turn the None var type
pass
if os.path.exists(curDir + "/lib/" + "/".join(path) + ".py"): # If curDir+/lib/task/kill.py exists
module = __import__("lib." + '.'.join(path)) # Returns "lib.task.kill"
module.exec.main(args) # Execute the "exec" class and the def "**main**"
else:
pathlast = path[-1] # Get the last item, in this case "kill"
path.remove(path[-1]) # Remove the last item, "kill"
print('Error: Unknow command: ' + '.'.join(path) + '. >>' + pathlast + '<<') # Returns an error message like: "Error: Unknow command: task. >>kill<<"
# Reset the input interface
The problem is that when the line "module = __import__("lib." + '.'.join(path))" is executed the console prints the error:
Traceback (most recent call last):
File "/home/pedro/documents/projects/prosser/main.py", line 18, in <module>
module.exec.main(path) # Execute the "exec" class and the def "**main**"
AttributeError: module 'lib' has no attribute 'exec'
I also tried to use:
module = \_\_import\_\_(curDir + "lib." + '.'.join(path))
But it gets the same error. I think it's lighter for now. I'd like if someone help me or find some replacement of the code. :)
I think you have error here:
You have diffirent path here:
if os.path.exists(curDir + "/lib/" + "/".join(path) + ".py")
And another here, you dont have curDir:
module = __import__("lib." + '.'.join(path)) # Returns "lib.task.kill"
You should use os.path.join to build paths like this:
module = __import__(os.path.join(curdir, 'lib', path + '.py'))

Updating database after exporting to EXE

I am exporting a script I have made in Python that sends commands to IP Addresses of projectors to shut them down. The functionality of the code works, and the projectors will shut down. The list of projectors is stored in a dictionary in a different file to the script to allow it to be edited and accessed by other scripts.
Once I export my script to an exe using Pyinstaller v3.3.1 for Python 3.5.1, the .exe file no longer updates from the .py file that contains the dictionary, and instead has a version already stored in memory that I cannot update.
How can I make the executable file still read from the dictionary and update every time it is run?
Thanks,
Josh
Code:
dictonaryfile.py (reduced for security, but format shown).
projectors = {
'1': '192.168.0.1'
}
Script that performs shutdown
from pypjlink import Projector
from file3 import projectors
for item in projectors:
try:
myProjector = Projector.from_address(projectors[item])
myProjector.authenticate('PASSWORD REMOVED FOR SECURITY')
state = myProjector.get_power()
try:
if state == 'on':
myProjector.set_power('off')
print('Successfully powered off: ', item)
except:
print('The projector in ', item, ', raised an error, shutdown
may not have occurred')
continue
except:
print(item, 'did not respond to state request, it is likely powered
off at the wall.')
continue
As you noticed, once an exe is made, you can't update it. A workaround for a problem like this is ask for the location of dictonaryfile.py in your code-
from pypjlink import Projector
projector_location = input('Enter projector file location')
with open(projector_location) as f:
for line in f:
# extract data from f
....
For applications like these, it's a good idea to take a configuration file(.ini) and python has Configparser to read from config files. You could create your config file as -
[Projectors]
1 = '192.168.0.1'
2 = '192.168.0.45' # ..and so on
And read projectors from this file with Configparser -
config = configparser.ConfigParser()
config.read(projector_location)
projectors = config['PROJECTORS']
for k, v in projectors.items():
# your code here

Error when running on python idle

Update: I deleted the .dat file where everything is saved and now it works again. I would like some input on what might have caused it anything will help. I just want to know how to prevent it in the future.
Everything work perfectly yesterday using python idle.
Today I edited my program in pycharm to add a delete account feature. Everything runs on pycharm I can receive accounts, delete accounts, and create them. I decided to test it on idle because most computers I work on I can't download pycharm and I keep getting this error:
Traceback (most recent call last):
File "E:\Passwords\password.py", line 140, in ?
program_start()
File "E:\Passwords\password.py", line 137, in program_start
all_accounts()
File "E:\Passwords\password.py", line 93, in all_accounts
klist = f.keys()
File "C:\Python24\lib\shelve.py", line 98, in keys
return self.dict.keys()
File "C:\Python24\lib\bsddb\__init__.py", line 244, in keys
return self.db.keys()
DBRunRecoveryError: (-30978, 'DB_RUNRECOVERY: Fatal error, run database recovery -- accounts.dat: pgin failed for page 1')
I decided to run on pycharm again and against all odds it still ran perfectly no errors. What does this error mean? How can I fix it? And what causes it?
Also I have tried to run it on multiple computers to see if python idle would run it and none of them would.
Did the delete function ruin it?
def delete_account():
"""Deletes an account"""
print'\n'
account = raw_input("What account do you want to delete?: ")
f = shelve.open("accounts.dat")
if account in f:
confirm_deletion = raw_input("Are you sure you want to delete " + account + "?: ")
if confirm_deletion.lower() in ('yes', 'y'):
del f[account]
print "This account has been deleted."
else:
print "Canceled... "
else:
print "I'm sorry we could not find any account related to " + account
print '\n'
f.close
Or did pycharm cause this error?
Check your python version
It could be pycharm is using a different version of python as compared to the idle you have installed.

Python Click Error from help string associated with an option

I am trying to learn how to use Python-click. I was not able to use a help parameter with one of my options so I finally gave up and changed the code to not include help for that option. However, despite closing and restarting Python and now rebooting my computer the error message associated with trying to use the help parameter is still appearing.
Code:
import click
def something():
pass
#click.command()
#click.argument('dest_dir',type=click.Path(exists=True, readable=True,
resolve_path=True, dir_okay=True),
help='Location of directory where results will be saved')
#click.option('--use_terms', is_flag=True,
help='Process strings based on terms or phrases')
#click.option('--use_query', is_flag=True, help='Process string based on
search query')
#click.option('--search_phrase', '-s', multiple=True)
def do_process(dest_dir,use_terms,use_query,*search_phrase):
""" testing setting parameters for snip tables"""
outref = open('e:\\myTemp\\testq.txt')
ms = dest_dir + '\n'
if use_terms:
ms += use_term + '\n'
else:
ms += use_query + '\n'
for each in search_phrase:
x = something()
ms += each + '\n'
outref.writelines(ms)
outref.close()
if __name__ == "__main__":
do_process()
Originally for the last #click.option I had
#click.option('--search_phrase', '-s', multiple=True, help='The search phrase to use')
I kept getting an error message that I could not solve relating to having an unknown parameter help. I ditched it, changed to what is above and now I am getting a similar error,
I then shut down Python, I closed my module and then restarted Python opened and ran my code again and still getting this error message
Traceback:
Traceback (most recent call last):
File "C:\Program Files\PYTHON\snipTables\test_snip_click.py", line 14, in <module>
#click.option('--search_phrase', '-s', multiple=True)
File "C:\Program Files\PYTHON\lib\site-packages\click\decorators.py", line 148, in decorator
_param_memo(f, ArgumentClass(param_decls, **attrs))
File "C:\Program Files\PYTHON\lib\site-packages\click\core.py", line 1618, in __init__
Parameter.__init__(self, param_decls, required=required, **attrs)
TypeError: __init__() got an unexpected keyword argument 'help'
So then I shut down Python Idle, I saved and closed my code and then restarted Python, reopened my code, but I am still getting the same traceback except notice that the traceback has the line of code I switched to after beating my head hard against the monitor and giving up
I am getting ready to reboot but am really curious as to the cause.
I rebooted and still am getting the same error
Renaming the file and running again did not change outcome - same traceback
The problem is that click does not accept a help string with an argument parameter. It is interesting behavior. The help string associated with the argument will be the string in the function that processes the argument and options.
The error message will always show up associated with the last option. So the correct code for this example would be
import click
def something():
pass
#click.command()
#click.argument('dest_dir',type=click.Path(exists=True, readable=True,
resolve_path=True, dir_okay=True)
##Notice no help string here
#click.option('--use_terms', is_flag=True,
help='Process strings based on terms or phrases')
#click.option('--use_query', is_flag=True, help='Process string based on
search query')
#click.option('--search_phrase', '-s', multiple=True)
def do_process(dest_dir,use_terms,use_query,*search_phrase):
""" testing setting parameters for snip tables"""
outref = open('e:\\myTemp\\testq.txt')
ms = dest_dir + '\n'
if use_terms:
ms += use_term + '\n'
else:
ms += use_query + '\n'
for each in search_phrase:
x = something()
ms += each + '\n'
outref.writelines(ms)
outref.close()
if __name__ == "__main__":
do_process()
This runs fine the problem I was originally having is that click was not doing a good job of explaining the source of the error. Above, even though I got rid of the help string in the option the click parser associates the help string from the argument with the last option it parses.
Maybe you renamed the source file and you are running an old version that was compiled with the previous name?
try deleting *.pyc files

Python Cmd Tab Completion Problems

I've got an application I'm currently working on for our company. Its currently built around Python's Cmd module, and features tab-completion for a number of tasks.
For some reason however, the Tab completion only currently works on one machine in the building - running the scripts from other machines doesn't allow the tab completion.
Here's the offending code parts:
def populate_jobs_list():
global avail_jobs
avail_jobs = os.walk(rootDir()).next()[1]
print avail_jobs
...
def complete_job(self, text, line, start_index, end_index):
global avail_jobs
populate_jobs_list()
if text:
return [
jobs for jobs in avail_jobs
if jobs.startswith(text)
]
else:
return avail_jobs
def do_job(self, args):
pass
split_args = args.rsplit()
os.environ['JOB'] = args
job_dir = os.path.join( rootDir(), os.getenv('JOB'))
os.environ['JOB_PROPS'] = (job_dir + '\\job_format.opm')
if not os.path.isdir(job_dir):
print 'Job does not exist. Try again.'
return
else:
print('Jobbed into: ' + os.getenv('JOB'))
return
populate_jobs_list()
prompt = outPrompt()
prompt.prompt = '\> '
prompt.cmdloop('Loading...')
Am I missing something obvious here? Just to clarify, on machine A, the tab completion works as intended. When its run on any other machine in the building, it fails to complete.
Check if the environment variable PYTHONSTARTUP is set properly. It should point to a script which in turn needs to do sth like this:
try:
import readline
except ImportError:
sys.stdout.write("No readline module found, no tab completion available.\n")
else:
import rlcompleter
readline.parse_and_bind('tab: complete')
Maybe (some part of) this is only done properly on the one working machine?
Maybe the readline module is available only on the one working machine?

Categories

Resources