Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Anders Blomdell
apa
Commits
7f5fa3fd
Commit
7f5fa3fd
authored
May 04, 2011
by
Anders Blomdell
Browse files
Improve code loading
parent
ff37baca
Changes
1
Hide whitespace changes
Inline
Side-by-side
apa
100755 → 100644
View file @
7f5fa3fd
...
...
@@ -2,12 +2,12 @@
"""
Anders Python Archiver
Copyright (C) 2004 Anders Blomdell <anders.blomdell@control.lth.se>
Copyright (C) 2004
-2009
Anders Blomdell <anders.blomdell@control.lth.se>
A small utility program to join a number of python modules
into a single executable python program.
http://www.control.lth.se/
~
andersb/software/apa
http://www.control.lth.se/
user/
andersb/software/apa
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
...
...
@@ -39,17 +39,15 @@ def getModuleName(s):
return
string
.
replace
(
m
.
group
(
1
),
"/"
,
"."
)
return
None
def
emitCode
(
f
,
module
,
name
,
filename
,
code
):
print
>>
sys
.
stderr
,
"EMIT:"
,
name
print
>>
f
,
'"%s" : ( "%s", "%s", """%s""")'
%
(
quote
(
module
),
quote
(
name
),
quote
(
filename
),
quote
(
code
))
def
emitCode
(
f
,
module
,
filename
,
code
):
print
>>
sys
.
stderr
,
"EMIT:"
,
module
print
>>
f
,
'"%s" : ( "%s", """%s""")'
%
(
quote
(
module
),
quote
(
filename
),
quote
(
code
))
def
quote
(
s
):
return
string
.
replace
(
string
.
replace
(
s
,
'
\\
'
,
'
\\\\
'
),
'"'
,
'
\\
"'
)
if
__name__
==
'__main__'
:
usage
=
"%prog [options] <main module> <additional modules>*"
optParser
=
optparse
.
OptionParser
(
usage
=
usage
)
...
...
@@ -59,6 +57,10 @@ if __name__ == '__main__':
optParser
.
add_option
(
'-o'
,
'--output'
,
action
=
'store'
,
help
=
'Name of archive'
)
optParser
.
add_option
(
'-s'
,
'--strip'
,
action
=
'append'
,
default
=
[],
help
=
'Strip this part from filenames'
)
(
options
,
args
)
=
optParser
.
parse_args
(
sys
.
argv
[
1
:])
if
options
.
documentation
:
...
...
@@ -68,10 +70,17 @@ if __name__ == '__main__':
# Read all python files
code
=
[]
for
filename
in
args
:
name
=
getModuleName
(
filename
)
archivename
=
filename
for
strip
in
options
.
strip
:
m
=
re
.
match
(
"^%s/*(.*)"
%
strip
,
filename
)
if
m
:
archivename
=
m
.
group
(
1
)
break
name
=
getModuleName
(
archivename
)
if
name
:
f
=
open
(
filename
)
code
.
append
((
name
,
fil
ename
,
f
.
read
()))
code
.
append
((
name
,
archiv
ename
,
f
.
read
()))
f
.
close
()
else
:
print
"Illegal filename '%s'"
%
filename
...
...
@@ -81,7 +90,7 @@ if __name__ == '__main__':
apa
=
file
(
options
.
output
,
'w'
)
else
:
apa
=
None
# Emit code
interpreter
=
code
[
0
][
2
].
splitlines
()[
0
]
if
interpreter
.
find
(
"python"
)
>=
0
:
...
...
@@ -98,7 +107,7 @@ if __name__ == '__main__':
for
(
n
,
f
,
c
)
in
code
[
1
:]:
print
>>
apa
,
" %-20s %s"
%
(
n
,
f
)
print
>>
apa
,
"""
Archive created by 'apa' (http://www.control.lth.se/
~
andersb/software/apa)
Archive created by 'apa' (http://www.control.lth.se/
user/
andersb/software/apa)
To extract as individual files:
...
...
@@ -111,82 +120,76 @@ To extract as individual files:
"""
print
>>
apa
,
"code = {"
(
n
,
f
,
c
)
=
code
[
0
]
emitCode
(
apa
,
'__apa__main__'
,
'__main__'
,
f
,
c
)
emitCode
(
apa
,
'__main__'
,
f
,
c
)
for
(
n
,
f
,
c
)
in
code
[
1
:]:
print
>>
apa
,
","
emitCode
(
apa
,
n
,
n
,
f
,
c
)
emitCode
(
apa
,
n
,
f
,
c
)
print
>>
apa
,
"}"
print
>>
apa
,
"""
import exceptions
import ihooks
import imp
import os
import os.path
import sys
import traceback
class
String
Importer
(ihooks.ModuleImporter, object)
:
class Importer:
\"\"\"
Loads modules from local code dictionary
\"\"\"
def __init__(self, code_dict):
super(StringImporter, self).__init__()
self.code_dict = code_dict;
self.loaded = {}
self.result = None
def import_it(self, partname, fqname, parent, force_load=0):
try:
# First shot, return part from parent module
return parent.__dict__[partname]
except (KeyError, AttributeError):
pass
def __init__(self, code):
self.code = code;
self.path = "<%s>" % str(self.__class__)
if not self.path in sys.path:
sys.path.insert(0, self.path)
def __call__(self, path):
if path == self.path:
return self
return None
def find_module(self, fullname):
try:
# Second shot, load it from already loaded code
return self.loaded[fqname]
except (KeyError, AttributeError):
pass
self.code[fullname]
return self
except:
return None
def load_module(self, fullname):
mod = sys.modules.setdefault(fullname, imp.new_module(fullname))
(filename, src) = self.code[fullname]
mod.__file__ = filename
mod.__loader__ = self
mod.__path__ = [ self.path ]
global BAD
BAD = None
try:
# Third shot, load it from code_dictionary
(name, filename, code) = self.code_dict[fqname]
module = self.loader.hooks.add_module(fqname)
self.loaded[fqname] = module
module.__name__ = name
module.__file__ = filename
try:
comp = compile(code, filename, 'exec')
exec comp in module.__dict__
except exceptions.SystemExit, e:
# Silently propagate exit
raise e
except Exception, e:
# print module.__file__
# print "StringLoading '%s' failed: %s [%s]" % (fqname,
# e, e.__class__)
traceback.print_exc()
raise exceptions.SystemExit(1)
if parent != None:
parent.__dict__[partname] = module
return module
except (KeyError, AttributeError), e:
pass
code = compile(src, "%s/%s" % (self.path, filename), 'exec')
exec code in mod.__dict__
except exceptions.SystemExit, e:
# Silently propagate exit
raise e
except Exception, e:
# Silently propagate other exceptions as well
BAD = sys.exc_info()
raise e
return mod
def is_package(self, fullname):
(filename, src) = self.code[fullname]
return True
def get_code(self, fullname):
(filename, src) = self.code[fullname]
code = compile(src, "%s/%s" % (self.path, filename), 'exec')
return code
def get_source(self, fullname):
(filename, src) = self.code[fullname]
return src
# Fourth shot, default loader
return ihooks.ModuleImporter.import_it(self, partname, fqname, parent, force_load)
def reload(self, module):
for (n, m) in self.loaded.iteritems():
if m is module:
(filename, code) = self.code_dict[n]
exec code in module.__dict__
return
return super(StringImporter, self).reload(module)
def get_filename(self, fullname):
(filename, src) = self.code[fullname]
return filename
def extract(dest='.'):
\"\"\"
Extracts archived files in dest directory ('.' is default)
\"\"\"
for (m, (n, f, c)) in code.iteritems():
import os
import os.path
for (m, (f, c)) in code.iteritems():
filepath = '%s/%s' % (dest, f)
dirpath = os.path.dirname(filepath)
if os.path.exists(filepath):
...
...
@@ -199,16 +202,26 @@ def extract(dest='.'):
os.chmod(filepath, 0755)
if __name__ == '__main__':
importer = StringImporter(code)
importer.install()
# This will start actual execution
import sys
importer = Importer(code)
sys.path_hooks.append(importer)
import exceptions
import imp
try:
import __apa__main__
# This will start actual execution
importer.load_module("__main__")
except exceptions.SystemExit, e:
raise e
except:
if BAD:
import traceback
traceback.print_exception(*BAD)
pass
sys.exit(1)
"""
if
apa
:
apa
.
close
()
os
.
chmod
(
options
.
output
,
0755
)
try
:
os
.
chmod
(
options
.
output
,
0755
)
except
:
pass
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment