Update icon and Add info
This commit is contained in:
@ -0,0 +1,2 @@
|
||||
from . import setup
|
||||
from . import plist_template
|
12
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/lib/__error__.sh
Executable file
12
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/lib/__error__.sh
Executable file
@ -0,0 +1,12 @@
|
||||
#!/bin/sh
|
||||
#
|
||||
# This is the default bundletemplate error script
|
||||
# Note that this DOES NOT present a GUI dialog, because
|
||||
# it has no output on stdout, and has a return value of 0.
|
||||
#
|
||||
if ( test -n "$2" ) ; then
|
||||
echo "[$1] Unexpected Exception:" 1>&2
|
||||
echo "$2: $3" 1>&2
|
||||
else
|
||||
echo "[$1] Could not find a suitable Python runtime" 1>&2
|
||||
fi
|
132
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/lib/site.py
Normal file
132
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/lib/site.py
Normal file
@ -0,0 +1,132 @@
|
||||
"""
|
||||
Append module search paths for third-party packages to sys.path.
|
||||
|
||||
This is stripped down and customized for use in py2app applications
|
||||
"""
|
||||
|
||||
import sys
|
||||
# os is actually in the zip, so we need to do this here.
|
||||
# we can't call it python24.zip because zlib is not a built-in module (!)
|
||||
_libdir = '/lib/python' + sys.version[:3]
|
||||
_parent = '/'.join(__file__.split('/')[:-1])
|
||||
if not _parent.endswith(_libdir):
|
||||
_parent += _libdir
|
||||
sys.path.append(_parent + '/site-packages.zip')
|
||||
|
||||
# Stuffit decompresses recursively by default, that can mess up py2app bundles,
|
||||
# add the uncompressed site-packages to the path to compensate for that.
|
||||
sys.path.append(_parent + '/site-packages')
|
||||
|
||||
USER_SITE=None
|
||||
|
||||
import os
|
||||
try:
|
||||
basestring
|
||||
except NameError:
|
||||
basestring = str
|
||||
|
||||
def makepath(*paths):
|
||||
dir = os.path.abspath(os.path.join(*paths))
|
||||
return dir, os.path.normcase(dir)
|
||||
|
||||
for m in sys.modules.values():
|
||||
f = getattr(m, '__file__', None)
|
||||
if isinstance(f, basestring) and os.path.exists(f):
|
||||
m.__file__ = os.path.abspath(m.__file__)
|
||||
del m
|
||||
|
||||
# This ensures that the initial path provided by the interpreter contains
|
||||
# only absolute pathnames, even if we're running from the build directory.
|
||||
L = []
|
||||
_dirs_in_sys_path = {}
|
||||
dir = dircase = None # sys.path may be empty at this point
|
||||
for dir in sys.path:
|
||||
# Filter out duplicate paths (on case-insensitive file systems also
|
||||
# if they only differ in case); turn relative paths into absolute
|
||||
# paths.
|
||||
dir, dircase = makepath(dir)
|
||||
if not dircase in _dirs_in_sys_path:
|
||||
L.append(dir)
|
||||
_dirs_in_sys_path[dircase] = 1
|
||||
sys.path[:] = L
|
||||
del dir, dircase, L
|
||||
_dirs_in_sys_path = None
|
||||
|
||||
def _init_pathinfo():
|
||||
global _dirs_in_sys_path
|
||||
_dirs_in_sys_path = d = {}
|
||||
for dir in sys.path:
|
||||
if dir and not os.path.isdir(dir):
|
||||
continue
|
||||
dir, dircase = makepath(dir)
|
||||
d[dircase] = 1
|
||||
|
||||
def addsitedir(sitedir):
|
||||
global _dirs_in_sys_path
|
||||
if _dirs_in_sys_path is None:
|
||||
_init_pathinfo()
|
||||
reset = 1
|
||||
else:
|
||||
reset = 0
|
||||
sitedir, sitedircase = makepath(sitedir)
|
||||
if not sitedircase in _dirs_in_sys_path:
|
||||
sys.path.append(sitedir) # Add path component
|
||||
try:
|
||||
names = os.listdir(sitedir)
|
||||
except os.error:
|
||||
return
|
||||
names.sort()
|
||||
for name in names:
|
||||
if name[-4:] == os.extsep + "pth":
|
||||
addpackage(sitedir, name)
|
||||
if reset:
|
||||
_dirs_in_sys_path = None
|
||||
|
||||
def addpackage(sitedir, name):
|
||||
global _dirs_in_sys_path
|
||||
if _dirs_in_sys_path is None:
|
||||
_init_pathinfo()
|
||||
reset = 1
|
||||
else:
|
||||
reset = 0
|
||||
fullname = os.path.join(sitedir, name)
|
||||
try:
|
||||
with open(fullname) as f:
|
||||
while 1:
|
||||
dir = f.readline()
|
||||
if not dir:
|
||||
break
|
||||
if dir[0] == '#':
|
||||
continue
|
||||
if dir.startswith("import"):
|
||||
exec(dir)
|
||||
continue
|
||||
if dir[-1] == '\n':
|
||||
dir = dir[:-1]
|
||||
dir, dircase = makepath(sitedir, dir)
|
||||
if not dircase in _dirs_in_sys_path and os.path.exists(dir):
|
||||
sys.path.append(dir)
|
||||
_dirs_in_sys_path[dircase] = 1
|
||||
except IOError:
|
||||
return
|
||||
if reset:
|
||||
_dirs_in_sys_path = None
|
||||
|
||||
|
||||
#sys.setdefaultencoding('utf-8')
|
||||
|
||||
#
|
||||
# Run custom site specific code, if available.
|
||||
#
|
||||
try:
|
||||
import sitecustomize
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
#
|
||||
# Remove sys.setdefaultencoding() so that users cannot change the
|
||||
# encoding after initialization. The test for presence is needed when
|
||||
# this module is run as a script, because this code is executed twice.
|
||||
#
|
||||
if hasattr(sys, "setdefaultencoding"):
|
||||
del sys.setdefaultencoding
|
@ -0,0 +1,51 @@
|
||||
import sys
|
||||
import py2app
|
||||
__all__ = ['infoPlistDict']
|
||||
|
||||
def infoPlistDict(CFBundleExecutable, plist={}):
|
||||
CFBundleExecutable = CFBundleExecutable
|
||||
NSPrincipalClass = ''.join(CFBundleExecutable.split())
|
||||
version = sys.version[:3]
|
||||
pdict = dict(
|
||||
CFBundleDevelopmentRegion='English',
|
||||
CFBundleDisplayName=plist.get('CFBundleName', CFBundleExecutable),
|
||||
CFBundleExecutable=CFBundleExecutable,
|
||||
CFBundleIconFile=CFBundleExecutable,
|
||||
CFBundleIdentifier='org.pythonmac.unspecified.%s' % (NSPrincipalClass,),
|
||||
CFBundleInfoDictionaryVersion='6.0',
|
||||
CFBundleName=CFBundleExecutable,
|
||||
CFBundlePackageType='BNDL',
|
||||
CFBundleShortVersionString=plist.get('CFBundleVersion', '0.0'),
|
||||
CFBundleSignature='????',
|
||||
CFBundleVersion='0.0',
|
||||
LSHasLocalizedDisplayName=False,
|
||||
NSAppleScriptEnabled=False,
|
||||
NSHumanReadableCopyright='Copyright not specified',
|
||||
NSMainNibFile='MainMen',
|
||||
NSPrincipalClass=NSPrincipalClass,
|
||||
PyMainFileNames=['__boot__'],
|
||||
PyResourcePackages=[ (s % version) for s in [
|
||||
'lib/python%s',
|
||||
'lib/python%s/lib-dynload',
|
||||
'lib/python%s/site-packages.zip',
|
||||
]] + [ 'lib/python%s.zip' % version.replace('.', '') ],
|
||||
PyRuntimeLocations=[(s % version) for s in [
|
||||
'@executable_path/../Frameworks/Python.framework/Versions/%s/Python',
|
||||
'~/Library/Frameworks/Python.framework/Versions/%s/Python',
|
||||
'/Library/Frameworks/Python.framework/Versions/%s/Python',
|
||||
'/Network/Library/Frameworks/Python.framework/Versions/%s/Python',
|
||||
'/System/Library/Frameworks/Python.framework/Versions/%s/Python',
|
||||
]],
|
||||
)
|
||||
pdict.update(plist)
|
||||
pythonInfo = pdict.setdefault('PythonInfoDict', {})
|
||||
pythonInfo.update(dict(
|
||||
PythonLongVersion=sys.version,
|
||||
PythonShortVersion=sys.version[:3],
|
||||
PythonExecutable=sys.executable,
|
||||
))
|
||||
py2appInfo = pythonInfo.setdefault('py2app', {}).update(dict(
|
||||
version=py2app.__version__,
|
||||
template='bundle',
|
||||
))
|
||||
return pdict
|
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-fat
Executable file
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-fat
Executable file
Binary file not shown.
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-fat3
Executable file
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-fat3
Executable file
Binary file not shown.
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-i386
Executable file
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-i386
Executable file
Binary file not shown.
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-intel
Executable file
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-intel
Executable file
Binary file not shown.
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-ppc
Executable file
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-ppc
Executable file
Binary file not shown.
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-ppc64
Executable file
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-ppc64
Executable file
Binary file not shown.
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-universal
Executable file
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-universal
Executable file
Binary file not shown.
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-x86_64
Executable file
BIN
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/prebuilt/main-x86_64
Executable file
Binary file not shown.
122
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/setup.py
Normal file
122
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/setup.py
Normal file
@ -0,0 +1,122 @@
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import distutils.sysconfig
|
||||
import distutils.util
|
||||
|
||||
gPreBuildVariants = [
|
||||
{
|
||||
'name': 'main-universal',
|
||||
'target': '10.5',
|
||||
'cflags': '-isysroot @@XCODE_ROOT@@/SDKs/MacOSX10.5.sdk -arch i386 -arch ppc -arch ppc64 -arch x86_64',
|
||||
'cc': 'gcc-4.2',
|
||||
},
|
||||
{
|
||||
'name': 'main-ppc64',
|
||||
'target': '10.5',
|
||||
'cflags': '-isysroot @@XCODE_ROOT@@/SDKs/MacOSX10.5.sdk -arch ppc64',
|
||||
'cc': 'gcc-4.2',
|
||||
},
|
||||
{
|
||||
'name': 'main-x86_64',
|
||||
'target': '10.5',
|
||||
'cflags': '-isysroot / -arch x86_64',
|
||||
'cc': 'clang',
|
||||
},
|
||||
{
|
||||
'name': 'main-fat3',
|
||||
'target': '10.5',
|
||||
'cflags': '-isysroot / -arch i386 -arch ppc -arch x86_64',
|
||||
'cc': 'gcc-4.2',
|
||||
},
|
||||
{
|
||||
'name': 'main-intel',
|
||||
'target': '10.5',
|
||||
'cflags': '-isysroot / -arch i386 -arch x86_64',
|
||||
'cc': 'clang',
|
||||
},
|
||||
{
|
||||
'name': 'main-i386',
|
||||
'target': '10.3',
|
||||
#'cflags': '-isysroot @@XCODE_ROOT@@/SDKs/MacOSX10.4u.sdk -arch i386',
|
||||
'cflags': '-arch i386 -isysroot /',
|
||||
'cc': 'clang',
|
||||
},
|
||||
{
|
||||
'name': 'main-ppc',
|
||||
'target': '10.3',
|
||||
'cflags': '-isysroot @@XCODE_ROOT@@/SDKs/MacOSX10.4u.sdk -arch ppc',
|
||||
'cc': 'gcc-4.0',
|
||||
},
|
||||
{
|
||||
'name': 'main-fat',
|
||||
'target': '10.3',
|
||||
'cflags': '-isysroot @@XCODE_ROOT@@/SDKs/MacOSX10.4u.sdk -arch i386 -arch ppc',
|
||||
'cc': 'gcc-4.0',
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def main(all=False, arch=None):
|
||||
basepath = os.path.dirname(__file__)
|
||||
builddir = os.path.join(basepath, 'prebuilt')
|
||||
if not os.path.exists(builddir):
|
||||
os.makedirs(builddir)
|
||||
src = os.path.join(basepath, 'src', 'main.m')
|
||||
|
||||
cfg = distutils.sysconfig.get_config_vars()
|
||||
|
||||
BASE_CFLAGS = cfg['CFLAGS']
|
||||
BASE_CFLAGS = BASE_CFLAGS.replace('-dynamic', '')
|
||||
BASE_CFLAGS += ' -bundle -framework Foundation -framework AppKit'
|
||||
while True:
|
||||
x = re.sub('-arch\s+\S+', '', BASE_CFLAGS)
|
||||
if x == BASE_CFLAGS:
|
||||
break
|
||||
BASE_CFLAGS=x
|
||||
|
||||
while True:
|
||||
x = re.sub('-isysroot\s+\S+', '', BASE_CFLAGS)
|
||||
if x == BASE_CFLAGS:
|
||||
break
|
||||
BASE_CFLAGS=x
|
||||
|
||||
if arch is None:
|
||||
arch = distutils.util.get_platform().split('-')[-1]
|
||||
if sys.prefix.startswith('/System') and \
|
||||
sys.version_info[:2] == (2,5):
|
||||
arch = "fat"
|
||||
|
||||
name = 'main-' + arch
|
||||
root = None
|
||||
|
||||
if all:
|
||||
for entry in gPreBuildVariants:
|
||||
if (not all) and entry['name'] != name: continue
|
||||
|
||||
dest = os.path.join(builddir, entry['name'])
|
||||
if not os.path.exists(dest) or (
|
||||
os.stat(dest).st_mtime < os.stat(src).st_mtime):
|
||||
if root is None:
|
||||
fp = os.popen('xcode-select -print-path', 'r')
|
||||
root = fp.read().strip()
|
||||
fp.close()
|
||||
|
||||
print ("rebuilding %s"%(entry['name']))
|
||||
|
||||
#CC=os.path.join(root, 'usr', 'bin', entry['cc'])
|
||||
CC=entry['cc']
|
||||
CFLAGS = BASE_CFLAGS + ' ' + entry['cflags'].replace('@@XCODE_ROOT@@', root)
|
||||
os.environ['MACOSX_DEPLOYMENT_TARGET'] = entry['target']
|
||||
os.system('"%(CC)s" -o "%(dest)s" "%(src)s" %(CFLAGS)s' % locals())
|
||||
|
||||
dest = os.path.join(
|
||||
builddir,
|
||||
'main-' + arch
|
||||
)
|
||||
|
||||
return dest
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main(all=True)
|
692
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/src/main.m
Normal file
692
.eggs/py2app-0.12-py3.6.egg/py2app/bundletemplate/src/main.m
Normal file
@ -0,0 +1,692 @@
|
||||
//
|
||||
// main.m
|
||||
// apptemplate
|
||||
//
|
||||
// Created by Bob Ippolito on Mon September 20 2004.
|
||||
// Copyright (c) 2004 Bob Ippolito. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#include <mach-o/dyld.h>
|
||||
#include <mach-o/loader.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syslimits.h>
|
||||
#include <crt_externs.h>
|
||||
#include <wchar.h>
|
||||
#include <locale.h>
|
||||
#include <langinfo.h>
|
||||
|
||||
#include <objc/objc-class.h>
|
||||
|
||||
//
|
||||
// Constants
|
||||
//
|
||||
NSString *ERR_CANNOT_SAVE_LOCALE = @"Cannot save locale information";
|
||||
NSString *ERR_REALLYBADTITLE = @"The bundle could not be launched.";
|
||||
NSString *ERR_TITLEFORMAT = @"%@ has encountered a fatal error, and will now terminate.";
|
||||
NSString *ERR_PYRUNTIMELOCATIONS = @"The Info.plist file must have a PyRuntimeLocations array containing string values for preferred Python runtime locations. These strings should be \"otool -L\" style mach ids; \"@executable_stub\" and \"~\" prefixes will be translated accordingly.";
|
||||
NSString *ERR_NOPYTHONRUNTIME = @"A Python runtime could be located. You may need to install a framework build of Python, or edit the PyRuntimeLocations array in this bundle's Info.plist file.\rThese runtime locations were attempted:\r\r";
|
||||
NSString *ERR_NOPYTHONSCRIPT = @"A main script could not be located in the Resources folder.\rThese files were tried:\r\r";
|
||||
NSString *ERR_LINKERRFMT = @"An internal error occurred while attempting to link with:\r\r%s\r\rSee the Console for a detailed dyld error message";
|
||||
NSString *ERR_PYTHONEXCEPTION = @"An uncaught exception was raised during execution of the main script:\r\r%@: %@\r\rThis may mean that an unexpected error has occurred, or that you do not have all of the dependencies for this bundle.";
|
||||
NSString *ERR_COLONPATH = @"Python bundles can not currently run from paths containing a '/' (or ':' from the Terminal).";
|
||||
|
||||
#define PYMACAPP_NSIMAGEFLAGS (NSADDIMAGE_OPTION_RETURN_ON_ERROR | NSADDIMAGE_OPTION_WITH_SEARCHING)
|
||||
#define PYMACAPP_NSLOOKUPSYMBOLINIMAGEFLAGS (NSLOOKUPSYMBOLINIMAGE_OPTION_BIND | NSLOOKUPSYMBOLINIMAGE_OPTION_RETURN_ON_ERROR)
|
||||
|
||||
//
|
||||
// Typedefs
|
||||
//
|
||||
|
||||
#define Py_file_input 257
|
||||
typedef int PyObject;
|
||||
typedef int PyThreadState;
|
||||
typedef enum {PyGILState_LOCKED, PyGILState_UNLOCKED} PyGILState_STATE;
|
||||
typedef PyGILState_STATE (*PyGILState_EnsurePtr)(void);
|
||||
typedef void (*PyGILState_ReleasePtr)(PyGILState_STATE);
|
||||
typedef PyThreadState *(*PyThreadState_SwapPtr)(PyThreadState *);
|
||||
typedef void (*PyEval_ReleaseLockPtr)(void);
|
||||
typedef void (*PyErr_ClearPtr)(void);
|
||||
typedef void (*PyErr_PrintPtr)(void);
|
||||
typedef int (*PyErr_OccurredPtr)(void);
|
||||
typedef PyObject *(*PyBytes_FromStringPtr)(const char *);
|
||||
typedef int (*PyList_InsertPtr)(PyObject *, int, PyObject *);
|
||||
typedef void (*Py_DecRefPtr)(PyObject *);
|
||||
typedef void (*Py_SetProgramNamePtr)(const wchar_t *);
|
||||
typedef int (*Py_IsInitializedPtr)(void);
|
||||
typedef void (*Py_InitializePtr)(void);
|
||||
typedef void (*PyEval_InitThreadsPtr)(void);
|
||||
typedef PyObject *(*PyRun_FilePtr)(FILE *, const char *, int, PyObject *, PyObject *);
|
||||
typedef PyObject *(*PySys_GetObjectPtr)(const char *);
|
||||
typedef int *(*PySys_SetArgvPtr)(int argc, char **argv);
|
||||
typedef PyObject *(*PyObject_StrPtr)(PyObject *);
|
||||
typedef const char *(*PyBytes_AsStringPtr)(PyObject *);
|
||||
typedef PyObject *(*PyObject_GetAttrStringPtr)(PyObject *, const char *);
|
||||
typedef PyObject *(*PyObject_CallMethodPtr)(PyObject *, const char *, const char *, ...);
|
||||
typedef PyObject *(*PyImport_ImportModulePtr)(char *);
|
||||
typedef PyObject *(*PyImport_AddModulePtr)(char *);
|
||||
typedef PyObject *(*PyModule_AddStringConstantPtr)(PyObject *, char *, char *);
|
||||
typedef PyObject *(*PyModule_AddObjectPtr)(PyObject *, char *, PyObject *);
|
||||
typedef PyObject *(*PyModule_GetDictPtr)(PyObject *);
|
||||
typedef void (*PyObject_SetItemPtr)(PyObject *, PyObject *, PyObject *);
|
||||
typedef wchar_t* (*_Py_DecodeUTF8_surrogateescapePtr)(const char *s, ssize_t size);
|
||||
|
||||
|
||||
//
|
||||
// Signatures
|
||||
//
|
||||
|
||||
static void DefaultDecRef(PyObject *op);
|
||||
static int report_error(NSString *err);
|
||||
static int report_linkEdit_error(const char* name);
|
||||
static int report_script_error(NSString *err, NSString *errClassName, NSString *errName);
|
||||
static NSString *pyStandardizePath(NSString *pyLocation);
|
||||
static BOOL doesPathExist(NSString *path);
|
||||
static NSString *getBundleName(void);
|
||||
static NSString *getErrorTitle(NSString *bundleName);
|
||||
static const char *bundlePath(void);
|
||||
static NSBundle *bundleBundle(void);
|
||||
static int pyobjc_main(int argc, char * const *argv, char * const *envp);
|
||||
|
||||
//
|
||||
// Mach-O Constructor
|
||||
//
|
||||
|
||||
static void __attribute__ ((constructor)) _py2app_bundle_load(void);
|
||||
|
||||
//
|
||||
// Implementation
|
||||
//
|
||||
|
||||
static
|
||||
const char *bundlePath(void) {
|
||||
int i;
|
||||
const struct mach_header *myHeader = _dyld_get_image_header_containing_address(&bundlePath);
|
||||
int count = _dyld_image_count();
|
||||
for (i = 0; i < count; i++) {
|
||||
if (_dyld_get_image_header(i) == myHeader) {
|
||||
return _dyld_get_image_name(i);
|
||||
}
|
||||
}
|
||||
abort();
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static
|
||||
NSBundle *bundleBundle(void) {
|
||||
static NSBundle *myBundle = NULL;
|
||||
if (!myBundle) {
|
||||
int i;
|
||||
NSString *path = [NSString stringWithUTF8String:bundlePath()];
|
||||
// strip Contents/MacOS/App
|
||||
for (i = 0; i < 3; i++) {
|
||||
path = [path stringByDeletingLastPathComponent];
|
||||
}
|
||||
myBundle = [[NSBundle alloc] initWithPath:path];
|
||||
}
|
||||
return myBundle;
|
||||
}
|
||||
|
||||
//
|
||||
// THIS WILL NOT WORK WITH Py_TRACE_REFS / Py_DEBUG ON UNLESS USING 2.4 OR LATER!
|
||||
//
|
||||
static
|
||||
void DefaultDecRef(PyObject *op) {
|
||||
if (op != NULL) {
|
||||
--(*op);
|
||||
}
|
||||
}
|
||||
|
||||
static
|
||||
int report_script_error(NSString *err, NSString *errClassName, NSString *errName) {
|
||||
return report_error(err);
|
||||
}
|
||||
|
||||
static
|
||||
int report_error(NSString *err) {
|
||||
NSLog(@"%@", getErrorTitle(getBundleName()));
|
||||
NSLog(@"%@", err);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static
|
||||
int report_linkEdit_error(const char* name) {
|
||||
NSLinkEditErrors errorClass;
|
||||
int errorNumber;
|
||||
const char *fileName;
|
||||
const char *errorString;
|
||||
NSLinkEditError(&errorClass, &errorNumber, &fileName, &errorString);
|
||||
NSLog(@"%s: %s", name, errorString);
|
||||
printf("<<<py2app>>>> %s: %s\n", name, errorString);
|
||||
return report_error([NSString stringWithFormat:ERR_LINKERRFMT, fileName]);
|
||||
}
|
||||
|
||||
static
|
||||
NSString *pyStandardizePath(NSString *pyLocation) {
|
||||
if ([pyLocation hasPrefix:@"@executable_path/"]) {
|
||||
NSMutableArray *newComponents = [[pyLocation pathComponents] mutableCopy];
|
||||
[newComponents replaceObjectAtIndex:0 withObject:[bundleBundle() privateFrameworksPath]];
|
||||
pyLocation = [NSString pathWithComponents: newComponents];
|
||||
}
|
||||
return [pyLocation stringByStandardizingPath];
|
||||
};
|
||||
|
||||
static
|
||||
BOOL doesPathExist(NSString *path) {
|
||||
struct stat sb;
|
||||
return (stat([path fileSystemRepresentation], &sb) == -1) ? NO : YES;
|
||||
}
|
||||
|
||||
static
|
||||
NSString *getBundleName(void) {
|
||||
NSDictionary *infoDictionary = [bundleBundle() infoDictionary];
|
||||
NSString *bundleName = [infoDictionary objectForKey:@"CFBundleName"];
|
||||
if (!bundleName) {
|
||||
bundleName = [infoDictionary objectForKey:@"CFBundleExecutable"];
|
||||
}
|
||||
return bundleName;
|
||||
}
|
||||
|
||||
static
|
||||
NSString *getErrorTitle(NSString *bundleName) {
|
||||
if (!bundleName) {
|
||||
return ERR_REALLYBADTITLE;
|
||||
}
|
||||
return [NSString stringWithFormat:ERR_TITLEFORMAT,bundleName];
|
||||
}
|
||||
|
||||
static
|
||||
NSString *getPythonLocation(NSArray *pyLocations) {
|
||||
// get the runtime locations from the Info.plist
|
||||
|
||||
// *does not* inspect DYLD environment variables for overrides, fallbacks, suffixes, etc.
|
||||
// I don't really consider that a very bad thing, as it makes this search extremely deterministic.
|
||||
// Note that I use the env variables when the image is actually linked, so what you find here
|
||||
// may not be what gets linked. If this is the case, you deserve it :)
|
||||
|
||||
// find a Python runtime
|
||||
NSString *pyLocation;
|
||||
NSEnumerator *pyLocationsEnumerator = [pyLocations objectEnumerator];
|
||||
while ((pyLocation = [pyLocationsEnumerator nextObject])) {
|
||||
pyLocation = pyStandardizePath(pyLocation);
|
||||
if (doesPathExist(pyLocation)) {
|
||||
return pyLocation;
|
||||
}
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
static NSString* getPythonInterpreter(NSString* pyLocation) {
|
||||
NSBundle* bndl;
|
||||
NSString* auxName;
|
||||
|
||||
bndl = bundleBundle();
|
||||
|
||||
auxName = [[bndl infoDictionary] objectForKey:@"PyExecutableName"];
|
||||
if (!auxName) {
|
||||
auxName = @"python";
|
||||
}
|
||||
return [bndl pathForAuxiliaryExecutable:auxName];
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
NSArray *getPythonPathArray(NSDictionary *infoDictionary, NSString *resourcePath) {
|
||||
NSMutableArray *pythonPathArray = [NSMutableArray arrayWithObject: resourcePath];
|
||||
NSArray *pyResourcePackages = [infoDictionary objectForKey:@"PyResourcePackages"];
|
||||
if (pyResourcePackages != nil) {
|
||||
NSString *pkg;
|
||||
NSEnumerator *pyResourcePackageEnumerator = [pyResourcePackages objectEnumerator];
|
||||
while ((pkg = [pyResourcePackageEnumerator nextObject])) {
|
||||
pkg = [pkg stringByExpandingTildeInPath];
|
||||
if (![@"/" isEqualToString: [pkg substringToIndex:1]]) {
|
||||
pkg = [resourcePath stringByAppendingPathComponent:pkg];
|
||||
}
|
||||
[pythonPathArray addObject:pkg];
|
||||
}
|
||||
}
|
||||
return pythonPathArray;
|
||||
}
|
||||
|
||||
static
|
||||
NSString *getMainPyPath(NSDictionary *infoDictionary) {
|
||||
NSArray *possibleMains = [infoDictionary objectForKey:@"PyMainFileNames"];
|
||||
if ( !possibleMains )
|
||||
possibleMains = [NSArray array];
|
||||
// find main python file. __main__.py seems to be a standard, so we'll go ahead and add defaults.
|
||||
possibleMains = [possibleMains arrayByAddingObjectsFromArray:[NSArray arrayWithObjects:
|
||||
@"__main__",
|
||||
@"__realmain__",
|
||||
@"Main",
|
||||
nil]];
|
||||
NSEnumerator *possibleMainsEnumerator = [possibleMains objectEnumerator];
|
||||
NSString *mainPyPath = nil;
|
||||
NSString *nextFileName = nil;
|
||||
NSString *nextExtension = nil;
|
||||
NSArray *extensions = [NSArray arrayWithObjects:@".py", @".pyc", @".pyo", @"", nil];
|
||||
|
||||
NSMutableArray *runtimeAttempts = [NSMutableArray array];
|
||||
while ((nextFileName = [possibleMainsEnumerator nextObject])) {
|
||||
NSEnumerator *nextExtensionEnumerator = [extensions objectEnumerator];
|
||||
while ((nextExtension = [nextExtensionEnumerator nextObject])) {
|
||||
[runtimeAttempts addObject:[nextFileName stringByAppendingString:nextExtension]];
|
||||
}
|
||||
}
|
||||
possibleMainsEnumerator = [runtimeAttempts objectEnumerator];
|
||||
while ((nextFileName = [possibleMainsEnumerator nextObject]) && !mainPyPath) {
|
||||
mainPyPath = [bundleBundle() pathForResource:nextFileName ofType:nil];
|
||||
}
|
||||
if (!mainPyPath) {
|
||||
NSString *components = [runtimeAttempts componentsJoinedByString:@"\r"];
|
||||
report_error([ERR_NOPYTHONSCRIPT stringByAppendingString:components]);
|
||||
}
|
||||
return mainPyPath;
|
||||
}
|
||||
|
||||
|
||||
int pyobjc_main(int argc, char * const *argv, char * const *envp) {
|
||||
char* curenv;
|
||||
char* curlocale;
|
||||
NSDictionary *infoDictionary = [bundleBundle() infoDictionary];
|
||||
|
||||
if (getenv("PYTHONOPTIMIZE") != NULL) {
|
||||
unsetenv("PYTHONOPTIMIZE");
|
||||
}
|
||||
if (getenv("PYTHONDEBUG") != NULL) {
|
||||
unsetenv("PYTHONDEBUG");
|
||||
}
|
||||
if (getenv("PYTHONDONTWRITEBYTECODE") != NULL) {
|
||||
unsetenv("PYTHONDONTWRITEBYTECODE");
|
||||
}
|
||||
if (getenv("PYTHONIOENCODING") != NULL) {
|
||||
unsetenv("PYTHONIOENCODING");
|
||||
}
|
||||
if (getenv("PYTHONDUMPREFS") != NULL) {
|
||||
unsetenv("PYTHONDUMPREFS");
|
||||
}
|
||||
if (getenv("PYTHONMALLOCSTATS") != NULL) {
|
||||
unsetenv("PYTHONMALLOCSTATS");
|
||||
}
|
||||
|
||||
/* Disable writing of bytecode files */
|
||||
setenv("PYTHONDONTWRITEBYTECODE", "1", 1);
|
||||
|
||||
NSString *pyLocation = nil;
|
||||
while (NSIsSymbolNameDefined("_Py_Initialize")) {
|
||||
// Python is already in-process
|
||||
NSSymbol sym = NSLookupAndBindSymbol("_Py_Initialize");
|
||||
if (!sym) {
|
||||
break;
|
||||
}
|
||||
NSModule mod = NSModuleForSymbol(sym);
|
||||
if (!mod) {
|
||||
break;
|
||||
}
|
||||
const char *python_dylib_path = NSLibraryNameForModule(mod);
|
||||
if (python_dylib_path) {
|
||||
pyLocation = [NSString stringWithUTF8String:python_dylib_path];
|
||||
}
|
||||
break;
|
||||
}
|
||||
NSArray *pyLocations = [infoDictionary objectForKey:@"PyRuntimeLocations"];
|
||||
if (!pyLocation) {
|
||||
// Python is not in-process
|
||||
if (!pyLocations) {
|
||||
return report_error(ERR_PYRUNTIMELOCATIONS);
|
||||
}
|
||||
pyLocation = getPythonLocation(pyLocations);
|
||||
}
|
||||
if (!pyLocation) {
|
||||
NSString *components = [pyLocations componentsJoinedByString:@"\r\r"];
|
||||
return report_script_error([ERR_NOPYTHONRUNTIME stringByAppendingString:components], nil, nil);
|
||||
}
|
||||
|
||||
// Find our resource path and possible PYTHONPATH
|
||||
NSString *resourcePath = [bundleBundle() resourcePath];
|
||||
NSArray *pythonPathArray = getPythonPathArray(infoDictionary, resourcePath);
|
||||
|
||||
// find the main script
|
||||
NSString *mainPyPath = getMainPyPath(infoDictionary);
|
||||
if (!mainPyPath) {
|
||||
// error already reported
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Load the Python dylib (may have already been loaded, that is OK)
|
||||
const struct mach_header *py_dylib = NSAddImage([pyLocation fileSystemRepresentation], PYMACAPP_NSIMAGEFLAGS);
|
||||
if (!py_dylib) {
|
||||
return report_linkEdit_error([pyLocation fileSystemRepresentation]);
|
||||
}
|
||||
|
||||
// Load the symbols we need from Python. We avoid lookups of unicode methods because their
|
||||
// names are mangled by Python (because of UCS2/UCS4 stuff) and looking them up reliably is
|
||||
// problematic.
|
||||
NSSymbol tmpSymbol;
|
||||
#define LOOKUP_SYMBOL(NAME) \
|
||||
tmpSymbol = NSLookupSymbolInImage(py_dylib, "_" #NAME, PYMACAPP_NSLOOKUPSYMBOLINIMAGEFLAGS)
|
||||
#define LOOKUP_DEFINEADDRESS(NAME, ADDRESS) \
|
||||
NAME ## Ptr NAME = (NAME ## Ptr)ADDRESS
|
||||
#define LOOKUP_DEFINE(NAME) \
|
||||
LOOKUP_DEFINEADDRESS(NAME, NSAddressOfSymbol(tmpSymbol))
|
||||
#define LOOKUP(NAME) \
|
||||
LOOKUP_SYMBOL(NAME); \
|
||||
if ( !tmpSymbol ) \
|
||||
return report_linkEdit_error(#NAME); \
|
||||
LOOKUP_DEFINE(NAME)
|
||||
|
||||
#define OPT_LOOKUP(NAME) \
|
||||
LOOKUP_SYMBOL(NAME); \
|
||||
NAME ## Ptr NAME = NULL; \
|
||||
if (tmpSymbol) { \
|
||||
NAME = (NAME ## Ptr)NSAddressOfSymbol(tmpSymbol); \
|
||||
}
|
||||
|
||||
LOOKUP_SYMBOL(Py_DecRef);
|
||||
LOOKUP_DEFINEADDRESS(Py_DecRef, (tmpSymbol ? NSAddressOfSymbol(tmpSymbol) : &DefaultDecRef));
|
||||
LOOKUP(Py_SetProgramName);
|
||||
LOOKUP(Py_IsInitialized);
|
||||
LOOKUP(Py_Initialize);
|
||||
LOOKUP(PyErr_Clear);
|
||||
LOOKUP(PyErr_Print);
|
||||
LOOKUP(PyErr_Occurred);
|
||||
LOOKUP(PyEval_ReleaseLock);
|
||||
LOOKUP(PyGILState_Ensure);
|
||||
LOOKUP(PyGILState_Release);
|
||||
LOOKUP(PyEval_InitThreads);
|
||||
LOOKUP(PyRun_File);
|
||||
LOOKUP(PySys_GetObject);
|
||||
LOOKUP(PySys_SetArgv);
|
||||
LOOKUP(PyObject_Str);
|
||||
LOOKUP(PyList_Insert);
|
||||
LOOKUP(PyObject_GetAttrString);
|
||||
LOOKUP(PyObject_CallMethod);
|
||||
LOOKUP(PyImport_ImportModule);
|
||||
LOOKUP(PyImport_AddModule);
|
||||
LOOKUP(PyObject_SetItem);
|
||||
LOOKUP(PyModule_AddStringConstant);
|
||||
LOOKUP(PyModule_AddObject);
|
||||
LOOKUP(PyModule_GetDict);
|
||||
LOOKUP(PyThreadState_Swap);
|
||||
OPT_LOOKUP(_Py_DecodeUTF8_surrogateescape);
|
||||
|
||||
|
||||
/* PyBytes / PyString lookups depend of if we're on py3k or not */
|
||||
PyBytes_AsStringPtr PyBytes_AsString = NULL;
|
||||
PyBytes_FromStringPtr PyBytes_FromString = NULL;
|
||||
LOOKUP_SYMBOL(PyBytes_AsString);
|
||||
int isPy3k = tmpSymbol != NULL;
|
||||
if (isPy3k) {
|
||||
PyBytes_AsString = (PyBytes_AsStringPtr)NSAddressOfSymbol(tmpSymbol);
|
||||
LOOKUP_SYMBOL(PyBytes_FromString);
|
||||
PyBytes_FromString = (PyBytes_FromStringPtr)NSAddressOfSymbol(tmpSymbol);
|
||||
}
|
||||
else {
|
||||
LOOKUP_SYMBOL(PyString_AsString);
|
||||
PyBytes_AsString = (PyBytes_AsStringPtr)NSAddressOfSymbol(tmpSymbol);
|
||||
LOOKUP_SYMBOL(PyString_FromString);
|
||||
PyBytes_FromString = (PyBytes_FromStringPtr)NSAddressOfSymbol(tmpSymbol);
|
||||
}
|
||||
|
||||
#undef LOOKUP
|
||||
#undef LOOKUP_DEFINE
|
||||
#undef LOOKUP_DEFINEADDRESS
|
||||
#undef LOOKUP_SYMBOL
|
||||
|
||||
int was_initialized = Py_IsInitialized();
|
||||
|
||||
/*
|
||||
* When apps are started from the Finder (or anywhere
|
||||
* except from the terminal), the LANG and LC_* variables
|
||||
* aren't set in the environment. This confuses Py_Initialize
|
||||
* when it tries to import the codec for UTF-8,
|
||||
* therefore explicitly set the locale.
|
||||
*
|
||||
* Also set the LC_CTYPE environment variable because Py_Initialize
|
||||
* reset the locale information using the environment :-(
|
||||
*/
|
||||
if (isPy3k) {
|
||||
curlocale = setlocale(LC_ALL, NULL);
|
||||
if (curlocale != NULL) {
|
||||
curlocale = strdup(curlocale);
|
||||
if (curlocale == NULL) {
|
||||
(void)report_error(ERR_CANNOT_SAVE_LOCALE);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
setlocale(LC_ALL, "en_US.UTF-8");
|
||||
|
||||
curenv = getenv("LC_CTYPE");
|
||||
if (!curenv) {
|
||||
setenv("LC_CTYPE", "en_US.UTF-8", 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Set up the environment variables to be transferred
|
||||
NSMutableDictionary *newEnviron = [NSMutableDictionary dictionary];
|
||||
[newEnviron setObject:[NSString stringWithFormat:@"%p", bundleBundle()] forKey:@"PYOBJC_BUNDLE_ADDRESS"];
|
||||
[newEnviron setObject:[NSString stringWithFormat:@"%p", bundleBundle()] forKey:[NSString
|
||||
stringWithFormat:@"PYOBJC_BUNDLE_ADDRESS%ld", (long)getpid()]];
|
||||
[newEnviron setObject:resourcePath forKey:@"RESOURCEPATH"];
|
||||
NSMutableDictionary *oldEnviron = [NSMutableDictionary dictionary];
|
||||
|
||||
// bootstrap Python with information about how to find what it needs
|
||||
// if it is not already initialized
|
||||
if (!was_initialized) {
|
||||
// $PREFIX/Python -> $PREFIX
|
||||
NSString *pythonProgramName = [pyLocation stringByDeletingLastPathComponent];
|
||||
NSString* interpreter = getPythonInterpreter(pyLocation);
|
||||
struct stat sb;
|
||||
|
||||
if (lstat([interpreter fileSystemRepresentation], &sb) == 0) {
|
||||
if(!((sb.st_mode & S_IFLNK) == S_IFLNK)) {
|
||||
setenv("PYTHONHOME", [resourcePath fileSystemRepresentation], 1);
|
||||
}
|
||||
} else {
|
||||
setenv("PYTHONHOME", [resourcePath fileSystemRepresentation], 1);
|
||||
}
|
||||
|
||||
NSString *pyExecutableName = [infoDictionary objectForKey:@"PyExecutableName"];
|
||||
if ( !pyExecutableName ) {
|
||||
pyExecutableName = @"python";
|
||||
}
|
||||
|
||||
pythonProgramName = [[pythonProgramName stringByAppendingPathComponent:@"bin"] stringByAppendingPathComponent:pyExecutableName];
|
||||
|
||||
wchar_t wPythonName[PATH_MAX+1];
|
||||
if (isPy3k) {
|
||||
mbstowcs(wPythonName, [pythonProgramName fileSystemRepresentation], PATH_MAX+1);
|
||||
}
|
||||
else {
|
||||
const char *cPythonName = [pythonProgramName fileSystemRepresentation];
|
||||
memcpy(wPythonName, cPythonName, strlen(cPythonName));
|
||||
}
|
||||
Py_SetProgramName(wPythonName);
|
||||
}
|
||||
|
||||
// Set new environment variables and save older ones (for nested plugin loading)
|
||||
NSEnumerator *envEnumerator = [newEnviron keyEnumerator];
|
||||
NSString *envKey;
|
||||
while ((envKey = [envEnumerator nextObject])) {
|
||||
char *keyString = (char *)[envKey UTF8String];
|
||||
char *oldValue = getenv(keyString);
|
||||
if (oldValue) {
|
||||
[oldEnviron setObject:[NSString stringWithUTF8String:oldValue] forKey:envKey];
|
||||
}
|
||||
setenv(keyString, (char *)[[newEnviron objectForKey:envKey] UTF8String], 1);
|
||||
}
|
||||
|
||||
|
||||
int rval = 0;
|
||||
FILE *mainPyFile = NULL;
|
||||
Py_Initialize();
|
||||
PyEval_InitThreads();
|
||||
|
||||
if (isPy3k) {
|
||||
/*
|
||||
* Reset the environment and locale information
|
||||
*/
|
||||
setlocale(LC_CTYPE, curlocale);
|
||||
free(curlocale);
|
||||
|
||||
if (!curenv) {
|
||||
unsetenv("LC_CTYPE");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
PyGILState_STATE gilState = PyGILState_Ensure();
|
||||
|
||||
if (was_initialized) {
|
||||
// transfer path into existing Python process
|
||||
PyObject *path = PySys_GetObject("path");
|
||||
NSEnumerator *pathEnumerator = [pythonPathArray reverseObjectEnumerator];
|
||||
NSString *curPath;
|
||||
while ((curPath = [pathEnumerator nextObject])) {
|
||||
PyObject *b = PyBytes_FromString([curPath UTF8String]);
|
||||
PyObject *s = PyObject_CallMethod(b, "decode", "s", "utf-8");
|
||||
PyList_Insert(path, 0, s);
|
||||
Py_DecRef(b);Py_DecRef(s);
|
||||
}
|
||||
|
||||
// transfer environment variables into existing Python process
|
||||
PyObject *osModule = PyImport_ImportModule("os");
|
||||
PyObject *pyenv = PyObject_GetAttrString(osModule, "environ");
|
||||
Py_DecRef(osModule);
|
||||
envEnumerator = [newEnviron keyEnumerator];
|
||||
while ((envKey = [envEnumerator nextObject])) {
|
||||
char *keyString = (char *)[envKey UTF8String];
|
||||
PyObject *b_key = PyBytes_FromString(keyString);
|
||||
PyObject *b_value = PyBytes_FromString(getenv(keyString));
|
||||
PyObject *key = PyObject_CallMethod(b_key, "decode", "s", "utf-8");
|
||||
PyObject *value = PyObject_CallMethod(b_value, "decode", "s", "utf-8");
|
||||
PyObject_SetItem(pyenv, key, value);
|
||||
Py_DecRef(b_key);Py_DecRef(key);
|
||||
Py_DecRef(b_value);Py_DecRef(value);
|
||||
}
|
||||
Py_DecRef(pyenv);
|
||||
}
|
||||
|
||||
char *c_mainPyPath = (char *)[mainPyPath fileSystemRepresentation];
|
||||
mainPyFile = fopen(c_mainPyPath, "r");
|
||||
if (!mainPyFile) {
|
||||
rval = report_error([NSString stringWithFormat:@"Could not open main script %@",mainPyPath]);
|
||||
goto cleanup;
|
||||
}
|
||||
if (!was_initialized) {
|
||||
int i;
|
||||
NSMutableData *data_argv = [NSMutableData dataWithCapacity:(sizeof(char *) * argc)];
|
||||
char **argv_new = [data_argv mutableBytes];
|
||||
if (isPy3k) {
|
||||
argv_new[0] = (char*)_Py_DecodeUTF8_surrogateescape(c_mainPyPath, strlen(c_mainPyPath));
|
||||
} else {
|
||||
argv_new[0] = c_mainPyPath;
|
||||
}
|
||||
for (i = 1; i < argc; i++) {
|
||||
if (isPy3k) {
|
||||
argv_new[i] = (char*)_Py_DecodeUTF8_surrogateescape(argv[i], strlen(argv[i]));
|
||||
} else {
|
||||
argv_new[i] = argv[i];
|
||||
}
|
||||
}
|
||||
argv_new[argc] = NULL;
|
||||
PySys_SetArgv(argc, argv_new);
|
||||
}
|
||||
|
||||
// create a unique moduleName by CFBundleIdentifier replacing . with _ and prepending __main__
|
||||
NSString *moduleName = [NSString stringWithFormat:@"__main__%@", [[[infoDictionary objectForKey:@"CFBundleIdentifier"] componentsSeparatedByString:@"."] componentsJoinedByString:@"_"]];
|
||||
PyObject *module = PyImport_AddModule((char *)[moduleName UTF8String]);
|
||||
if (!module) {
|
||||
rval = report_error([NSString stringWithFormat:@"Could not create module '%@'",moduleName]);
|
||||
goto cleanup;
|
||||
}
|
||||
PyModule_AddStringConstant(module, "__file__", c_mainPyPath);
|
||||
char * builtinsName = isPy3k ? "builtins" : "__builtin__";
|
||||
PyObject *builtins = PyImport_ImportModule(builtinsName);
|
||||
PyModule_AddObject(module, "__builtins__", builtins);
|
||||
PyObject *module_dict = PyModule_GetDict(module);
|
||||
if (PyErr_Occurred()) {
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
PyObject *res = PyRun_File(mainPyFile, c_mainPyPath, Py_file_input, module_dict, module_dict);
|
||||
if (res) {
|
||||
Py_DecRef(res);
|
||||
}
|
||||
|
||||
cleanup:
|
||||
// un-transfer the environment variables
|
||||
envEnumerator = [newEnviron keyEnumerator];
|
||||
while ((envKey = [envEnumerator nextObject])) {
|
||||
char *keyString = (char *)[envKey UTF8String];
|
||||
NSString *newValue = [oldEnviron objectForKey:envKey];
|
||||
if (newValue) {
|
||||
setenv(keyString, [newValue UTF8String], 1);
|
||||
} else {
|
||||
unsetenv(keyString);
|
||||
}
|
||||
}
|
||||
|
||||
if (mainPyFile) {
|
||||
fclose(mainPyFile);
|
||||
}
|
||||
if (PyErr_Occurred()) {
|
||||
rval = -1;
|
||||
PyErr_Print();
|
||||
}
|
||||
while ( rval ) {
|
||||
PyObject *exc = PySys_GetObject("last_type");
|
||||
if ( !exc ) {
|
||||
rval = report_error([NSString stringWithFormat:ERR_PYTHONEXCEPTION,"<<PyMacAppException>>","The exception went away?"]);
|
||||
break;
|
||||
}
|
||||
|
||||
PyObject *exceptionClassName = PyObject_GetAttrString(exc, "__name__");
|
||||
if ( !exceptionClassName ) {
|
||||
rval = report_error([NSString stringWithFormat:ERR_PYTHONEXCEPTION,"<<PyMacAppException>>","Could not get exception class name?"]);
|
||||
break;
|
||||
}
|
||||
|
||||
PyObject *v = PySys_GetObject("last_value");
|
||||
PyObject *exceptionName = NULL;
|
||||
if ( v )
|
||||
exceptionName = PyObject_Str(v);
|
||||
|
||||
PyObject *b = PyObject_CallMethod(exceptionClassName, "encode", "s", "utf-8");
|
||||
NSString *nsExceptionClassName = [NSString stringWithCString:PyBytes_AsString(b) encoding:NSUTF8StringEncoding];
|
||||
Py_DecRef(exceptionClassName);Py_DecRef(b);
|
||||
NSString *nsExceptionName;
|
||||
if ( exceptionName ) {
|
||||
PyObject *b = PyObject_CallMethod(exceptionName, "encode", "s", "utf-8");
|
||||
nsExceptionName = [NSString stringWithCString:PyBytes_AsString(b) encoding:NSUTF8StringEncoding];
|
||||
Py_DecRef(exceptionName);Py_DecRef(b);
|
||||
} else {
|
||||
nsExceptionName = @"";
|
||||
}
|
||||
rval = report_script_error([NSString stringWithFormat:ERR_PYTHONEXCEPTION, nsExceptionClassName, nsExceptionName], nsExceptionClassName, nsExceptionName);
|
||||
break;
|
||||
}
|
||||
PyErr_Clear();
|
||||
PyGILState_Release(gilState);
|
||||
if (gilState == PyGILState_LOCKED) {
|
||||
PyThreadState_Swap(NULL);
|
||||
PyEval_ReleaseLock();
|
||||
}
|
||||
|
||||
return rval;
|
||||
}
|
||||
|
||||
|
||||
static
|
||||
void _py2app_bundle_load(void)
|
||||
{
|
||||
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
|
||||
int argc = 1;
|
||||
char * const argv[] = { (char *)bundlePath(), NULL };
|
||||
char * const *envp = *_NSGetEnviron();
|
||||
(void)pyobjc_main(argc, argv, envp);
|
||||
[pool release];
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user