mirror of
https://github.com/python/cpython.git
synced 2025-09-15 21:26:04 +00:00
- Better commandline interface to BuildApplet, complete with options,
verbose output to the console, etc. - Allow Cocoa applets to be built with BuildApplet. No full testing has been done yet to ensure OS9 operation hasn't suffered.
This commit is contained in:
parent
2befa48926
commit
388fbf3d4a
3 changed files with 159 additions and 49 deletions
|
@ -17,9 +17,6 @@ import shutil
|
||||||
|
|
||||||
BuildError = "BuildError"
|
BuildError = "BuildError"
|
||||||
|
|
||||||
DEBUG=1
|
|
||||||
|
|
||||||
|
|
||||||
# .pyc file (and 'PYC ' resource magic number)
|
# .pyc file (and 'PYC ' resource magic number)
|
||||||
MAGIC = imp.get_magic()
|
MAGIC = imp.get_magic()
|
||||||
|
|
||||||
|
@ -70,13 +67,13 @@ def findtemplate_macho():
|
||||||
return '/'.join(execpath[:i])
|
return '/'.join(execpath[:i])
|
||||||
|
|
||||||
|
|
||||||
def process(template, filename, output, copy_codefragment):
|
def process(template, filename, destname, copy_codefragment,
|
||||||
|
rsrcname=None, others=[], raw=0, progress="default"):
|
||||||
|
|
||||||
if DEBUG:
|
if progress == "default":
|
||||||
progress = EasyDialogs.ProgressBar("Processing %s..."%os.path.split(filename)[1], 120)
|
progress = EasyDialogs.ProgressBar("Processing %s..."%os.path.split(filename)[1], 120)
|
||||||
progress.label("Compiling...")
|
progress.label("Compiling...")
|
||||||
else:
|
progress.inc(0)
|
||||||
progress = None
|
|
||||||
|
|
||||||
# Read the source and compile it
|
# Read the source and compile it
|
||||||
# (there's no point overwriting the destination if it has a syntax error)
|
# (there's no point overwriting the destination if it has a syntax error)
|
||||||
|
@ -89,34 +86,38 @@ def process(template, filename, output, copy_codefragment):
|
||||||
except (SyntaxError, EOFError):
|
except (SyntaxError, EOFError):
|
||||||
raise BuildError, "Syntax error in script %s" % `filename`
|
raise BuildError, "Syntax error in script %s" % `filename`
|
||||||
|
|
||||||
# Set the destination file name
|
# Set the destination file name. Note that basename
|
||||||
|
# does contain the whole filepath, only a .py is stripped.
|
||||||
|
|
||||||
if string.lower(filename[-3:]) == ".py":
|
if string.lower(filename[-3:]) == ".py":
|
||||||
destname = filename[:-3]
|
basename = filename[:-3]
|
||||||
rsrcname = destname + '.rsrc'
|
if MacOS.runtimemodel != 'macho' and not destname:
|
||||||
|
destname = basename
|
||||||
else:
|
else:
|
||||||
|
basename = filename
|
||||||
|
|
||||||
|
if not destname:
|
||||||
if MacOS.runtimemodel == 'macho':
|
if MacOS.runtimemodel == 'macho':
|
||||||
destname = filename + '.app'
|
destname = basename + '.app'
|
||||||
else:
|
else:
|
||||||
destname = filename + ".applet"
|
destname = basename + '.applet'
|
||||||
rsrcname = filename + '.rsrc'
|
if not rsrcname:
|
||||||
|
rsrcname = basename + '.rsrc'
|
||||||
if output:
|
|
||||||
destname = output
|
|
||||||
|
|
||||||
# Try removing the output file. This fails in MachO, but it should
|
# Try removing the output file. This fails in MachO, but it should
|
||||||
# do any harm.
|
# do any harm.
|
||||||
try:
|
try:
|
||||||
os.remove(destname)
|
os.remove(destname)
|
||||||
except os.error:
|
except os.error:
|
||||||
pass
|
pass
|
||||||
process_common(template, progress, code, rsrcname, destname, 0, copy_codefragment)
|
process_common(template, progress, code, rsrcname, destname, 0,
|
||||||
|
copy_codefragment, raw, others)
|
||||||
|
|
||||||
|
|
||||||
def update(template, filename, output):
|
def update(template, filename, output):
|
||||||
if MacOS.runtimemodel == 'macho':
|
if MacOS.runtimemodel == 'macho':
|
||||||
raise BuildError, "No updating yet for MachO applets"
|
raise BuildError, "No updating yet for MachO applets"
|
||||||
if DEBUG:
|
if progress:
|
||||||
progress = EasyDialogs.ProgressBar("Updating %s..."%os.path.split(filename)[1], 120)
|
progress = EasyDialogs.ProgressBar("Updating %s..."%os.path.split(filename)[1], 120)
|
||||||
else:
|
else:
|
||||||
progress = None
|
progress = None
|
||||||
|
@ -131,16 +132,20 @@ def update(template, filename, output):
|
||||||
process_common(template, progress, None, filename, output, 1, 1)
|
process_common(template, progress, None, filename, output, 1, 1)
|
||||||
|
|
||||||
|
|
||||||
def process_common(template, progress, code, rsrcname, destname, is_update, copy_codefragment):
|
def process_common(template, progress, code, rsrcname, destname, is_update,
|
||||||
|
copy_codefragment, raw=0, others=[]):
|
||||||
if MacOS.runtimemodel == 'macho':
|
if MacOS.runtimemodel == 'macho':
|
||||||
return process_common_macho(template, progress, code, rsrcname, destname, is_update)
|
return process_common_macho(template, progress, code, rsrcname, destname,
|
||||||
|
is_update, raw, others)
|
||||||
|
if others:
|
||||||
|
raise BuildError, "Extra files only allowed for MachoPython applets"
|
||||||
# Create FSSpecs for the various files
|
# Create FSSpecs for the various files
|
||||||
template_fss = macfs.FSSpec(template)
|
template_fss = macfs.FSSpec(template)
|
||||||
template_fss, d1, d2 = macfs.ResolveAliasFile(template_fss)
|
template_fss, d1, d2 = macfs.ResolveAliasFile(template_fss)
|
||||||
dest_fss = macfs.FSSpec(destname)
|
dest_fss = macfs.FSSpec(destname)
|
||||||
|
|
||||||
# Copy data (not resources, yet) from the template
|
# Copy data (not resources, yet) from the template
|
||||||
if DEBUG:
|
if progress:
|
||||||
progress.label("Copy data fork...")
|
progress.label("Copy data fork...")
|
||||||
progress.set(10)
|
progress.set(10)
|
||||||
|
|
||||||
|
@ -157,7 +162,7 @@ def process_common(template, progress, code, rsrcname, destname, is_update, copy
|
||||||
|
|
||||||
# Open the output resource fork
|
# Open the output resource fork
|
||||||
|
|
||||||
if DEBUG:
|
if progress:
|
||||||
progress.label("Copy resources...")
|
progress.label("Copy resources...")
|
||||||
progress.set(20)
|
progress.set(20)
|
||||||
try:
|
try:
|
||||||
|
@ -172,7 +177,7 @@ def process_common(template, progress, code, rsrcname, destname, is_update, copy
|
||||||
input = Res.FSpOpenResFile(rsrcname, READ)
|
input = Res.FSpOpenResFile(rsrcname, READ)
|
||||||
except (MacOS.Error, ValueError):
|
except (MacOS.Error, ValueError):
|
||||||
pass
|
pass
|
||||||
if DEBUG:
|
if progress:
|
||||||
progress.inc(50)
|
progress.inc(50)
|
||||||
else:
|
else:
|
||||||
if is_update:
|
if is_update:
|
||||||
|
@ -222,7 +227,7 @@ def process_common(template, progress, code, rsrcname, destname, is_update, copy
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Create the raw data for the resource from the code object
|
# Create the raw data for the resource from the code object
|
||||||
if DEBUG:
|
if progress:
|
||||||
progress.label("Write PYC resource...")
|
progress.label("Write PYC resource...")
|
||||||
progress.set(120)
|
progress.set(120)
|
||||||
|
|
||||||
|
@ -256,10 +261,11 @@ def process_common(template, progress, code, rsrcname, destname, is_update, copy
|
||||||
dest_fss.SetFInfo(dest_finfo)
|
dest_fss.SetFInfo(dest_finfo)
|
||||||
|
|
||||||
macostools.touched(dest_fss)
|
macostools.touched(dest_fss)
|
||||||
if DEBUG:
|
if progress:
|
||||||
progress.label("Done.")
|
progress.label("Done.")
|
||||||
|
progress.inc(0)
|
||||||
|
|
||||||
def process_common_macho(template, progress, code, rsrcname, destname, is_update):
|
def process_common_macho(template, progress, code, rsrcname, destname, is_update, raw=0, others=[]):
|
||||||
# First make sure the name ends in ".app"
|
# First make sure the name ends in ".app"
|
||||||
if destname[-4:] != '.app':
|
if destname[-4:] != '.app':
|
||||||
destname = destname + '.app'
|
destname = destname + '.app'
|
||||||
|
@ -286,14 +292,17 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
|
||||||
"Contents/Resources/English.lproj/InfoPlist.strings",
|
"Contents/Resources/English.lproj/InfoPlist.strings",
|
||||||
"Contents/Resources/python.rsrc",
|
"Contents/Resources/python.rsrc",
|
||||||
]
|
]
|
||||||
copyapptree(template, destname, exceptlist)
|
copyapptree(template, destname, exceptlist, progress)
|
||||||
# Now either use the .plist file or the default
|
# Now either use the .plist file or the default
|
||||||
|
if progress:
|
||||||
|
progress.label('Create info.plist')
|
||||||
|
progress.inc(0)
|
||||||
if plistname:
|
if plistname:
|
||||||
shutil.copy2(plistname, os.path.join(destname, 'Contents/Info.plist'))
|
shutil.copy2(plistname, os.path.join(destname, 'Contents', 'Info.plist'))
|
||||||
if icnsname:
|
if icnsname:
|
||||||
icnsdest = os.path.split(icnsname)[1]
|
icnsdest = os.path.split(icnsname)[1]
|
||||||
icnsdest = os.path.join(destname,
|
icnsdest = os.path.join(destname,
|
||||||
os.path.join('Contents/Resources', icnsdest))
|
os.path.join('Contents', 'Resources', icnsdest))
|
||||||
shutil.copy2(icnsname, icnsdest)
|
shutil.copy2(icnsname, icnsdest)
|
||||||
# XXXX Wrong. This should be parsed from plist file. Also a big hack:-)
|
# XXXX Wrong. This should be parsed from plist file. Also a big hack:-)
|
||||||
if shortname == 'PythonIDE':
|
if shortname == 'PythonIDE':
|
||||||
|
@ -302,31 +311,44 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
|
||||||
ownertype = 'PytA'
|
ownertype = 'PytA'
|
||||||
# XXXX Should copy .icns file
|
# XXXX Should copy .icns file
|
||||||
else:
|
else:
|
||||||
plistname = os.path.join(template, 'Contents/Resources/Applet-Info.plist')
|
cocoainfo = ''
|
||||||
|
for o in others:
|
||||||
|
if o[-4:] == '.nib':
|
||||||
|
nibname = os.path.split(o)[1][:-4]
|
||||||
|
cocoainfo = """
|
||||||
|
<key>NSMainNibFile</key>
|
||||||
|
<string>%s</string>
|
||||||
|
<key>NSPrincipalClass</key>
|
||||||
|
<string>NSApplication</string>""" % nibname
|
||||||
|
|
||||||
|
|
||||||
|
plistname = os.path.join(template, 'Contents', 'Resources', 'Applet-Info.plist')
|
||||||
plistdata = open(plistname).read()
|
plistdata = open(plistname).read()
|
||||||
plistdata = plistdata % {'appletname':shortname}
|
plistdata = plistdata % {'appletname':shortname, 'cocoainfo':cocoainfo}
|
||||||
ofp = open(os.path.join(destname, 'Contents/Info.plist'), 'w')
|
ofp = open(os.path.join(destname, 'Contents', 'Info.plist'), 'w')
|
||||||
ofp.write(plistdata)
|
ofp.write(plistdata)
|
||||||
ofp.close()
|
ofp.close()
|
||||||
ownertype = 'PytA'
|
ownertype = 'PytA'
|
||||||
# Create the PkgInfo file
|
# Create the PkgInfo file
|
||||||
ofp = open(os.path.join(destname, 'Contents/PkgInfo'), 'wb')
|
if progress:
|
||||||
|
progress.label('Create PkgInfo')
|
||||||
|
progress.inc(0)
|
||||||
|
ofp = open(os.path.join(destname, 'Contents', 'PkgInfo'), 'wb')
|
||||||
ofp.write('APPL' + ownertype)
|
ofp.write('APPL' + ownertype)
|
||||||
ofp.close()
|
ofp.close()
|
||||||
|
|
||||||
|
|
||||||
if DEBUG:
|
if progress:
|
||||||
progress.label("Copy resources...")
|
progress.label("Copy resources...")
|
||||||
progress.set(20)
|
progress.set(20)
|
||||||
resfilename = '%s.rsrc' % shortname
|
resfilename = '%s.rsrc' % shortname
|
||||||
respartialpathname = 'Contents/Resources/%s' % resfilename
|
|
||||||
try:
|
try:
|
||||||
output = Res.FSOpenResourceFile(
|
output = Res.FSOpenResourceFile(
|
||||||
os.path.join(destname, respartialpathname),
|
os.path.join(destname, 'Contents', 'Resources', resfilename),
|
||||||
u'', WRITE)
|
u'', WRITE)
|
||||||
except MacOS.Error:
|
except MacOS.Error:
|
||||||
fsr, dummy = Res.FSCreateResourceFile(
|
fsr, dummy = Res.FSCreateResourceFile(
|
||||||
os.path.join(destname, 'Contents/Resources'),
|
os.path.join(destname, 'Contents', 'Resources'),
|
||||||
unicode(resfilename), '')
|
unicode(resfilename), '')
|
||||||
output = Res.FSOpenResourceFile(fsr, u'', WRITE)
|
output = Res.FSOpenResourceFile(fsr, u'', WRITE)
|
||||||
|
|
||||||
|
@ -336,7 +358,7 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
|
||||||
input = macresource.open_pathname(rsrcname)
|
input = macresource.open_pathname(rsrcname)
|
||||||
except (MacOS.Error, ValueError):
|
except (MacOS.Error, ValueError):
|
||||||
pass
|
pass
|
||||||
if DEBUG:
|
if progress:
|
||||||
progress.inc(50)
|
progress.inc(50)
|
||||||
else:
|
else:
|
||||||
typesfound, ownertype = copyres(input, output, [], 0, progress)
|
typesfound, ownertype = copyres(input, output, [], 0, progress)
|
||||||
|
@ -355,8 +377,12 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
|
||||||
# Copy the resources from the template
|
# Copy the resources from the template
|
||||||
|
|
||||||
input = Res.FSOpenResourceFile(
|
input = Res.FSOpenResourceFile(
|
||||||
os.path.join(template, 'Contents/Resources/python.rsrc'), u'', READ)
|
os.path.join(template, 'Contents', 'Resources', 'python.rsrc'), u'', READ)
|
||||||
dummy, tmplowner = copyres(input, output, skiptypes, 1, progress)
|
if progress:
|
||||||
|
progress.label("Copy standard resources...")
|
||||||
|
progress.inc(0)
|
||||||
|
## dummy, tmplowner = copyres(input, output, skiptypes, 1, progress)
|
||||||
|
dummy, tmplowner = copyres(input, output, skiptypes, 1, None)
|
||||||
|
|
||||||
Res.CloseResFile(input)
|
Res.CloseResFile(input)
|
||||||
## if ownertype == None:
|
## if ownertype == None:
|
||||||
|
@ -366,8 +392,29 @@ def process_common_macho(template, progress, code, rsrcname, destname, is_update
|
||||||
Res.CloseResFile(output)
|
Res.CloseResFile(output)
|
||||||
|
|
||||||
if code:
|
if code:
|
||||||
outputfilename = os.path.join(destname, 'Contents/Resources/__main__.pyc')
|
if raw:
|
||||||
|
pycname = '__rawmain__.pyc'
|
||||||
|
else:
|
||||||
|
pycname = '__main__.pyc'
|
||||||
|
outputfilename = os.path.join(destname, 'Contents', 'Resources', pycname)
|
||||||
|
if progress:
|
||||||
|
progress.label('Creating '+pycname)
|
||||||
|
progress.inc(0)
|
||||||
writepycfile(code, outputfilename)
|
writepycfile(code, outputfilename)
|
||||||
|
# Copy other files the user asked for
|
||||||
|
for osrc in others:
|
||||||
|
oname = os.path.split(osrc)[1]
|
||||||
|
odst = os.path.join(destname, 'Contents', 'Resources', oname)
|
||||||
|
if progress:
|
||||||
|
progress.label('Copy ' + oname)
|
||||||
|
progress.inc(0)
|
||||||
|
if os.path.isdir(osrc):
|
||||||
|
copyapptree(osrc, odst)
|
||||||
|
else:
|
||||||
|
shutil.copy2(osrc, odst)
|
||||||
|
if progress:
|
||||||
|
progress.label('Done.')
|
||||||
|
progress.inc(0)
|
||||||
|
|
||||||
## macostools.touched(dest_fss)
|
## macostools.touched(dest_fss)
|
||||||
|
|
||||||
|
@ -400,7 +447,7 @@ def copyres(input, output, skiptypes, skipowner, progress=None):
|
||||||
ctor = type
|
ctor = type
|
||||||
size = res.size
|
size = res.size
|
||||||
attrs = res.GetResAttrs()
|
attrs = res.GetResAttrs()
|
||||||
if DEBUG and progress:
|
if progress:
|
||||||
progress.label("Copy %s %d %s"%(type, id, name))
|
progress.label("Copy %s %d %s"%(type, id, name))
|
||||||
progress.inc(progress_cur_inc)
|
progress.inc(progress_cur_inc)
|
||||||
res.LoadResource()
|
res.LoadResource()
|
||||||
|
@ -411,8 +458,9 @@ def copyres(input, output, skiptypes, skipowner, progress=None):
|
||||||
except MacOS.Error:
|
except MacOS.Error:
|
||||||
res2 = None
|
res2 = None
|
||||||
if res2:
|
if res2:
|
||||||
if DEBUG and progress:
|
if progress:
|
||||||
progress.label("Overwrite %s %d %s"%(type, id, name))
|
progress.label("Overwrite %s %d %s"%(type, id, name))
|
||||||
|
progress.inc(0)
|
||||||
res2.RemoveResource()
|
res2.RemoveResource()
|
||||||
res.AddResource(type, id, name)
|
res.AddResource(type, id, name)
|
||||||
res.WriteResource()
|
res.WriteResource()
|
||||||
|
@ -421,7 +469,7 @@ def copyres(input, output, skiptypes, skipowner, progress=None):
|
||||||
Res.UseResFile(input)
|
Res.UseResFile(input)
|
||||||
return alltypes, ctor
|
return alltypes, ctor
|
||||||
|
|
||||||
def copyapptree(srctree, dsttree, exceptlist=[]):
|
def copyapptree(srctree, dsttree, exceptlist=[], progress=None):
|
||||||
names = []
|
names = []
|
||||||
if os.path.exists(dsttree):
|
if os.path.exists(dsttree):
|
||||||
shutil.rmtree(dsttree)
|
shutil.rmtree(dsttree)
|
||||||
|
@ -443,6 +491,9 @@ def copyapptree(srctree, dsttree, exceptlist=[]):
|
||||||
if os.path.isdir(srcpath):
|
if os.path.isdir(srcpath):
|
||||||
os.mkdir(dstpath)
|
os.mkdir(dstpath)
|
||||||
else:
|
else:
|
||||||
|
if progress:
|
||||||
|
progress.label('Copy '+this)
|
||||||
|
progress.inc(0)
|
||||||
shutil.copy2(srcpath, dstpath)
|
shutil.copy2(srcpath, dstpath)
|
||||||
|
|
||||||
def writepycfile(codeobject, cfile):
|
def writepycfile(codeobject, cfile):
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
|
|
||||||
<key>CFBundleGetInfoString</key>
|
<key>CFBundleGetInfoString</key>
|
||||||
<string>%(appletname)s, a Python applet</string>
|
<string>%(appletname)s, a Python applet</string>
|
||||||
|
|
||||||
|
%(cocoainfo)s
|
||||||
|
|
||||||
<key>CFBundleIconFile</key>
|
<key>CFBundleIconFile</key>
|
||||||
<string>PythonApplet.icns</string>
|
<string>PythonApplet.icns</string>
|
||||||
|
|
|
@ -15,7 +15,7 @@ import macfs
|
||||||
import MacOS
|
import MacOS
|
||||||
import EasyDialogs
|
import EasyDialogs
|
||||||
import buildtools
|
import buildtools
|
||||||
|
import getopt
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
try:
|
try:
|
||||||
|
@ -54,14 +54,71 @@ def buildapplet():
|
||||||
buildtools.process(template, filename, dstfilename, 1)
|
buildtools.process(template, filename, dstfilename, 1)
|
||||||
else:
|
else:
|
||||||
|
|
||||||
|
SHORTOPTS = "o:r:ne:v?"
|
||||||
|
LONGOPTS=("output=", "resource=", "noargv", "extra=", "verbose", "help")
|
||||||
|
try:
|
||||||
|
options, args = getopt.getopt(sys.argv[1:], SHORTOPTS, LONGOPTS)
|
||||||
|
except getopt.error:
|
||||||
|
usage()
|
||||||
|
if options and len(args) > 1:
|
||||||
|
sys.stderr.write("Cannot use options when specifying multiple input files")
|
||||||
|
sys.exit(1)
|
||||||
|
dstfilename = None
|
||||||
|
rsrcfilename = None
|
||||||
|
raw = 0
|
||||||
|
extras = []
|
||||||
|
verbose = None
|
||||||
|
for opt, arg in options:
|
||||||
|
if opt in ('-o', '--output'):
|
||||||
|
dstfilename = arg
|
||||||
|
elif opt in ('-r', '--resource'):
|
||||||
|
rsrcfilename = arg
|
||||||
|
elif opt in ('-n', '--noargv'):
|
||||||
|
raw = 1
|
||||||
|
elif opt in ('-e', '--extra'):
|
||||||
|
extras.append(arg)
|
||||||
|
elif opt in ('-v', '--verbose'):
|
||||||
|
verbose = Verbose()
|
||||||
|
elif opt in ('-?', '--help'):
|
||||||
|
usage()
|
||||||
# Loop over all files to be processed
|
# Loop over all files to be processed
|
||||||
for filename in sys.argv[1:]:
|
for filename in args:
|
||||||
cr, tp = MacOS.GetCreatorAndType(filename)
|
cr, tp = MacOS.GetCreatorAndType(filename)
|
||||||
if tp == 'APPL':
|
if tp == 'APPL':
|
||||||
buildtools.update(template, filename, '')
|
buildtools.update(template, filename, dstfilename)
|
||||||
else:
|
else:
|
||||||
buildtools.process(template, filename, '', 1)
|
buildtools.process(template, filename, dstfilename, 1,
|
||||||
|
rsrcname=rsrcfilename, others=extras, raw=raw, progress=verbose)
|
||||||
|
|
||||||
|
def usage():
|
||||||
|
print "BuildApplet creates an application from a Python source file"
|
||||||
|
print "Usage:"
|
||||||
|
print " BuildApplet interactive, single file, no options"
|
||||||
|
print " BuildApplet src1.py src2.py ... non-interactive multiple file"
|
||||||
|
print " BuildApplet [options] src.py non-interactive single file"
|
||||||
|
print "Options:"
|
||||||
|
print " --output o Output file; default based on source filename, short -o"
|
||||||
|
print " --resource r Resource file; default based on source filename, short -r"
|
||||||
|
print " --noargv Build applet without drag-and-drop sys.argv emulation, short -n, OSX only"
|
||||||
|
print " --extra f Extra file to put in .app bundle, short -e, OSX only"
|
||||||
|
print " --verbose Verbose, short -v"
|
||||||
|
print " --help This message, short -?"
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
class Verbose:
|
||||||
|
"""This class mimics EasyDialogs.ProgressBar but prints to stderr"""
|
||||||
|
def __init__(self, *args):
|
||||||
|
if args and args[0]:
|
||||||
|
self.label(args[0])
|
||||||
|
|
||||||
|
def set(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def inc(self, *args):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def label(self, str):
|
||||||
|
sys.stderr.write(str+'\n')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue