From: Gilles DAVID Date: Mon, 29 May 2017 11:25:36 +0000 (+0200) Subject: Python 3 - optparse => argparse X-Git-Tag: V9_0_0~25^2~1 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=1315fd971e7333a532456a346fce4c181487aaa3;p=modules%2Fkernel.git Python 3 - optparse => argparse --- diff --git a/bin/appliskel/kill_remote_containers.py b/bin/appliskel/kill_remote_containers.py index 4c3a39429..39bb93397 100755 --- a/bin/appliskel/kill_remote_containers.py +++ b/bin/appliskel/kill_remote_containers.py @@ -25,14 +25,14 @@ """ """ import sys,os,shutil,glob,socket -import optparse +import argparse from salome_utils import getUserName import getAppliPath appli_local=os.path.realpath(os.path.dirname(__file__)) APPLI=getAppliPath.relpath(appli_local,os.path.realpath(os.getenv('HOME'))) -usage="""usage: %prog [options] +usage="""%(prog)s [options] This procedure kill all containers that have been launched in a SALOME session on remote machines. A SALOME session is identified by a machine name and a port number. @@ -110,15 +110,14 @@ class Resource: return appliPath def main(): - parser = optparse.OptionParser(usage=usage) - parser.add_option('-p','--port', dest="port", - help="The SALOME session port (default NSPORT or 2810)") + parser = argparse.ArgumentParser(usage=usage) + parser.add_argument('-p','--port', dest="port", + help="The SALOME session port (default NSPORT or 2810)") - - options, args = parser.parse_args() + args = parser.parse_args() if not os.path.exists(catalog_file): - print("ERROR: the catalog file %s is mandatory" % catalog_file_base) + print("ERROR: the catalog file %s is mandatory" % catalog_file) sys.exit(1) #Parse CatalogResource.xml @@ -142,13 +141,14 @@ def main(): if resource.get_host() in local_names:continue command=resource.get_rsh() +" -l "+resource.get_user()+" "+resource.get_host() command=command+ " " + os.path.join(resource.get_appliPath(),"runRemote.sh") - if options.port: - port=options.port + if args.port: + port=args.port else: port=os.getenv("NSPORT") or "2810" command=command+ " " + get_hostname() + " " + port +" killSalomeWithPort.py " + port print(command) - os.system(command) + return subprocess.call(command, shell=True) + if __name__ == '__main__': main() diff --git a/bin/appliskel/update_catalogs.py b/bin/appliskel/update_catalogs.py index 8555e0c46..e9981d662 100644 --- a/bin/appliskel/update_catalogs.py +++ b/bin/appliskel/update_catalogs.py @@ -25,14 +25,14 @@ """ """ import sys,os,shutil,glob,socket -import optparse +import argparse from salome_utils import getUserName import getAppliPath appli_local=os.path.realpath(os.path.dirname(__file__)) APPLI=getAppliPath.relpath(appli_local,os.path.realpath(os.getenv('HOME'))) -usage="""usage: %prog [options] +usage="""%(prog)s [options] Typical use is: python update_catalogs.py @@ -207,9 +207,8 @@ class Resource: def main(): - parser = optparse.OptionParser(usage=usage) - - options, args = parser.parse_args() + parser = argparse.ArgumentParser(usage=usage) + args = parser.parse_args() if not os.path.exists(catalog_file_base): print("ERROR: the base catalog file %s is mandatory" % catalog_file_base) @@ -251,11 +250,10 @@ def main(): mach.update() #dump new CatalogResources.xml - f=open(catalog_file,'w') - f.write('\n') - doc.write(f) - f.write('\n') - f.close() + with open(catalog_file,'w') as f: + f.write('\n') + doc.write(f) + f.write('\n') print("%s updated" % catalog_file) #update configRemote.sh in env.d directory (environment variable SALOME_CATALOGS_PATH) @@ -264,9 +262,8 @@ def main(): if mach.resource_dir: path.append(mach.resource_dir) - f=open(os.path.join(appli_local,"env.d","configRemote.sh"),'w') - f.write("export SALOME_CATALOGS_PATH=%s\n" % SEP.join(path)) - f.close() + with open(os.path.join(appli_local,"env.d","configRemote.sh"),'w') as f: + f.write("export SALOME_CATALOGS_PATH=%s\n" % SEP.join(path)) if __name__ == '__main__': diff --git a/bin/launchConfigureParser.py b/bin/launchConfigureParser.py index 4ea79d03c..f5331d5d5 100755 --- a/bin/launchConfigureParser.py +++ b/bin/launchConfigureParser.py @@ -21,13 +21,15 @@ # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com # -import os, glob, string, sys, re +import argparse +import glob +import os +import re +import sys import xml.sax -import optparse -import types from salome_utils import verbose, getPortNumber, getHomeDir -from six import string_types + # names of tags in XML configuration file doc_tag = "document" @@ -214,7 +216,7 @@ def userFile(appname, cfgname): files += glob.glob(os.path.join(getHomeDir(), filetmpl2.format(appname))) pass - # ... loop through all files and find most appopriate file (with closest id) + # ... loop through all files and find most appropriate file (with closest id) appr_id = -1 appr_file = "" for f in files: @@ -285,11 +287,11 @@ class xml_parser: def boolValue( self, item): strloc = item - if isinstance(strloc, string_types): + if isinstance(strloc, str): strloc = strloc.encode().strip() if isinstance(strloc, bytes): strlow = strloc.decode().lower() - if strlow in ("1", "yes", "y", "on", "true", "ok"): + if strlow in ("1", "yes", "y", "on", "true", "ok"): return True elif strlow in ("0", "no", "n", "off", "false", "cancel"): return False @@ -298,11 +300,11 @@ class xml_parser: def intValue( self, item): strloc = item - if isinstance(strloc, string_types): + if isinstance(strloc, str): strloc = strloc.encode().strip() if isinstance(strloc, bytes): strlow = strloc.decode().lower() - if strlow in ("1", "yes", "y", "on", "true", "ok"): + if strlow in ("1", "yes", "y", "on", "true", "ok"): return 1 elif strlow in ("0", "no", "n", "off", "false", "cancel"): return 0 @@ -421,7 +423,7 @@ class xml_parser: # import file imp = xml_parser(absfname, opts, self.importHistory) # merge results - for key in list(imp.opts.keys()): + for key in imp.opts: if key not in self.opts: self.opts[key] = imp.opts[key] pass @@ -434,425 +436,367 @@ class xml_parser: # ----------------------------------------------------------------------------- -booleans = { '1': True , 'yes': True , 'y': True , 'on' : True , 'true' : True , 'ok' : True, - '0': False, 'no' : False, 'n': False, 'off': False, 'false': False, 'cancel' : False } +booleans = {'1': True , 'yes': True , 'y': True , 'on' : True , 'true' : True , 'ok' : True, + '0': False, 'no' : False, 'n': False, 'off': False, 'false': False, 'cancel' : False} boolean_choices = list(booleans.keys()) -def check_embedded(option, opt, value, parser): - from optparse import OptionValueError - assert value is not None - if parser.values.embedded: - embedded = [a for a in re.split( "[:;,]", parser.values.embedded ) if a.strip()] - else: - embedded = [] - if parser.values.standalone: - standalone = [a for a in re.split( "[:;,]", parser.values.standalone ) if a.strip()] - else: - standalone = [] - vals = [a for a in re.split( "[:;,]", value ) if a.strip()] - for v in vals: - if v not in embedded_choices: - raise OptionValueError( "option %s: invalid choice: %r (choose from %s)" % ( opt, v, ", ".join( map( repr, embedded_choices ) ) ) ) - if v not in embedded: - embedded.append( v ) - if v in standalone: - del standalone[ standalone.index( v ) ] - pass - parser.values.embedded = ",".join( embedded ) - parser.values.standalone = ",".join( standalone ) - pass -def check_standalone(option, opt, value, parser): - from optparse import OptionValueError - assert value is not None - if parser.values.embedded: - embedded = [a for a in re.split( "[:;,]", parser.values.embedded ) if a.strip()] - else: - embedded = [] - if parser.values.standalone: - standalone = [a for a in re.split( "[:;,]", parser.values.standalone ) if a.strip()] - else: - standalone = [] - vals = [a for a in re.split( "[:;,]", value ) if a.strip()] - for v in vals: - if v not in standalone_choices: - raise OptionValueError( "option %s: invalid choice: %r (choose from %s)" % ( opt, v, ", ".join( map( repr, standalone_choices ) ) ) ) - if v not in standalone: - standalone.append( v ) - if v in embedded: - del embedded[ embedded.index( v ) ] - pass - parser.values.embedded = ",".join( embedded ) - parser.values.standalone = ",".join( standalone ) - pass +class CheckEmbeddedAction(argparse.Action): + def __call__(self, parser, namespace, value, option_string=None): + assert value is not None + if namespace.embedded: + embedded = [a for a in re.split("[:;,]", namespace.embedded) if a.strip()] + else: + embedded = [] + if namespace.standalone: + standalone = [a for a in re.split("[:;,]", namespace.standalone) if a.strip()] + else: + standalone = [] + vals = [a for a in re.split("[:;,]", value) if a.strip()] + for v in vals: + if v not in embedded_choices: + raise argparse.ArgumentError("option %s: invalid choice: %r (choose from %s)" + % (self.dest, v, ", ".join(map(repr, embedded_choices)))) + if v not in embedded: + embedded.append(v) + if v in standalone: + del standalone[standalone.index(v)] + pass + namespace.embedded = ",".join(embedded) + namespace.standalone = ",".join(standalone) + pass -def store_boolean (option, opt, value, parser, *args): - if isinstance(value, bytes) or isinstance(value, str): - try: - value_conv = booleans[value.strip().lower()] - for attribute in args: - setattr(parser.values, attribute, value_conv) - except KeyError: - raise optparse.OptionValueError( - "option %s: invalid boolean value: %s (choose from %s)" - % (opt, value, boolean_choices)) - else: - for attribute in args: - setattr(parser.values, attribute, value) -def CreateOptionParser (theAdditionalOptions=None, exeName=None): - if theAdditionalOptions is None: - theAdditionalOptions = [] +class CheckStandaloneAction(argparse.Action): + def __call__(self, parser, namespace, value, option_string=None): + assert value is not None + if namespace.embedded: + embedded = [a for a in re.split("[:;,]", namespace.embedded) if a.strip()] + else: + embedded = [] + if namespace.standalone: + standalone = [a for a in re.split("[:;,]", namespace.standalone) if a.strip()] + else: + standalone = [] + vals = [a for a in re.split("[:;,]", value) if a.strip()] + for v in vals: + if v not in standalone_choices: + raise argparse.ArgumentError("option %s: invalid choice: %r (choose from %s)" + % (self.dest, v, ", ".join(map(repr, standalone_choices)))) + if v not in standalone: + standalone.append(v) + if v in embedded: + del embedded[embedded.index(v)] + pass + namespace.embedded = ",".join(embedded) + namespace.standalone = ",".join(standalone) + + +class StoreBooleanAction(argparse.Action): + def __call__(self, parser, namespace, value, option_string=None): + if isinstance(value, bytes): + value = value.decode() + if isinstance(value, str): + try: + value_conv = booleans[value.strip().lower()] + setattr(namespace, self.dest, value_conv) + except KeyError: + raise argparse.ArgumentError( + "option %s: invalid boolean value: %s (choose from %s)" + % (self.dest, value, boolean_choices)) + else: + setattr(namespace, self.dest, value) + + +def CreateOptionParser(exeName=None): + + if not exeName: + exeName = "%(prog)s" + + a_usage = """%s [options] [STUDY_FILE] [PYTHON_FILE [args] [PYTHON_FILE [args]...]] +Python file arguments, if any, must be comma-separated (without blank characters) and prefixed by "args:" (without quotes), e.g. myscript.py args:arg1,arg2=val,... +""" % exeName + version_str = "Salome %s" % version() + pars = argparse.ArgumentParser(usage=a_usage) + + # Version + pars.add_argument('-v', '--version', action='version', version=version_str) + # GUI/Terminal. Default: GUI help_str = "Launch without GUI (in the terminal mode)." - o_t = optparse.Option("-t", - "--terminal", - action="store_false", - dest="gui", - help=help_str) + pars.add_argument("-t", + "--terminal", + action="store_false", + dest="gui", + help=help_str) help_str = "Launch in Batch Mode. (Without GUI on batch machine)" - o_b = optparse.Option("-b", - "--batch", - action="store_true", - dest="batch", - help=help_str) + pars.add_argument("-b", + "--batch", + action="store_true", + dest="batch", + help=help_str) help_str = "Launch in GUI mode [default]." - o_g = optparse.Option("-g", - "--gui", - action="store_true", - dest="gui", - help=help_str) + pars.add_argument("-g", + "--gui", + action="store_true", + dest="gui", + help=help_str) # Show Desktop (inly in GUI mode). Default: True help_str = "1 to activate GUI desktop [default], " help_str += "0 to not activate GUI desktop (Session_Server starts, but GUI is not shown). " help_str += "Ignored in the terminal mode." - o_d = optparse.Option("-d", - "--show-desktop", - metavar="<1/0>", - #type="choice", choices=boolean_choices, - type="string", - action="callback", callback=store_boolean, callback_args=('desktop',), - dest="desktop", - help=help_str) + pars.add_argument("-d", + "--show-desktop", + metavar="<1/0>", + action=StoreBooleanAction, + dest="desktop", + help=help_str) help_str = "Do not activate GUI desktop (Session_Server starts, but GUI is not shown). " help_str += "The same as --show-desktop=0." - o_o = optparse.Option("-o", - "--hide-desktop", - action="store_false", - dest="desktop", - help=help_str) + pars.add_argument("-o", + "--hide-desktop", + action="store_false", + dest="desktop", + help=help_str) # Use logger or log-file. Default: nothing. help_str = "Redirect messages to the CORBA collector." - #o4 = optparse.Option("-l", "--logger", action="store_true", dest="logger", help=help_str) - o_l = optparse.Option("-l", - "--logger", - action="store_const", const="CORBA", - dest="log_file", - help=help_str) + pars.add_argument("-l", + "--logger", + action="store_const", const="CORBA", + dest="log_file", + help=help_str) help_str = "Redirect messages to the " - o_f = optparse.Option("-f", - "--log-file", - metavar="", - type="string", - action="store", - dest="log_file", - help=help_str) + pars.add_argument("-f", + "--log-file", + metavar="", + dest="log_file", + help=help_str) # Configuration XML file. Default: see defaultUserFile() function - help_str = "Parse application settings from the " + help_str = "Parse application settings from the " help_str += "instead of default %s" % defaultUserFile() - o_r = optparse.Option("-r", - "--resources", - metavar="", - type="string", - action="store", - dest="resources", - help=help_str) + pars.add_argument("-r", + "--resources", + metavar="", + dest="resources", + help=help_str) # Use own xterm for each server. Default: False. help_str = "Launch each SALOME server in own xterm console" - o_x = optparse.Option("-x", - "--xterm", - action="store_true", - dest="xterm", - help=help_str) + pars.add_argument("-x", + "--xterm", + action="store_true", + dest="xterm", + help=help_str) # Modules. Default: Like in configuration files. help_str = "SALOME modules list (where , are the names " help_str += "of SALOME modules which should be available in the SALOME session)" - o_m = optparse.Option("-m", - "--modules", - metavar="", - type="string", - action="append", - dest="modules", - help=help_str) + pars.add_argument("-m", + "--modules", + metavar="", + action="append", + dest="modules", + help=help_str) # Embedded servers. Default: Like in configuration files. help_str = "CORBA servers to be launched in the Session embedded mode. " help_str += "Valid values for : %s " % ", ".join( embedded_choices ) help_str += "[by default the value from the configuration files is used]" - o_e = optparse.Option("-e", - "--embedded", - metavar="", - type="string", - action="callback", - dest="embedded", - callback=check_embedded, - help=help_str) + pars.add_argument("-e", + "--embedded", + metavar="", + action=CheckEmbeddedAction, + dest="embedded", + help=help_str) # Standalone servers. Default: Like in configuration files. help_str = "CORBA servers to be launched in the standalone mode (as separate processes). " help_str += "Valid values for : %s " % ", ".join( standalone_choices ) help_str += "[by default the value from the configuration files is used]" - o_s = optparse.Option("-s", - "--standalone", - metavar="", - type="string", - action="callback", - dest="standalone", - callback=check_standalone, - help=help_str) + pars.add_argument("-s", + "--standalone", + metavar="", + action=CheckStandaloneAction, + dest="standalone", + help=help_str) # Kill with port. Default: False. help_str = "Kill SALOME with the current port" - o_p = optparse.Option("-p", - "--portkill", - action="store_true", - dest="portkill", - help=help_str) + pars.add_argument("-p", + "--portkill", + action="store_true", + dest="portkill", + help=help_str) # Kill all. Default: False. help_str = "Kill all running SALOME sessions" - o_k = optparse.Option("-k", - "--killall", - action="store_true", - dest="killall", - help=help_str) + pars.add_argument("-k", + "--killall", + action="store_true", + dest="killall", + help=help_str) # Additional python interpreters. Default: 0. help_str = "The number of additional external python interpreters to run. " help_str += "Each additional python interpreter is run in separate " help_str += "xterm session with properly set SALOME environment" - o_i = optparse.Option("-i", - "--interp", - metavar="", - type="int", - action="store", - dest="interp", - help=help_str) + pars.add_argument("-i", + "--interp", + metavar="", + type=int, + dest="interp", + help=help_str) # Splash. Default: True. help_str = "1 to display splash screen [default], " help_str += "0 to disable splash screen. " help_str += "This option is ignored in the terminal mode. " help_str += "It is also ignored if --show-desktop=0 option is used." - o_z = optparse.Option("-z", - "--splash", - metavar="<1/0>", - #type="choice", choices=boolean_choices, - type="string", - action="callback", callback=store_boolean, callback_args=('splash',), - dest="splash", - help=help_str) + pars.add_argument("-z", + "--splash", + metavar="<1/0>", + action=StoreBooleanAction, + dest="splash", + help=help_str) # Catch exceptions. Default: True. help_str = "1 (yes,true,on,ok) to enable centralized exception handling [default], " help_str += "0 (no,false,off,cancel) to disable centralized exception handling." - o_c = optparse.Option("-c", - "--catch-exceptions", - metavar="<1/0>", - #type="choice", choices=boolean_choices, - type="string", - action="callback", callback=store_boolean, callback_args=('catch_exceptions',), - dest="catch_exceptions", - help=help_str) + pars.add_argument("-c", + "--catch-exceptions", + metavar="<1/0>", + action=StoreBooleanAction, + dest="catch_exceptions", + help=help_str) # Print free port and exit help_str = "Print free port and exit" - o_a = optparse.Option("--print-port", - action="store_true", - dest="print_port", default=False, - help=help_str) + pars.add_argument("--print-port", + action="store_true", + dest="print_port", + help=help_str) # Do not relink ${HOME}/.omniORB_last.cfg help_str = "Do not save current configuration ${HOME}/.omniORB_last.cfg" - o_n = optparse.Option("--nosave-config", - action="store_false", - dest="save_config", default=True, - help=help_str) + pars.add_argument("--nosave-config", + action="store_false", + dest="save_config", + help=help_str) # Launch with interactive python console. Default: False. help_str = "Launch with interactive python console." - o_pi = optparse.Option("--pinter", - action="store_true", - dest="pinter", - help=help_str) + pars.add_argument("--pinter", + action="store_true", + dest="pinter", + help=help_str) # Print Naming service port into a user file. Default: False. help_str = "Print Naming Service Port into a user file." - o_nspl = optparse.Option("--ns-port-log", - metavar="", - type="string", - action="store", - dest="ns_port_log_file", - help=help_str) + pars.add_argument("--ns-port-log", + metavar="", + dest="ns_port_log_file", + help=help_str) # Write/read test script file with help of TestRecorder. Default: False. help_str = "Write/read test script file with help of TestRecorder." - o_test = optparse.Option("--test", - metavar="", - type="string", - action="store", - dest="test_script_file", - help=help_str) + pars.add_argument("--test", + metavar="", + dest="test_script_file", + help=help_str) # Reproducing test script with help of TestRecorder. Default: False. help_str = "Reproducing test script with help of TestRecorder." - o_play = optparse.Option("--play", - metavar="", - type="string", - action="store", - dest="play_script_file", - help=help_str) + pars.add_argument("--play", + metavar="", + dest="play_script_file", + help=help_str) # gdb session help_str = "Launch session with gdb" - o_gdb = optparse.Option("--gdb-session", - action="store_true", - dest="gdb_session", default=False, - help=help_str) + pars.add_argument("--gdb-session", + action="store_true", + dest="gdb_session", + help=help_str) # ddd session help_str = "Launch session with ddd" - o_ddd = optparse.Option("--ddd-session", - action="store_true", - dest="ddd_session", default=False, - help=help_str) + pars.add_argument("--ddd-session", + action="store_true", + dest="ddd_session", + help=help_str) # valgrind session help_str = "Launch session with valgrind $VALGRIND_OPTIONS" - o_valgrind = optparse.Option("--valgrind-session", - action="store_true", - dest="valgrind_session", default=False, - help=help_str) + pars.add_argument("--valgrind-session", + action="store_true", + dest="valgrind_session", + help=help_str) # shutdown-servers. Default: False. help_str = "1 to shutdown standalone servers when leaving python interpreter, " help_str += "0 to keep the standalone servers as daemon [default]. " help_str += "This option is only useful in batchmode " help_str += "(terminal mode or without showing desktop)." - o_shutdown = optparse.Option("-w", - "--shutdown-servers", - metavar="<1/0>", - #type="choice", choices=boolean_choices, - type="string", - action="callback", callback=store_boolean, callback_args=('shutdown_servers',), - dest="shutdown_servers", - help=help_str) + pars.add_argument("-w", + "--shutdown-servers", + metavar="<1/0>", + action=StoreBooleanAction, + dest="shutdown_servers", + help=help_str) # foreground. Default: True. help_str = "0 and runSalome exits after have launched the gui, " help_str += "1 to launch runSalome in foreground mode [default]." - o_foreground = optparse.Option("--foreground", - metavar="<1/0>", - #type="choice", choices=boolean_choices, - type="string", - action="callback", callback=store_boolean, callback_args=('foreground',), - dest="foreground", - help=help_str) + pars.add_argument("--foreground", + metavar="<1/0>", + action=StoreBooleanAction, + dest="foreground", + help=help_str) # wake up session help_str = "Wake up a previously closed session. " help_str += "The session object is found in the naming service pointed by the variable OMNIORB_CONFIG. " help_str += "If this variable is not setted, the last configuration is taken. " - o_wake_up = optparse.Option("--wake-up-session", - action="store_true", - dest="wake_up_session", default=False, - help=help_str) + pars.add_argument("--wake-up-session", + action="store_true", + dest="wake_up_session", + help=help_str) # server launch mode help_str = "Mode used to launch server processes (daemon or fork)." - o_slm = optparse.Option("--server-launch-mode", - metavar="", - type="choice", - choices=["daemon","fork"], - action="store", - dest="server_launch_mode", - help=help_str) + pars.add_argument("--server-launch-mode", + metavar="", + choices=["daemon", "fork"], + dest="server_launch_mode", + help=help_str) # use port help_str = "Preferable port SALOME to be started on. " help_str += "If specified port is not busy, SALOME session will start on it; " help_str += "otherwise, any available port will be searched and used." - o_port = optparse.Option("--port", - metavar="", - type="int", - action="store", - dest="use_port", - help=help_str) + pars.add_argument("--port", + metavar="", + type=int, + dest="use_port", + help=help_str) + # Language help_str = "Force application language. By default, a language specified in " help_str += "the user's preferences is used." - o_lang = optparse.Option("-a", - "--language", - action="store", - dest="language", - help=help_str) - - # All options - opt_list = [o_t,o_g, # GUI/Terminal - o_d,o_o, # Desktop - o_b, # Batch - o_l,o_f, # Use logger or log-file - o_r, # Configuration XML file - o_x, # xterm - o_m, # Modules - o_e, # Embedded servers - o_s, # Standalone servers - o_p, # Kill with port - o_k, # Kill all - o_i, # Additional python interpreters - o_z, # Splash - o_c, # Catch exceptions - o_a, # Print free port and exit - o_n, # --nosave-config - o_pi, # Interactive python console - o_nspl, - o_test, # Write/read test script file with help of TestRecorder - o_play, # Reproducing test script with help of TestRecorder - o_gdb, - o_ddd, - o_valgrind, - o_shutdown, - o_foreground, - o_wake_up, - o_slm, # Server launch mode - o_port, # Use port - o_lang, # Language - ] - - #std_options = ["gui", "desktop", "log_file", "resources", - # "xterm", "modules", "embedded", "standalone", - # "portkill", "killall", "interp", "splash", - # "catch_exceptions", "print_port", "save_config", "ns_port_log_file"] - - opt_list += theAdditionalOptions - - if not exeName: - exeName = "%prog" + pars.add_argument("-a", + "--language", + dest="language", + help=help_str) - a_usage = """%s [options] [STUDY_FILE] [PYTHON_FILE [args] [PYTHON_FILE [args]...]] -Python file arguments, if any, must be comma-separated (without blank characters) and prefixed by "args:" (without quotes), e.g. myscript.py args:arg1,arg2=val,... -"""%exeName - version_str = "Salome %s" % version() - pars = optparse.OptionParser(usage=a_usage, version=version_str, option_list=opt_list) + # Positional arguments (hdf file, python file) + pars.add_argument("arguments", nargs=argparse.REMAINDER) return pars @@ -866,7 +810,7 @@ Python file arguments, if any, must be comma-separated (without blank characters args = {} #def get_env(): #args = [] -def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgname, exeName=None): +def get_env(appname=salomeappname, cfgname=salomecfgname, exeName=None): ### # Collect launch configuration files: # - The environment variable "Config" (SalomeAppConfig) which can @@ -889,9 +833,6 @@ def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgn # specified in configuration file(s) ### - if theAdditionalOptions is None: - theAdditionalOptions = [] - global args config_var = appname+'Config' @@ -906,8 +847,8 @@ def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgn ############################ # parse command line options - pars = CreateOptionParser(theAdditionalOptions, exeName=exeName) - (cmd_opts, cmd_args) = pars.parse_args(sys.argv[1:]) + pars = CreateOptionParser(exeName=exeName) + cmd_opts = pars.parse_args(sys.argv[1:]) ############################ # Process --print-port option @@ -936,7 +877,7 @@ def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgn gui_available = False if os.getenv("GUI_ROOT_DIR"): gui_resources_dir = os.path.join(os.getenv("GUI_ROOT_DIR"),'share','salome','resources','gui') - if os.path.isdir( gui_resources_dir ): + if os.path.isdir(gui_resources_dir): gui_available = True dirs.append(gui_resources_dir) pass @@ -957,8 +898,8 @@ def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgn _opts = {} # associative array of options to be filled # parse SalomeApp.xml files in directories specified by SalomeAppConfig env variable - for dir in dirs: - filename = os.path.join(dir, appname+'.xml') + for directory in dirs: + filename = os.path.join(directory, appname + '.xml') if not os.path.exists(filename): if verbose(): print("Configure parser: Warning : can not find configuration file %s" % filename) else: @@ -1002,7 +943,7 @@ def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgn args[aKey] = 0 if args[file_nam]: - afile=args[file_nam] + afile = args[file_nam] args[file_nam] = [afile] args[appname_nam] = appname @@ -1054,26 +995,28 @@ def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgn # Naming Service port log file if cmd_opts.ns_port_log_file is not None: - args["ns_port_log_file"] = cmd_opts.ns_port_log_file + args["ns_port_log_file"] = cmd_opts.ns_port_log_file # Study files - for arg in cmd_args: - if arg[-4:] == ".hdf" and not args["study_hdf"]: + for arg in cmd_opts.arguments: + file_extension = os.path.splitext(arg)[-1] + if file_extension == ".hdf" and not args["study_hdf"]: args["study_hdf"] = arg # Python scripts from salomeContextUtils import getScriptsAndArgs, ScriptAndArgs - args[script_nam] = getScriptsAndArgs(cmd_args) + args[script_nam] = getScriptsAndArgs(cmd_opts.arguments) if args[gui_nam] and args["session_gui"]: new_args = [] - for sa_obj in args[script_nam]: # args[script_nam] is a list of ScriptAndArgs objects + for sa_obj in args[script_nam]: # args[script_nam] is a list of ScriptAndArgs objects script = re.sub(r'^python.*\s+', r'', sa_obj.script) new_args.append(ScriptAndArgs(script=script, args=sa_obj.args, out=sa_obj.out)) # args[script_nam] = new_args # xterm - if cmd_opts.xterm is not None: args[xterm_nam] = cmd_opts.xterm + if cmd_opts.xterm is not None: + args[xterm_nam] = cmd_opts.xterm # Modules if cmd_opts.modules is not None: @@ -1154,13 +1097,6 @@ def get_env(theAdditionalOptions=None, appname=salomeappname, cfgname=salomecfgn if cmd_opts.wake_up_session is not None: args[wake_up_session_nam] = cmd_opts.wake_up_session - #################################################### - # Add values to args - for add_opt in theAdditionalOptions: - cmd = "args[\"{0}\"] = cmd_opts.{0}".format(add_opt.dest) - exec(cmd) - #################################################### - # disable signals handling if args[except_nam] == 1: os.environ["NOT_INTERCEPT_SIGNALS"] = "1" diff --git a/bin/salomeContextUtils.py.in b/bin/salomeContextUtils.py.in index ae2ea269d..4835bcd25 100644 --- a/bin/salomeContextUtils.py.in +++ b/bin/salomeContextUtils.py.in @@ -221,17 +221,18 @@ def getScriptsAndArgs(args=None, searchPathList=None): callPython = True afterArgs = False else: + file_extension = os.path.splitext(elt)[-1] if not os.path.isfile(elt) and not os.path.isfile(elt+".py"): eltInSearchPath = __getScriptPath(elt, searchPathList) if eltInSearchPath is None or (not os.path.isfile(eltInSearchPath) and not os.path.isfile(eltInSearchPath+".py")): - if elt[-3:] == ".py": + if file_extension == ".py": raise SalomeContextException("Script not found: %s"%elt) scriptArgs.append(ScriptAndArgs(script=elt)) continue elt = eltInSearchPath - if elt[-4:] != ".hdf": - if elt[-3:] == ".py" or isDriver: + if file_extension != ".hdf": + if file_extension == ".py" or isDriver: currentScript = os.path.abspath(elt) elif os.path.isfile(elt+".py"): currentScript = os.path.abspath(elt+".py") @@ -244,6 +245,7 @@ def getScriptsAndArgs(args=None, searchPathList=None): scriptArgs.append(ScriptAndArgs(script=currentKey)) callPython = False elif currentScript: + script_extension = os.path.splitext(currentScript)[-1] if isDriver: currentKey = currentScript scriptArgs.append(ScriptAndArgs(script=currentKey)) @@ -264,7 +266,7 @@ def getScriptsAndArgs(args=None, searchPathList=None): fn.close() except: pass - if not ispython and currentScript[-3:] == ".py": + if not ispython and script_extension == ".py": currentKey = "@PYTHONBIN@ "+currentScript else: currentKey = currentScript diff --git a/bin/setenv.py b/bin/setenv.py index 4d83b489d..d699fae27 100755 --- a/bin/setenv.py +++ b/bin/setenv.py @@ -88,18 +88,9 @@ def get_config(silent=False, exeName=None): # read args from launch configure xml file and command line options - #*** Test additional option - #*** import optparse - #*** help_str = "Test options addition." - #*** o_j = optparse.Option("-j", "--join", action="store_true", dest="join", help=help_str) - import launchConfigureParser args = launchConfigureParser.get_env(exeName=exeName) - #*** Test additional option - #*** args = launchConfigureParser.get_env([o_j]) - #*** if args.has_key("join"): print(args["join"]) - # Check variables _ROOT_DIR # and set list of used modules (without KERNEL) diff --git a/salome_adm/prepare_generating_doc.py b/salome_adm/prepare_generating_doc.py index b818d7af7..5dec70e4b 100755 --- a/salome_adm/prepare_generating_doc.py +++ b/salome_adm/prepare_generating_doc.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # Copyright (C) 2007-2016 CEA/DEN, EDF R&D, OPEN CASCADE # # This library is free software; you can redistribute it and/or @@ -32,16 +32,16 @@ # Current the script does: # 1. remove Python documentation in triple double quotes (like """some_comments""") # -# Usage: prepare_generating_doc.py [-o ] +# Usage: prepare_generating_doc.py [-o ] # # If is not specified, it is generated in the current directory. # -################################################################################# +############################################################################### -import os, sys, re +import os, sys def main(input_file, output_file = None): - + # open input file try: infile = open(input_file, 'rb') @@ -50,7 +50,7 @@ def main(input_file, output_file = None): pass if not output_file: output_file = os.path.basename(input_file) - + # open output file try: outfile = open(output_file, 'wb') @@ -92,14 +92,13 @@ def main(input_file, output_file = None): pass if __name__ == "__main__": - import optparse - parser = optparse.OptionParser(usage="%prog [options] input_file") + import argparse + parser = argparse.ArgumentParser() h = "Output file (if not specified, generated in the current directory)" - parser.add_option("-o", "--output", dest="output", - action="store", default=None, metavar="file", - help=h) - (options, args) = parser.parse_args() - - if len( args ) < 1: sys.exit("Input file is not specified") - main( args[0], options.output ) + parser.add_argument("-o", "--output", dest="output", + action="store", default=None, metavar="file", + help=h) + parser.add_argument('input_file') + args = parser.parse_args() + main( args.input_file, args.output ) pass diff --git a/src/AppQuickStart/app-quickstart.py b/src/AppQuickStart/app-quickstart.py index 77eaaff34..1a3fde918 100755 --- a/src/AppQuickStart/app-quickstart.py +++ b/src/AppQuickStart/app-quickstart.py @@ -21,55 +21,50 @@ import os import shutil -import optparse +import argparse # Options of this script def profileQuickStartParser() : - parser = optparse.OptionParser( usage = "usage: python app-quickstart.py [options]" ) + parser = argparse.ArgumentParser( usage = "usage: python app-quickstart.py [options]" ) - parser.add_option('-p', + parser.add_argument('-p', "--prefix", metavar="", - type="string", action="store", dest="prefix", default='.', help="Where the application's sources will be generated. [Default : '.']") - parser.add_option('-m', + parser.add_argument('-m', "--modules", metavar="", - type="string", action="store", dest="modules", default='KERNEL,GUI', help="List of the application's modules. [Default : KERNEL,GUI]") - parser.add_option('-n', + parser.add_argument('-n', "--name", - type="string", action="store", dest="name", help="Name of the application") - parser.add_option('-v', + parser.add_argument('-v', "--version", - type="string", action="store", dest="version", default='1.0', help="Version of the application. [Default : 1.0]") - parser.add_option('-s', + parser.add_argument('-s', "--slogan", - type="string", action="store", dest="slogan", default='', help="Slogan of the application.") - parser.add_option('-f', + parser.add_argument('-f', "--force", action="store_true", dest="force", @@ -85,8 +80,14 @@ def profileGenerateSplash( resources_dir, appname, version, subtext ): import ImageDraw import ImageFont - uname = str(appname, 'UTF-8') - uversion = str(version, 'UTF-8') + if isinstance(appname, bytes): + uname = str(appname, 'UTF-8') + else: + uname = appname + if isinstance(version, bytes): + uversion = str(version, 'UTF-8') + else: + uversion = version # fonts fontbig = ImageFont.truetype( os.path.join( resources_dir, 'Anita semi square.ttf' ), 64) @@ -98,7 +99,7 @@ def profileGenerateSplash( resources_dir, appname, version, subtext ): nbcar = len(uname) width = 600 if nbcar > 12: - width = min( width*nbcar/12, 1024) #a little more + width = min( width*nbcar//12, 1024) #a little more height = 300 borderX = 30 #50 borderY = 3 #30 @@ -143,7 +144,10 @@ def profileGenerateLogo( appname, font ): import Image import ImageDraw - uname = str(appname, 'UTF-8') + if isinstance(appname, bytes): + uname = str(appname, 'UTF-8') + else: + uname = appname # evaluate size before deleting draw im = Image.new( "RGBA", (1, 1), (0, 0, 0, 0) ) @@ -157,28 +161,42 @@ def profileGenerateLogo( appname, font ): del draw return im - + +# Check if filename is a binary file +def is_binary(filename): + """ returns True if filename is a binary file + (from https://stackoverflow.com/a/7392391/2531279) + """ + textchars = bytearray({7,8,9,10,12,13,27} | set(range(0x20, 0x100)) - {0x7f}) + with open(filename, 'rb') as f: + s = f.read(512) + return bool(s.translate(None, textchars)) + + #Replace strings in the template -def profileReplaceStrings( src, dst, options ) : - with open( dst, "wt" ) as fout: - with open( src, "rt" ) as fin: +def profileReplaceStrings( src, dst, args) : + if is_binary(src): + shutil.copyfile(src, dst) + else: + with open( dst, "w") as fout, \ + open( src, "r") as fin: for line in fin: - if options.modules == '_NO_' and '[LIST_OF_MODULES]' in line: + if args.modules == '_NO_' and '[LIST_OF_MODULES]' in line: line = '' - l = line.replace( '[LIST_OF_MODULES]', options.modules ) - l = l.replace( '[VERSION]', options.version ) - l = l.replace( '[SLOGAN]', options.slogan ) - l = l.replace( '[NAME_OF_APPLICATION]', options.name.upper() ) - l = l.replace( '[Name_of_Application]', options.name ) - l = l.replace( '(name_of_application)', options.name.lower() ) + l = line.replace( '[LIST_OF_MODULES]', args.modules ) + l = l.replace( '[VERSION]', args.version ) + l = l.replace( '[SLOGAN]', args.slogan ) + l = l.replace( '[NAME_OF_APPLICATION]', args.name.upper() ) + l = l.replace( '[Name_of_Application]', args.name ) + l = l.replace( '(name_of_application)', args.name.lower() ) fout.write( l ) #Generation of a template profile sources -def profileGenerateSources( options, args ) : +def profileGenerateSources( args ) : #Set name of several directories - app_dir = options.prefix + app_dir = args.prefix app_resources_dir = os.path.join( app_dir, "resources" ) kernel_root_dir = os.environ["KERNEL_ROOT_DIR"] bin_salome_dir = os.path.join( kernel_root_dir, "bin", "salome" ) @@ -187,7 +205,7 @@ def profileGenerateSources( options, args ) : #Check if the directory of the sources already exists and delete it if os.path.exists( app_dir ) : - if not options.force : + if not args.force : print("Directory %s already exists." %app_dir) print("Use option --force to overwrite it.") return @@ -201,7 +219,7 @@ def profileGenerateSources( options, args ) : for d in dirs : os.mkdir( os.path.join( dst_dir, d ) ) for f in files : - profileReplaceStrings( os.path.join( root, f ), os.path.join( dst_dir, f ), options ) + profileReplaceStrings( os.path.join( root, f ), os.path.join( dst_dir, f ), args) #Complete source directory contextFiles = [ "salomeContext.py", "salomeContextUtils.py", "parseConfigFile.py" ] @@ -227,15 +245,15 @@ def profileGenerateSources( options, args ) : font = ImageFont.truetype( os.path.join( kernel_resources_dir, "Anita semi square.ttf" ) , 18 ) #Generate and save logo - app_logo = profileGenerateLogo( options.name, font ) + app_logo = profileGenerateLogo( args.name, font ) app_logo.save( logo_destination, "PNG" ) #Generate and splash screen and about image - if options.slogan : - subtext = options.slogan + if args.slogan : + subtext = args.slogan else : subtext = "Powered by SALOME" - im = profileGenerateSplash( kernel_resources_dir, options.name, options.version, subtext ) + im = profileGenerateSplash( kernel_resources_dir, args.name, args.version, subtext ) im.save( splash_destination, "PNG" ) im.save( about_destination, "PNG" ) else : @@ -249,22 +267,22 @@ def profileGenerateSources( options, args ) : shutil.copy( about_name, splash_destination ) #End of script - print("Sources of %s were generated in %s." %( options.name, app_dir )) + print("Sources of %s were generated in %s." %( args.name, app_dir )) # ----------------------------------------------------------------------------- if __name__ == '__main__': - #Get options and args - (options, args) = profileQuickStartParser().parse_args() + #Get optional and positional args + args = profileQuickStartParser().parse_args() #Check name of the application - if not options.name : + if not args.name : raise RuntimeError( "A name must be given to the application. Please use option --name." ) #Check if the prefix's parent is a directory - if not os.path.isdir( os.path.dirname( options.prefix ) ) : - raise RuntimeError( "%s is not a directory." % os.path.dirname( options.prefix ) ) + if not os.path.isdir( os.path.dirname( args.prefix ) ) : + raise RuntimeError( "%s is not a directory." % os.path.dirname( args.prefix ) ) #Generate sources of the profile - profileGenerateSources( options, args ) + profileGenerateSources( args )