From 2d995e07e2b02f89ca0309716ca609655f56e8e8 Mon Sep 17 00:00:00 2001 From: Christian Van Wambeke Date: Fri, 11 Jan 2019 11:48:41 +0100 Subject: [PATCH] better src/callerName.py --- commands/config.py | 2 +- sat | 2 +- src/ElementTree.py | 2 +- src/callerName.py | 202 +++++++++++++++++++++++------ src/internal_config/distrib.pyconf | 134 +++++++++---------- src/system.py | 27 ++-- 6 files changed, 236 insertions(+), 133 deletions(-) diff --git a/commands/config.py b/commands/config.py index 15f7ce6..31a522c 100644 --- a/commands/config.py +++ b/commands/config.py @@ -74,7 +74,7 @@ def osJoin(*args): res = os.path.realpath(os.path.join(*args)) if verbose: if True: # ".pyconf" in res: - logger.info("osJoin %-80s in %s" % (res, CALN.caller_name())) + logger.info("osJoin %-80s in %s" % (res, CALN.caller_name(1))) return res class ConfigOpener: diff --git a/sat b/sat index 02c2b57..14b9a86 100755 --- a/sat +++ b/sat @@ -44,7 +44,7 @@ import src.debug as DBG # Easy print stderr (for DEBUG only) logger = LOG.getDefaultLogger() -DBG.write("Python version", sys.version) +DBG.write("Python version", sys.version, DBG.isDeveloper()) ################################# # MAIN diff --git a/src/ElementTree.py b/src/ElementTree.py index 1cfe8ce..8b1b92b 100644 --- a/src/ElementTree.py +++ b/src/ElementTree.py @@ -13,7 +13,7 @@ _versionPython = sys.version_info[0] if _versionPython < 3: # python2 previous historic mode import src.ElementTreePython2 as etree - DBG.write("ElementTree Python2", etree.__file__) + DBG.write("ElementTree Python2", etree.__file__, DBG.isDeveloper()) tostring = etree.tostring else: diff --git a/src/callerName.py b/src/callerName.py index 6c4140c..9fd0308 100644 --- a/src/callerName.py +++ b/src/callerName.py @@ -5,47 +5,169 @@ # Public Domain, i.e. feel free to copy/paste # Considered a hack in Python 2 +import os +import sys import inspect import logging -import sys +import pprint as PP + + +############################################################################## +def caller_name_simple(skip=1): + """ + Get a name of a caller in the format module.class.method + + 'skip' specifies how many levels of stack to skip while getting caller + name. skip=1 means 'who calls me', skip=2 'who calls my caller' etc. + + An empty string is returned if skipped levels exceed stack height + """ + + def stack_(frame): + framelist = [] + while frame: + framelist.append(frame) + frame = frame.f_back + return framelist + + stack = stack_(sys._getframe(1)) + start = 0 + skip + if len(stack) < start + 1: + return '' + parentframe = stack[start] + + name = [] + module = inspect.getmodule(parentframe) + # `modname` can be None when frame is executed directly in console + # TODO(techtonik): consider using __main__ + if module: + name.append(module.__name__) + # detect classname + if 'self' in parentframe.f_locals: + # I don't know any way to detect call from the object method + # XXX: there seems to be no way to detect static method call - it will + # be just a function call + name.append(parentframe.f_locals['self'].__class__.__name__) + codename = parentframe.f_code.co_name + + fr = inspect.currentframe().f_back + for i in range(skip): # no more 20 for precaution + fr = fr.f_back + if fr is None: + break + lineno = fr.f_lineno + + if codename != '': # top level usually + name.append(codename) + + name[-1] += "[%s]" % str(lineno) # function or a method + del parentframe + return ".".join(name) + + +############################################################################## +def caller_name_stack(skip=1): + """ + Get a name of a caller in the format module[no].class[no].method[no] + where [no] is line nunber in source file(s) + + 'skip' specifies how many levels of stack to skip while getting caller + name. skip=1 means 'who calls me', skip=2 'who calls my caller' etc. + + An empty string is returned if skipped levels exceed stack height + """ + def stack_(frame): + framelist = [] + while frame: + framelist.append(frame) + frame = frame.f_back + return framelist + + stack = stack_(sys._getframe(1)) + start = 0 + skip + if len(stack) < start + 1: + return '' + parentframe = stack[start] + + name = [] + module = inspect.getmodule(parentframe) + # `modname` can be None when frame is executed directly in console + # TODO(techtonik): consider using __main__ + if module: + name.append(module.__name__) + # detect classname + if 'self' in parentframe.f_locals: + # I don't know any way to detect call from the object method + # XXX: there seems to be no way to detect static method call - it will + # be just a function call + name.append(parentframe.f_locals['self'].__class__.__name__) + codename = parentframe.f_code.co_name + + fr = inspect.currentframe().f_back + lineno = [fr.f_lineno] + for i in range(20): # no more 20 for precaution + fr = fr.f_back + if fr is None: + break + #print("*** frame locals %s" % str(fr.f_locals.keys())) + #print("*** frame globals %s" % str(fr.f_globals.keys())) + try: + namesrc = fr.f_globals["__name__"] + if namesrc == "__main__": + namesrc = os.path.basename(fr.f_globals["__file__"]) + lineno.insert(0, (namesrc + "[%s]" % fr.f_lineno)) + except: + lineno.insert(0, ("??", fr.f_lineno)) + + if codename != '': # top level usually + name.append(codename) # function or a method + + #print("lineno", lineno) + #print("name", name) + + name[-1] += " // STACK: %s" % " ".join(lineno[0:-1]) + + del parentframe + return ".".join(name) + + +############################################################################## +def example_of_use(toCall): + """ + example of use caller_name_simple, or else + """ + class Dummy: + def one_method(self): + print("4- call in class %s" % toCall(0)) + + print("1- call in %s" % toCall(0)) # output from main to here + print("2- call in %s" % toCall(0)) + print("3- call in %s" % toCall(1)) # output from main to caller + tmp = Dummy() + tmp.one_method() + + +############################################################################## +# main as an example +############################################################################## +if __name__ == "__main__": + example_of_use(caller_name_simple) + example_of_use(caller_name_stack) + +""" +example of output + +1- call in __main__.example_of_use[143] +2- call in __main__.example_of_use[144] +3- call in __main__[154] +4- call in class __main__.Dummy.one_method[141] +1- call in __main__.example_of_use // STACK: callerName.py[155] +2- call in __main__.example_of_use // STACK: callerName.py[155] +3- call in __main__ // STACK: callerName.py[155] +4- call in class __main__.Dummy.one_method // STACK: callerName.py[155] callerName.py[147] +""" -def caller_name(skip=1): - """Get a name of a caller in the format module.class.method - - `skip` specifies how many levels of stack to skip while getting caller - name. skip=1 means "who calls me", skip=2 "who calls my caller" etc. - - An empty string is returned if skipped levels exceed stack height - """ - def stack_(frame): - framelist = [] - while frame: - framelist.append(frame) - frame = frame.f_back - return framelist - - stack = stack_(sys._getframe(1)) - start = 0 + skip - if len(stack) < start + 1: - return '' - parentframe = stack[start] - - name = [] - module = inspect.getmodule(parentframe) - # `modname` can be None when frame is executed directly in console - # TODO(techtonik): consider using __main__ - if module: - name.append(module.__name__) - # detect classname - if 'self' in parentframe.f_locals: - # I don't know any way to detect call from the object method - # XXX: there seems to be no way to detect static method call - it will - # be just a function call - name.append(parentframe.f_locals['self'].__class__.__name__) - codename = parentframe.f_code.co_name - lineno = inspect.currentframe().f_back.f_back.f_lineno - if codename != '': # top level usually - name.append(codename + "[%s]" % str(lineno)) # function or a method - del parentframe - return ".".join(name) \ No newline at end of file +# here default caller_name is user choice... +caller_name = caller_name_simple # not so verbose +# caller_name = caller_name_stack # more verbose, with stack diff --git a/src/internal_config/distrib.pyconf b/src/internal_config/distrib.pyconf index 50389e6..0e74962 100644 --- a/src/internal_config/distrib.pyconf +++ b/src/internal_config/distrib.pyconf @@ -6,17 +6,17 @@ # If no code is found an error will be raised. DISTRIBUTIONS : { - "bullxServer": "BS" - "CentOS": "CO" - "Debian": "DB" - "Fedora": "FD" - "LinuxMint": "MN" - "Mageia": "MG" - "MandrivaLinux": "MD" - "RedHatEnterpriseServer": "CO" - "RedHatEnterpriseWorkstation" : "CO" - "Ubuntu": "UB" - "openSUSE project":"OS" + "bullxServer": "BS" + "CentOS": "CO" + "Debian": "DB" + "Fedora": "FD" + "LinuxMint": "MN" + "Mageia": "MG" + "MandrivaLinux": "MD" + "RedHatEnterpriseServer": "CO" + "RedHatEnterpriseWorkstation" : "CO" + "Ubuntu": "UB" + "openSUSE project":"OS" } # versions substitution @@ -25,67 +25,57 @@ DISTRIBUTIONS : VERSIONS : { -# Do not do anything for the ubuntu machines (CEA dicision). -# + # Do not do anything for the ubuntu machines (CEA descision). - "DB": - { - "unstable": "sid" - "5.0": "05" - "4.0": "04" - "6.0.7" : "06" - "6.0.10": "06" - "7.1" : "07" - "7.11" : "07" - "7.2" : "07" - "7.3" : "07" - "7.5" : "07" - "8.1" : "08" - "8.2" : "08" - "8.3" : "08" - "8.4" : "08" - "8.5" : "08" - "8.6" : "08" - "8.7" : "08" - "8.8" : "08" - "9.1" : "09" - "9.2" : "09" - "9.3" : "09" - "9.4" : "09" - "9.5" : "09" - "9.6" : "09" - "9.7" : "09" - "9.8" : "09" - } - "MD": - { - "2008.0": "08" - "2010.0": "10" - "2010.1": "10" - "2010.2": "10" - "2007.1": "07" - "2006.0": "06" - "4" : "06" - } - "MG": - { - "3": "03" - "4": "04" - "5": "05" - "6": "06" - } - "CO": - { - "7.1.1503": "7" - "7.2.1511": "7" - "7.3.1611": "7" - "6.1" : "6" - "6.2" : "6" - "6.3" : "6" - "6.4" : "6" - "6.5" : "6" - "6.6" : "6" - "6.7" : "6" - } + "DB": + { + "unstable": "sid" + "5.0": "05" + "4.0": "04" + "6.0.7" : "06" + "6.0.10": "06" + "7.1" : "07" + "7.11" : "07" + "7.2" : "07" + "7.3" : "07" + "7.5" : "07" + "8.1" : "08" + "8.2" : "08" + "8.3" : "08" + "8.4" : "08" + "8.5" : "08" + "8.6" : "08" + "8.7" : "08" + } + "MD": + { + "2008.0": "08" + "2010.0": "10" + "2010.1": "10" + "2010.2": "10" + "2007.1": "07" + "2006.0": "06" + "4" : "06" + } + "MG": + { + "3": "03" + "4": "04" + "5": "05" + "6": "06" + } + "CO": + { + "7.1.1503": "7" + "7.2.1511": "7" + "7.3.1611": "7" + "6.1" : "6" + "6.2" : "6" + "6.3" : "6" + "6.4" : "6" + "6.5" : "6" + "6.6" : "6" + "6.7" : "6" + } } diff --git a/src/system.py b/src/system.py index bb1fc1a..6e7a788 100644 --- a/src/system.py +++ b/src/system.py @@ -97,32 +97,23 @@ git --git-dir=%(where_git)s --work-tree=%(where)s checkout %(tag)s DBG.write("cmd", cmd) - # git commands may fail sometimes for various raisons (big module, network troubles, tuleap maintenance) + # git commands may fail sometimes for various raisons + # (big module, network troubles, tuleap maintenance) # therefore we give several tries - i_try=0 - max_number_of_tries=3 - sleep_delay=30 # seconds + i_try = 0 + max_number_of_tries = 3 + sleep_delay = 30 # seconds while (True): - i_try+=1 + i_try += 1 rc = UTS.Popen(cmd, cwd=str(where.dir()), env=environment.environ.environ, logger=logger) if rc.isOk() or (i_try>=max_number_of_tries): - break - logger.write('\ngit command failed! Wait %d seconds and give an other try (%d/%d)\n' % (sleep_delay,i_try+1,max_number_of_tries), 3) + break + logger.write('\ngit command failed! Wait %d seconds and give an other try (%d/%d)\n' % \ + (sleep_delay, i_try + 1, max_number_of_tries), 3) time.sleep(sleep_delay) # wait a little return rc.isOk() - """ - res = subprocess.call(command, - cwd=str(where.dir()), - env=environment.environ.environ, - shell=True, - stdout=logger.logTxtFile, - stderr=subprocess.STDOUT) - return (res == 0) - """ - - def git_extract_sub_dir(from_what, tag, where, sub_dir, logger, environment=None): '''Extracts sources from a subtree sub_dir of a git repository. -- 2.39.2