python3-stdlib-extensions-3.4.0/0000755000000000000000000000000012313512422013457 5ustar python3-stdlib-extensions-3.4.0/build-stamp0000644000000000000000000000000012313512322015610 0ustar python3-stdlib-extensions-3.4.0/3.4/0000755000000000000000000000000012313512422013763 5ustar python3-stdlib-extensions-3.4.0/3.4/setup.py0000644000000000000000000010564712124366261015522 0ustar # Autodetecting setup.py script for building the Python extensions # import sys, os, imp, re, optparse from glob import glob import sysconfig from distutils import log from distutils import text_file from distutils.errors import * from distutils.core import Extension, setup from distutils.command.build_ext import build_ext from distutils.command.install import install from distutils.command.install_lib import install_lib from distutils.command.build_scripts import build_scripts from distutils.spawn import find_executable cross_compiling = "_PYTHON_HOST_PLATFORM" in os.environ def get_platform(): # cross build if "_PYTHON_HOST_PLATFORM" in os.environ: return os.environ["_PYTHON_HOST_PLATFORM"] # Get value of sys.platform if sys.platform.startswith('osf1'): return 'osf1' return sys.platform host_platform = get_platform() # Were we compiled --with-pydebug or with #define Py_DEBUG? COMPILED_WITH_PYDEBUG = ('--with-pydebug' in sysconfig.get_config_var("CONFIG_ARGS")) # This global variable is used to hold the list of modules to be disabled. disabled_module_list = [] def add_dir_to_list(dirlist, dir): """Add the directory 'dir' to the list 'dirlist' (after any relative directories) if: 1) 'dir' is not already in 'dirlist' 2) 'dir' actually exists, and is a directory. """ if dir is None or not os.path.isdir(dir) or dir in dirlist: return for i, path in enumerate(dirlist): if not os.path.isabs(path): dirlist.insert(i + 1, dir) return dirlist.insert(0, dir) def macosx_sdk_root(): """ Return the directory of the current OSX SDK, or '/' if no SDK was specified. """ cflags = sysconfig.get_config_var('CFLAGS') m = re.search(r'-isysroot\s+(\S+)', cflags) if m is None: sysroot = '/' else: sysroot = m.group(1) return sysroot def is_macosx_sdk_path(path): """ Returns True if 'path' can be located in an OSX SDK """ return ( (path.startswith('/usr/') and not path.startswith('/usr/local')) or path.startswith('/System/') or path.startswith('/Library/') ) def find_file(filename, std_dirs, paths): """Searches for the directory where a given file is located, and returns a possibly-empty list of additional directories, or None if the file couldn't be found at all. 'filename' is the name of a file, such as readline.h or libcrypto.a. 'std_dirs' is the list of standard system directories; if the file is found in one of them, no additional directives are needed. 'paths' is a list of additional locations to check; if the file is found in one of them, the resulting list will contain the directory. """ if host_platform == 'darwin': # Honor the MacOSX SDK setting when one was specified. # An SDK is a directory with the same structure as a real # system, but with only header files and libraries. sysroot = macosx_sdk_root() # Check the standard locations for dir in std_dirs: f = os.path.join(dir, filename) if host_platform == 'darwin' and is_macosx_sdk_path(dir): f = os.path.join(sysroot, dir[1:], filename) if os.path.exists(f): return [] # Check the additional directories for dir in paths: f = os.path.join(dir, filename) if host_platform == 'darwin' and is_macosx_sdk_path(dir): f = os.path.join(sysroot, dir[1:], filename) if os.path.exists(f): return [dir] # Not found anywhere return None def find_library_file(compiler, libname, std_dirs, paths): result = compiler.find_library_file(std_dirs + paths, libname) if result is None: return None if host_platform == 'darwin': sysroot = macosx_sdk_root() # Check whether the found file is in one of the standard directories dirname = os.path.dirname(result) for p in std_dirs: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) if host_platform == 'darwin' and is_macosx_sdk_path(p): if os.path.join(sysroot, p[1:]) == dirname: return [ ] if p == dirname: return [ ] # Otherwise, it must have been in one of the additional directories, # so we have to figure out which one. for p in paths: # Ensure path doesn't end with path separator p = p.rstrip(os.sep) if host_platform == 'darwin' and is_macosx_sdk_path(p): if os.path.join(sysroot, p[1:]) == dirname: return [ p ] if p == dirname: return [p] else: assert False, "Internal error: Path not found in std_dirs or paths" def module_enabled(extlist, modname): """Returns whether the module 'modname' is present in the list of extensions 'extlist'.""" extlist = [ext for ext in extlist if ext.name == modname] return len(extlist) def find_module_file(module, dirlist): """Find a module in a set of possible folders. If it is not found return the unadorned filename""" list = find_file(module, [], dirlist) if not list: return module if len(list) > 1: log.info("WARNING: multiple copies of %s found"%module) return os.path.join(list[0], module) class PyBuildExt(build_ext): def __init__(self, dist): build_ext.__init__(self, dist) self.failed = [] def build_extensions(self): # Detect which modules should be compiled old_so = self.compiler.shared_lib_extension # Workaround PEP 3149 stuff self.compiler.shared_lib_extension = os.environ.get("SO", ".so") try: missing = self.detect_modules() finally: self.compiler.shared_lib_extension = old_so # Remove modules that are present on the disabled list extensions = [ext for ext in self.extensions if ext.name not in disabled_module_list] # move ctypes to the end, it depends on other modules ext_map = dict((ext.name, i) for i, ext in enumerate(extensions)) if "_ctypes" in ext_map: ctypes = extensions.pop(ext_map["_ctypes"]) extensions.append(ctypes) self.extensions = extensions # Fix up the autodetected modules, prefixing all the source files # with Modules/. srcdir = sysconfig.get_config_var('srcdir') if not srcdir: # Maybe running on Windows but not using CYGWIN? raise ValueError("No source directory; cannot proceed.") srcdir = os.path.abspath(srcdir) moddirlist = [os.path.join(srcdir, 'Modules')] # Fix up the paths for scripts, too self.distribution.scripts = [os.path.join(srcdir, filename) for filename in self.distribution.scripts] # Python header files headers = [sysconfig.get_config_h_filename()] headers += glob(os.path.join(sysconfig.get_path('include'), "*.h")) for ext in self.extensions[:]: ext.sources = [ find_module_file(filename, moddirlist) for filename in ext.sources ] if ext.depends is not None: ext.depends = [find_module_file(filename, moddirlist) for filename in ext.depends] else: ext.depends = [] # re-compile extensions if a header file has been changed ext.depends.extend(headers) # If a module has already been built statically, # don't build it here if ext.name in sys.builtin_module_names: self.extensions.remove(ext) # Parse Modules/Setup and Modules/Setup.local to figure out which # modules are turned on in the file. remove_modules = [] for filename in ('Modules/Setup', 'Modules/Setup.local'): input = text_file.TextFile(filename, join_lines=1) while 1: line = input.readline() if not line: break line = line.split() remove_modules.append(line[0]) input.close() for ext in self.extensions[:]: if ext.name in remove_modules: self.extensions.remove(ext) # When you run "make CC=altcc" or something similar, you really want # those environment variables passed into the setup.py phase. Here's # a small set of useful ones. compiler = os.environ.get('CC') args = {} # unfortunately, distutils doesn't let us provide separate C and C++ # compilers if compiler is not None: (ccshared, cppflags, cflags) = \ sysconfig.get_config_vars('CCSHARED', 'CPPFLAGS', 'CFLAGS') cppflags = ' '.join([f for f in cppflags.split() if not f.startswith('-I')]) args['compiler_so'] = compiler + ' ' + ccshared + ' ' + cppflags + ' ' + cflags self.compiler.set_executables(**args) build_ext.build_extensions(self) longest = max([len(e.name) for e in self.extensions]) if self.failed: longest = max(longest, max([len(name) for name in self.failed])) def print_three_column(lst): lst.sort(key=str.lower) # guarantee zip() doesn't drop anything while len(lst) % 3: lst.append("") for e, f, g in zip(lst[::3], lst[1::3], lst[2::3]): print("%-*s %-*s %-*s" % (longest, e, longest, f, longest, g)) if missing: print() print("Python build finished, but the necessary bits to build " "these modules were not found:") print_three_column(missing) print("To find the necessary bits, look in setup.py in" " detect_modules() for the module's name.") print() if self.failed: failed = self.failed[:] print() print("Failed to build these modules:") print_three_column(failed) print() def build_extension(self, ext): if ext.name == '_ctypes': if not self.configure_ctypes(ext): return try: build_ext.build_extension(self, ext) except (CCompilerError, DistutilsError) as why: self.announce('WARNING: building of extension "%s" failed: %s' % (ext.name, sys.exc_info()[1])) self.failed.append(ext.name) return # Workaround for Mac OS X: The Carbon-based modules cannot be # reliably imported into a command-line Python if 'Carbon' in ext.extra_link_args: self.announce( 'WARNING: skipping import check for Carbon-based "%s"' % ext.name) return if host_platform == 'darwin' and ( sys.maxsize > 2**32 and '-arch' in ext.extra_link_args): # Don't bother doing an import check when an extension was # build with an explicit '-arch' flag on OSX. That's currently # only used to build 32-bit only extensions in a 4-way # universal build and loading 32-bit code into a 64-bit # process will fail. self.announce( 'WARNING: skipping import check for "%s"' % ext.name) return # Workaround for Cygwin: Cygwin currently has fork issues when many # modules have been imported if host_platform == 'cygwin': self.announce('WARNING: skipping import check for Cygwin-based "%s"' % ext.name) return ext_filename = os.path.join( self.build_lib, self.get_ext_filename(self.get_ext_fullname(ext.name))) # If the build directory didn't exist when setup.py was # started, sys.path_importer_cache has a negative result # cached. Clear that cache before trying to import. sys.path_importer_cache.clear() # Don't try to load extensions for cross builds if cross_compiling: return try: imp.load_dynamic(ext.name, ext_filename) except ImportError as why: self.failed.append(ext.name) self.announce('*** WARNING: renaming "%s" since importing it' ' failed: %s' % (ext.name, why), level=3) assert not self.inplace basename, tail = os.path.splitext(ext_filename) newname = basename + "_failed" + tail if os.path.exists(newname): os.remove(newname) os.rename(ext_filename, newname) # XXX -- This relies on a Vile HACK in # distutils.command.build_ext.build_extension(). The # _built_objects attribute is stored there strictly for # use here. # If there is a failure, _built_objects may not be there, # so catch the AttributeError and move on. try: for filename in self._built_objects: os.remove(filename) except AttributeError: self.announce('unable to remove files (ignored)') except: exc_type, why, tb = sys.exc_info() self.announce('*** WARNING: importing extension "%s" ' 'failed with %s: %s' % (ext.name, exc_type, why), level=3) self.failed.append(ext.name) def add_multiarch_paths(self): # Debian/Ubuntu multiarch support. # https://wiki.ubuntu.com/MultiarchSpec cc = sysconfig.get_config_var('CC') tmpfile = os.path.join(self.build_temp, 'multiarch') if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) ret = os.system( '%s -print-multiarch > %s 2> /dev/null' % (cc, tmpfile)) multiarch_path_component = '' try: if ret >> 8 == 0: with open(tmpfile) as fp: multiarch_path_component = fp.readline().strip() finally: os.unlink(tmpfile) if multiarch_path_component != '': add_dir_to_list(self.compiler.library_dirs, '/usr/lib/' + multiarch_path_component) add_dir_to_list(self.compiler.include_dirs, '/usr/include/' + multiarch_path_component) return if not find_executable('dpkg-architecture'): return opt = '' if cross_compiling: opt = '-t' + sysconfig.get_config_var('HOST_GNU_TYPE') tmpfile = os.path.join(self.build_temp, 'multiarch') if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) ret = os.system( 'dpkg-architecture %s -qDEB_HOST_MULTIARCH > %s 2> /dev/null' % (opt, tmpfile)) try: if ret >> 8 == 0: with open(tmpfile) as fp: multiarch_path_component = fp.readline().strip() add_dir_to_list(self.compiler.library_dirs, '/usr/lib/' + multiarch_path_component) add_dir_to_list(self.compiler.include_dirs, '/usr/include/' + multiarch_path_component) finally: os.unlink(tmpfile) def add_gcc_paths(self): gcc = sysconfig.get_config_var('CC') tmpfile = os.path.join(self.build_temp, 'gccpaths') if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) ret = os.system('%s -E -v - %s 1>/dev/null' % (gcc, tmpfile)) is_gcc = False in_incdirs = False inc_dirs = [] lib_dirs = [] try: if ret >> 8 == 0: with open(tmpfile) as fp: for line in fp.readlines(): if line.startswith("gcc version"): is_gcc = True elif line.startswith("#include <...>"): in_incdirs = True elif line.startswith("End of search list"): in_incdirs = False elif is_gcc and line.startswith("LIBRARY_PATH"): for d in line.strip().split("=")[1].split(":"): d = os.path.normpath(d) if '/gcc/' not in d: add_dir_to_list(self.compiler.library_dirs, d) elif is_gcc and in_incdirs and '/gcc/' not in line: add_dir_to_list(self.compiler.include_dirs, line.strip()) finally: os.unlink(tmpfile) def detect_modules(self): # On Debian /usr/local is always used, so we don't include it twice # only change this for cross builds for 3.3, issues on Mageia if cross_compiling: self.add_gcc_paths() self.add_multiarch_paths() # Add paths specified in the environment variables LDFLAGS and # CPPFLAGS for header and library files. # We must get the values from the Makefile and not the environment # directly since an inconsistently reproducible issue comes up where # the environment variable is not set even though the value were passed # into configure and stored in the Makefile (issue found on OS X 10.3). for env_var, arg_name, dir_list in ( ('LDFLAGS', '-R', self.compiler.runtime_library_dirs), ('LDFLAGS', '-L', self.compiler.library_dirs), ('CPPFLAGS', '-I', self.compiler.include_dirs)): env_val = sysconfig.get_config_var(env_var) if env_val: # To prevent optparse from raising an exception about any # options in env_val that it doesn't know about we strip out # all double dashes and any dashes followed by a character # that is not for the option we are dealing with. # # Please note that order of the regex is important! We must # strip out double-dashes first so that we don't end up with # substituting "--Long" to "-Long" and thus lead to "ong" being # used for a library directory. env_val = re.sub(r'(^|\s+)-(-|(?!%s))' % arg_name[1], ' ', env_val) parser = optparse.OptionParser() # Make sure that allowing args interspersed with options is # allowed parser.allow_interspersed_args = True parser.error = lambda msg: None parser.add_option(arg_name, dest="dirs", action="append") options = parser.parse_args(env_val.split())[0] if options.dirs: for directory in reversed(options.dirs): add_dir_to_list(dir_list, directory) if os.path.normpath(sys.base_prefix) != '/usr' \ and not sysconfig.get_config_var('PYTHONFRAMEWORK'): # OSX note: Don't add LIBDIR and INCLUDEDIR to building a framework # (PYTHONFRAMEWORK is set) to avoid # linking problems when # building a framework with different architectures than # the one that is currently installed (issue #7473) add_dir_to_list(self.compiler.library_dirs, sysconfig.get_config_var("LIBDIR")) add_dir_to_list(self.compiler.include_dirs, sysconfig.get_config_var("INCLUDEDIR")) # lib_dirs and inc_dirs are used to search for files; # if a file is found in one of those directories, it can # be assumed that no additional -I,-L directives are needed. if not cross_compiling: lib_dirs = self.compiler.library_dirs + [ '/lib64', '/usr/lib64', '/lib', '/usr/lib', ] inc_dirs = self.compiler.include_dirs + ['/usr/include'] else: lib_dirs = self.compiler.library_dirs[:] inc_dirs = self.compiler.include_dirs[:] exts = [] missing = [] config_h = sysconfig.get_config_h_filename() with open(config_h) as file: config_h_vars = sysconfig.parse_config_h(file) srcdir = sysconfig.get_config_var('srcdir') # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb) if host_platform in ['osf1', 'unixware7', 'openunix8']: lib_dirs += ['/usr/ccs/lib'] # HP-UX11iv3 keeps files in lib/hpux folders. if host_platform == 'hp-ux11': lib_dirs += ['/usr/lib/hpux64', '/usr/lib/hpux32'] if host_platform == 'darwin': # This should work on any unixy platform ;-) # If the user has bothered specifying additional -I and -L flags # in OPT and LDFLAGS we might as well use them here. # # NOTE: using shlex.split would technically be more correct, but # also gives a bootstrap problem. Let's hope nobody uses # directories with whitespace in the name to store libraries. cflags, ldflags = sysconfig.get_config_vars( 'CFLAGS', 'LDFLAGS') for item in cflags.split(): if item.startswith('-I'): inc_dirs.append(item[2:]) for item in ldflags.split(): if item.startswith('-L'): lib_dirs.append(item[2:]) # Check for MacOS X, which doesn't need libm.a at all math_libs = ['m'] if host_platform == 'darwin': math_libs = [] # XXX Omitted modules: gl, pure, dl, SGI-specific modules # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm: if (True or 'gdbm' in dbm_order and self.compiler.find_library_file(lib_dirs, 'gdbm')): exts.append( Extension('_gdbm', ['Modules/_gdbmmodule.c'], libraries = ['gdbm'] ) ) else: missing.append('_gdbm') self.extensions.extend(exts) # Call the method for detecting whether _tkinter can be compiled self.detect_tkinter(inc_dirs, lib_dirs) if '_tkinter' not in [e.name for e in self.extensions]: missing.append('_tkinter') return missing def detect_tkinter_darwin(self, inc_dirs, lib_dirs): # The _tkinter module, using frameworks. Since frameworks are quite # different the UNIX search logic is not sharable. from os.path import join, exists framework_dirs = [ '/Library/Frameworks', '/System/Library/Frameworks/', join(os.getenv('HOME'), '/Library/Frameworks') ] sysroot = macosx_sdk_root() # Find the directory that contains the Tcl.framework and Tk.framework # bundles. # XXX distutils should support -F! for F in framework_dirs: # both Tcl.framework and Tk.framework should be present for fw in 'Tcl', 'Tk': if is_macosx_sdk_path(F): if not exists(join(sysroot, F[1:], fw + '.framework')): break else: if not exists(join(F, fw + '.framework')): break else: # ok, F is now directory with both frameworks. Continure # building break else: # Tk and Tcl frameworks not found. Normal "unix" tkinter search # will now resume. return 0 # For 8.4a2, we must add -I options that point inside the Tcl and Tk # frameworks. In later release we should hopefully be able to pass # the -F option to gcc, which specifies a framework lookup path. # include_dirs = [ join(F, fw + '.framework', H) for fw in ('Tcl', 'Tk') for H in ('Headers', 'Versions/Current/PrivateHeaders') ] # For 8.4a2, the X11 headers are not included. Rather than include a # complicated search, this is a hard-coded path. It could bail out # if X11 libs are not found... include_dirs.append('/usr/X11R6/include') frameworks = ['-framework', 'Tcl', '-framework', 'Tk'] # All existing framework builds of Tcl/Tk don't support 64-bit # architectures. cflags = sysconfig.get_config_vars('CFLAGS')[0] archs = re.findall('-arch\s+(\w+)', cflags) tmpfile = os.path.join(self.build_temp, 'tk.arch') if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) # Note: cannot use os.popen or subprocess here, that # requires extensions that are not available here. if is_macosx_sdk_path(F): os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(os.path.join(sysroot, F[1:]), tmpfile)) else: os.system("file %s/Tk.framework/Tk | grep 'for architecture' > %s"%(F, tmpfile)) with open(tmpfile) as fp: detected_archs = [] for ln in fp: a = ln.split()[-1] if a in archs: detected_archs.append(ln.split()[-1]) os.unlink(tmpfile) for a in detected_archs: frameworks.append('-arch') frameworks.append(a) ext = Extension('_tkinter', ['_tkinter.c', 'tkappinit.c'], define_macros=[('WITH_APPINIT', 1)], include_dirs = include_dirs, libraries = [], extra_compile_args = frameworks[2:], extra_link_args = frameworks, ) self.extensions.append(ext) return 1 def detect_tkinter(self, inc_dirs, lib_dirs): # The _tkinter module. # Rather than complicate the code below, detecting and building # AquaTk is a separate method. Only one Tkinter will be built on # Darwin - either AquaTk, if it is found, or X11 based Tk. if (host_platform == 'darwin' and self.detect_tkinter_darwin(inc_dirs, lib_dirs)): return # Assume we haven't found any of the libraries or include files # The versions with dots are used on Unix, and the versions without # dots on Windows, for detection by cygwin. tcllib = tklib = tcl_includes = tk_includes = None for version in ['8.6', '86', '8.5', '85', '8.4', '84', '8.3', '83', '8.2', '82', '8.1', '81', '8.0', '80']: tklib = self.compiler.find_library_file(lib_dirs, 'tk' + version) tcllib = self.compiler.find_library_file(lib_dirs, 'tcl' + version) if tklib and tcllib: # Exit the loop when we've found the Tcl/Tk libraries break # Now check for the header files if tklib and tcllib: # Check for the include files on Debian and {Free,Open}BSD, where # they're put in /usr/include/{tcl,tk}X.Y dotversion = version if '.' not in dotversion and "bsd" in host_platform.lower(): # OpenBSD and FreeBSD use Tcl/Tk library names like libtcl83.a, # but the include subdirs are named like .../include/tcl8.3. dotversion = dotversion[:-1] + '.' + dotversion[-1] tcl_include_sub = [] tk_include_sub = [] for dir in inc_dirs: tcl_include_sub += [dir + os.sep + "tcl" + dotversion] tk_include_sub += [dir + os.sep + "tk" + dotversion] tk_include_sub += tcl_include_sub tcl_includes = find_file('tcl.h', inc_dirs, tcl_include_sub) tk_includes = find_file('tk.h', inc_dirs, tk_include_sub) if (tcllib is None or tklib is None or tcl_includes is None or tk_includes is None): self.announce("INFO: Can't locate Tcl/Tk libs and/or headers", 2) return # OK... everything seems to be present for Tcl/Tk. include_dirs = [] ; libs = [] ; defs = [] ; added_lib_dirs = [] for dir in tcl_includes + tk_includes: if dir not in include_dirs: include_dirs.append(dir) # Check for various platform-specific directories if host_platform == 'sunos5': include_dirs.append('/usr/openwin/include') added_lib_dirs.append('/usr/openwin/lib') elif os.path.exists('/usr/X11R6/include'): include_dirs.append('/usr/X11R6/include') added_lib_dirs.append('/usr/X11R6/lib64') added_lib_dirs.append('/usr/X11R6/lib') elif os.path.exists('/usr/X11R5/include'): include_dirs.append('/usr/X11R5/include') added_lib_dirs.append('/usr/X11R5/lib') else: # Assume default location for X11 include_dirs.append('/usr/X11/include') added_lib_dirs.append('/usr/X11/lib') # If Cygwin, then verify that X is installed before proceeding if host_platform == 'cygwin': x11_inc = find_file('X11/Xlib.h', [], include_dirs) if x11_inc is None: return # Check for BLT extension if self.compiler.find_library_file(lib_dirs + added_lib_dirs, 'BLT8.0'): defs.append( ('WITH_BLT', 1) ) libs.append('BLT8.0') elif self.compiler.find_library_file(lib_dirs + added_lib_dirs, 'BLT'): defs.append( ('WITH_BLT', 1) ) libs.append('BLT') # Add the Tcl/Tk libraries libs.append('tk'+ version) libs.append('tcl'+ version) if host_platform in ['aix3', 'aix4']: libs.append('ld') # Finally, link with the X11 libraries (not appropriate on cygwin) if host_platform != "cygwin": libs.append('X11') ext = Extension('_tkinter', ['Modules/_tkinter.c', 'Modules/tkappinit.c'], define_macros=[('WITH_APPINIT', 1)] + defs, include_dirs = include_dirs, libraries = libs, library_dirs = added_lib_dirs, ) self.extensions.append(ext) # XXX handle these, but how to detect? # *** Uncomment and edit for PIL (TkImaging) extension only: # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ # *** Uncomment and edit for TOGL extension only: # -DWITH_TOGL togl.c \ # *** Uncomment these for TOGL extension only: # -lGL -lGLU -lXext -lXmu \ class PyBuildInstall(install): # Suppress the warning about installation into the lib_dynload # directory, which is not in sys.path when running Python during # installation: def initialize_options (self): install.initialize_options(self) self.warn_dir=0 class PyBuildInstallLib(install_lib): # Do exactly what install_lib does but make sure correct access modes get # set on installed directories and files. All installed files with get # mode 644 unless they are a shared library in which case they will get # mode 755. All installed directories will get mode 755. so_ext = sysconfig.get_config_var("SO") def install(self): outfiles = install_lib.install(self) self.set_file_modes(outfiles, 0o644, 0o755) self.set_dir_modes(self.install_dir, 0o755) return outfiles def set_file_modes(self, files, defaultMode, sharedLibMode): if not self.is_chmod_supported(): return if not files: return for filename in files: if os.path.islink(filename): continue mode = defaultMode if filename.endswith(self.so_ext): mode = sharedLibMode log.info("changing mode of %s to %o", filename, mode) if not self.dry_run: os.chmod(filename, mode) def set_dir_modes(self, dirname, mode): if not self.is_chmod_supported(): return for dirpath, dirnames, fnames in os.walk(dirname): if os.path.islink(dirpath): continue log.info("changing mode of %s to %o", dirpath, mode) if not self.dry_run: os.chmod(dirpath, mode) def is_chmod_supported(self): return hasattr(os, 'chmod') SUMMARY = """ Python is an interpreted, interactive, object-oriented programming language. It is often compared to Tcl, Perl, Scheme or Java. Python combines remarkable power with very clear syntax. It has modules, classes, exceptions, very high level dynamic data types, and dynamic typing. There are interfaces to many system calls and libraries, as well as to various windowing systems (X11, Motif, Tk, Mac, MFC). New built-in modules are easily written in C or C++. Python is also usable as an extension language for applications that need a programmable interface. The Python implementation is portable: it runs on many brands of UNIX, on Windows, DOS, OS/2, Mac, Amiga... If your favorite system isn't listed here, it may still be supported, if there's a C compiler for it. Ask around on comp.lang.python -- or just try compiling Python yourself. """ CLASSIFIERS = """ Development Status :: 6 - Mature License :: OSI Approved :: Python Software Foundation License Natural Language :: English Programming Language :: C Programming Language :: Python Topic :: Software Development """ def main(): # turn off warnings when deprecated modules are imported import warnings warnings.filterwarnings("ignore",category=DeprecationWarning) setup(# PyPI Metadata (PEP 301) name = "Python", version = sys.version.split()[0], url = "http://www.python.org/%s" % sys.version[:3], maintainer = "Guido van Rossum and the Python community", maintainer_email = "python-dev@python.org", description = "A high-level object-oriented programming language", long_description = SUMMARY.strip(), license = "PSF license", classifiers = [x for x in CLASSIFIERS.split("\n") if x], platforms = ["Many"], # Build info cmdclass = {'build_ext': PyBuildExt, 'install': PyBuildInstall, 'install_lib': PyBuildInstallLib}, # The struct module is defined here, because build_ext won't be # called unless there's at least one extension module defined. ext_modules=[Extension('_struct', ['_struct.c'])], # If you change the scripts installed here, you also need to # check the PyBuildScripts command above, and change the links # created by the bininstall target in Makefile.pre.in scripts = [] ) # --install-platlib if __name__ == '__main__': main() python3-stdlib-extensions-3.4.0/3.4/Modules/0000755000000000000000000000000011740525160015401 5ustar python3-stdlib-extensions-3.4.0/3.4/Modules/_gdbmmodule.c0000644000000000000000000004240512313511423020022 0ustar /* DBM module using dictionary interface */ /* Author: Anthony Baxter, after dbmmodule.c */ /* Doc strings: Mitch Chapman */ #include "Python.h" #include #include #include #include "gdbm.h" #if defined(WIN32) && !defined(__CYGWIN__) #include "gdbmerrno.h" extern const char * gdbm_strerror(gdbm_error); #endif PyDoc_STRVAR(gdbmmodule__doc__, "This module provides an interface to the GNU DBM (GDBM) library.\n\ \n\ This module is quite similar to the dbm module, but uses GDBM instead to\n\ provide some additional functionality. Please note that the file formats\n\ created by GDBM and dbm are incompatible. \n\ \n\ GDBM objects behave like mappings (dictionaries), except that keys and\n\ values are always strings. Printing a GDBM object doesn't print the\n\ keys and values, and the items() and values() methods are not\n\ supported."); typedef struct { PyObject_HEAD int di_size; /* -1 means recompute */ GDBM_FILE di_dbm; } dbmobject; static PyTypeObject Dbmtype; #define is_dbmobject(v) (Py_TYPE(v) == &Dbmtype) #define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \ { PyErr_SetString(DbmError, "GDBM object has already been closed"); \ return NULL; } static PyObject *DbmError; PyDoc_STRVAR(gdbm_object__doc__, "This object represents a GDBM database.\n\ GDBM objects behave like mappings (dictionaries), except that keys and\n\ values are always strings. Printing a GDBM object doesn't print the\n\ keys and values, and the items() and values() methods are not\n\ supported.\n\ \n\ GDBM objects also support additional operations such as firstkey,\n\ nextkey, reorganize, and sync."); static PyObject * newdbmobject(char *file, int flags, int mode) { dbmobject *dp; dp = PyObject_New(dbmobject, &Dbmtype); if (dp == NULL) return NULL; dp->di_size = -1; errno = 0; if ((dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0) { if (errno != 0) PyErr_SetFromErrno(DbmError); else PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); Py_DECREF(dp); return NULL; } return (PyObject *)dp; } /* Methods */ static void dbm_dealloc(dbmobject *dp) { if (dp->di_dbm) gdbm_close(dp->di_dbm); PyObject_Del(dp); } static Py_ssize_t dbm_length(dbmobject *dp) { if (dp->di_dbm == NULL) { PyErr_SetString(DbmError, "GDBM object has already been closed"); return -1; } if (dp->di_size < 0) { datum key,okey; int size; okey.dsize=0; okey.dptr=NULL; size = 0; for (key=gdbm_firstkey(dp->di_dbm); key.dptr; key = gdbm_nextkey(dp->di_dbm,okey)) { size++; if(okey.dsize) free(okey.dptr); okey=key; } dp->di_size = size; } return dp->di_size; } static PyObject * dbm_subscript(dbmobject *dp, PyObject *key) { PyObject *v; datum drec, krec; if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) ) return NULL; if (dp->di_dbm == NULL) { PyErr_SetString(DbmError, "GDBM object has already been closed"); return NULL; } drec = gdbm_fetch(dp->di_dbm, krec); if (drec.dptr == 0) { PyErr_SetObject(PyExc_KeyError, key); return NULL; } v = PyBytes_FromStringAndSize(drec.dptr, drec.dsize); free(drec.dptr); return v; } PyDoc_STRVAR(dbm_get__doc__, "get(key[, default]) -> value\n\ Get the value for key, or default if not present; if not given,\n\ default is None."); static PyObject * dbm_get(dbmobject *dp, PyObject *args) { PyObject *v, *res; PyObject *def = Py_None; if (!PyArg_UnpackTuple(args, "get", 1, 2, &v, &def)) return NULL; res = dbm_subscript(dp, v); if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Clear(); Py_INCREF(def); return def; } return res; } static int dbm_ass_sub(dbmobject *dp, PyObject *v, PyObject *w) { datum krec, drec; if (!PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) { PyErr_SetString(PyExc_TypeError, "gdbm mappings have bytes or string indices only"); return -1; } if (dp->di_dbm == NULL) { PyErr_SetString(DbmError, "GDBM object has already been closed"); return -1; } dp->di_size = -1; if (w == NULL) { if (gdbm_delete(dp->di_dbm, krec) < 0) { PyErr_SetObject(PyExc_KeyError, v); return -1; } } else { if (!PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize)) { PyErr_SetString(PyExc_TypeError, "gdbm mappings have byte or string elements only"); return -1; } errno = 0; if (gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0) { if (errno != 0) PyErr_SetFromErrno(DbmError); else PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); return -1; } } return 0; } PyDoc_STRVAR(dbm_setdefault__doc__, "setdefault(key[, default]) -> value\n\ Get value for key, or set it to default and return default if not present;\n\ if not given, default is None."); static PyObject * dbm_setdefault(dbmobject *dp, PyObject *args) { PyObject *v, *res; PyObject *def = Py_None; if (!PyArg_UnpackTuple(args, "setdefault", 1, 2, &v, &def)) return NULL; res = dbm_subscript(dp, v); if (res == NULL && PyErr_ExceptionMatches(PyExc_KeyError)) { PyErr_Clear(); if (dbm_ass_sub(dp, v, def) < 0) return NULL; return dbm_subscript(dp, v); } return res; } static PyMappingMethods dbm_as_mapping = { (lenfunc)dbm_length, /*mp_length*/ (binaryfunc)dbm_subscript, /*mp_subscript*/ (objobjargproc)dbm_ass_sub, /*mp_ass_subscript*/ }; PyDoc_STRVAR(dbm_close__doc__, "close() -> None\n\ Closes the database."); static PyObject * dbm_close(dbmobject *dp, PyObject *unused) { if (dp->di_dbm) gdbm_close(dp->di_dbm); dp->di_dbm = NULL; Py_INCREF(Py_None); return Py_None; } /* XXX Should return a set or a set view */ PyDoc_STRVAR(dbm_keys__doc__, "keys() -> list_of_keys\n\ Get a list of all keys in the database."); static PyObject * dbm_keys(dbmobject *dp, PyObject *unused) { PyObject *v, *item; datum key, nextkey; int err; if (dp == NULL || !is_dbmobject(dp)) { PyErr_BadInternalCall(); return NULL; } check_dbmobject_open(dp); v = PyList_New(0); if (v == NULL) return NULL; key = gdbm_firstkey(dp->di_dbm); while (key.dptr) { item = PyBytes_FromStringAndSize(key.dptr, key.dsize); if (item == NULL) { free(key.dptr); Py_DECREF(v); return NULL; } err = PyList_Append(v, item); Py_DECREF(item); if (err != 0) { free(key.dptr); Py_DECREF(v); return NULL; } nextkey = gdbm_nextkey(dp->di_dbm, key); free(key.dptr); key = nextkey; } return v; } static int dbm_contains(PyObject *self, PyObject *arg) { dbmobject *dp = (dbmobject *)self; datum key; Py_ssize_t size; if ((dp)->di_dbm == NULL) { PyErr_SetString(DbmError, "GDBM object has already been closed"); return -1; } if (PyUnicode_Check(arg)) { key.dptr = PyUnicode_AsUTF8AndSize(arg, &size); key.dsize = size; if (key.dptr == NULL) return -1; } else if (!PyBytes_Check(arg)) { PyErr_Format(PyExc_TypeError, "gdbm key must be bytes or string, not %.100s", arg->ob_type->tp_name); return -1; } else { key.dptr = PyBytes_AS_STRING(arg); key.dsize = PyBytes_GET_SIZE(arg); } return gdbm_exists(dp->di_dbm, key); } static PySequenceMethods dbm_as_sequence = { 0, /* sq_length */ 0, /* sq_concat */ 0, /* sq_repeat */ 0, /* sq_item */ 0, /* sq_slice */ 0, /* sq_ass_item */ 0, /* sq_ass_slice */ dbm_contains, /* sq_contains */ 0, /* sq_inplace_concat */ 0, /* sq_inplace_repeat */ }; PyDoc_STRVAR(dbm_firstkey__doc__, "firstkey() -> key\n\ It's possible to loop over every key in the database using this method\n\ and the nextkey() method. The traversal is ordered by GDBM's internal\n\ hash values, and won't be sorted by the key values. This method\n\ returns the starting key."); static PyObject * dbm_firstkey(dbmobject *dp, PyObject *unused) { PyObject *v; datum key; check_dbmobject_open(dp); key = gdbm_firstkey(dp->di_dbm); if (key.dptr) { v = PyBytes_FromStringAndSize(key.dptr, key.dsize); free(key.dptr); return v; } else { Py_INCREF(Py_None); return Py_None; } } PyDoc_STRVAR(dbm_nextkey__doc__, "nextkey(key) -> next_key\n\ Returns the key that follows key in the traversal.\n\ The following code prints every key in the database db, without having\n\ to create a list in memory that contains them all:\n\ \n\ k = db.firstkey()\n\ while k != None:\n\ print k\n\ k = db.nextkey(k)"); static PyObject * dbm_nextkey(dbmobject *dp, PyObject *args) { PyObject *v; datum key, nextkey; if (!PyArg_ParseTuple(args, "s#:nextkey", &key.dptr, &key.dsize)) return NULL; check_dbmobject_open(dp); nextkey = gdbm_nextkey(dp->di_dbm, key); if (nextkey.dptr) { v = PyBytes_FromStringAndSize(nextkey.dptr, nextkey.dsize); free(nextkey.dptr); return v; } else { Py_INCREF(Py_None); return Py_None; } } PyDoc_STRVAR(dbm_reorganize__doc__, "reorganize() -> None\n\ If you have carried out a lot of deletions and would like to shrink\n\ the space used by the GDBM file, this routine will reorganize the\n\ database. GDBM will not shorten the length of a database file except\n\ by using this reorganization; otherwise, deleted file space will be\n\ kept and reused as new (key,value) pairs are added."); static PyObject * dbm_reorganize(dbmobject *dp, PyObject *unused) { check_dbmobject_open(dp); errno = 0; if (gdbm_reorganize(dp->di_dbm) < 0) { if (errno != 0) PyErr_SetFromErrno(DbmError); else PyErr_SetString(DbmError, gdbm_strerror(gdbm_errno)); return NULL; } Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(dbm_sync__doc__, "sync() -> None\n\ When the database has been opened in fast mode, this method forces\n\ any unwritten data to be written to the disk."); static PyObject * dbm_sync(dbmobject *dp, PyObject *unused) { check_dbmobject_open(dp); gdbm_sync(dp->di_dbm); Py_INCREF(Py_None); return Py_None; } static PyObject * dbm__enter__(PyObject *self, PyObject *args) { Py_INCREF(self); return self; } static PyObject * dbm__exit__(PyObject *self, PyObject *args) { _Py_IDENTIFIER(close); return _PyObject_CallMethodId(self, &PyId_close, NULL); } static PyMethodDef dbm_methods[] = { {"close", (PyCFunction)dbm_close, METH_NOARGS, dbm_close__doc__}, {"keys", (PyCFunction)dbm_keys, METH_NOARGS, dbm_keys__doc__}, {"firstkey", (PyCFunction)dbm_firstkey,METH_NOARGS, dbm_firstkey__doc__}, {"nextkey", (PyCFunction)dbm_nextkey, METH_VARARGS, dbm_nextkey__doc__}, {"reorganize",(PyCFunction)dbm_reorganize,METH_NOARGS, dbm_reorganize__doc__}, {"sync", (PyCFunction)dbm_sync, METH_NOARGS, dbm_sync__doc__}, {"get", (PyCFunction)dbm_get, METH_VARARGS, dbm_get__doc__}, {"setdefault",(PyCFunction)dbm_setdefault,METH_VARARGS, dbm_setdefault__doc__}, {"__enter__", dbm__enter__, METH_NOARGS, NULL}, {"__exit__", dbm__exit__, METH_VARARGS, NULL}, {NULL, NULL} /* sentinel */ }; static PyTypeObject Dbmtype = { PyVarObject_HEAD_INIT(0, 0) "_gdbm.gdbm", sizeof(dbmobject), 0, (destructor)dbm_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_reserved*/ 0, /*tp_repr*/ 0, /*tp_as_number*/ &dbm_as_sequence, /*tp_as_sequence*/ &dbm_as_mapping, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ 0, /*tp_str*/ 0, /*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_xxx4*/ gdbm_object__doc__, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ dbm_methods, /*tp_methods*/ }; /* ----------------------------------------------------------------- */ PyDoc_STRVAR(dbmopen__doc__, "open(filename, [flags, [mode]]) -> dbm_object\n\ Open a dbm database and return a dbm object. The filename argument is\n\ the name of the database file.\n\ \n\ The optional flags argument can be 'r' (to open an existing database\n\ for reading only -- default), 'w' (to open an existing database for\n\ reading and writing), 'c' (which creates the database if it doesn't\n\ exist), or 'n' (which always creates a new empty database).\n\ \n\ Some versions of gdbm support additional flags which must be\n\ appended to one of the flags described above. The module constant\n\ 'open_flags' is a string of valid additional flags. The 'f' flag\n\ opens the database in fast mode; altered data will not automatically\n\ be written to the disk after every change. This results in faster\n\ writes to the database, but may result in an inconsistent database\n\ if the program crashes while the database is still open. Use the\n\ sync() method to force any unwritten data to be written to the disk.\n\ The 's' flag causes all database operations to be synchronized to\n\ disk. The 'u' flag disables locking of the database file.\n\ \n\ The optional mode argument is the Unix mode of the file, used only\n\ when the database has to be created. It defaults to octal 0666. "); static PyObject * dbmopen(PyObject *self, PyObject *args) { char *name; char *flags = "r"; int iflags; int mode = 0666; if (!PyArg_ParseTuple(args, "s|si:open", &name, &flags, &mode)) return NULL; switch (flags[0]) { case 'r': iflags = GDBM_READER; break; case 'w': iflags = GDBM_WRITER; break; case 'c': iflags = GDBM_WRCREAT; break; case 'n': iflags = GDBM_NEWDB; break; default: PyErr_SetString(DbmError, "First flag must be one of 'r', 'w', 'c' or 'n'"); return NULL; } for (flags++; *flags != '\0'; flags++) { char buf[40]; switch (*flags) { #ifdef GDBM_FAST case 'f': iflags |= GDBM_FAST; break; #endif #ifdef GDBM_SYNC case 's': iflags |= GDBM_SYNC; break; #endif #ifdef GDBM_NOLOCK case 'u': iflags |= GDBM_NOLOCK; break; #endif default: PyOS_snprintf(buf, sizeof(buf), "Flag '%c' is not supported.", *flags); PyErr_SetString(DbmError, buf); return NULL; } } return newdbmobject(name, iflags, mode); } static char dbmmodule_open_flags[] = "rwcn" #ifdef GDBM_FAST "f" #endif #ifdef GDBM_SYNC "s" #endif #ifdef GDBM_NOLOCK "u" #endif ; static PyMethodDef dbmmodule_methods[] = { { "open", (PyCFunction)dbmopen, METH_VARARGS, dbmopen__doc__}, { 0, 0 }, }; static struct PyModuleDef _gdbmmodule = { PyModuleDef_HEAD_INIT, "_gdbm", gdbmmodule__doc__, -1, dbmmodule_methods, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit__gdbm(void) { PyObject *m, *d, *s; if (PyType_Ready(&Dbmtype) < 0) return NULL; m = PyModule_Create(&_gdbmmodule); if (m == NULL) return NULL; d = PyModule_GetDict(m); DbmError = PyErr_NewException("_gdbm.error", PyExc_IOError, NULL); if (DbmError != NULL) { PyDict_SetItemString(d, "error", DbmError); s = PyUnicode_FromString(dbmmodule_open_flags); PyDict_SetItemString(d, "open_flags", s); Py_DECREF(s); } return m; } python3-stdlib-extensions-3.4.0/3.4/Modules/Setup0000644000000000000000000003523111414103166016424 0ustar # -*- makefile -*- # The file Setup is used by the makesetup script to construct the files # Makefile and config.c, from Makefile.pre and config.c.in, # respectively. The file Setup itself is initially copied from # Setup.dist; once it exists it will not be overwritten, so you can edit # Setup to your heart's content. Note that Makefile.pre is created # from Makefile.pre.in by the toplevel configure script. # (VPATH notes: Setup and Makefile.pre are in the build directory, as # are Makefile and config.c; the *.in and *.dist files are in the source # directory.) # Each line in this file describes one or more optional modules. # Modules enabled here will not be compiled by the setup.py script, # so the file can be used to override setup.py's behavior. # Lines have the following structure: # # ... [ ...] [ ...] [ ...] # # is anything ending in .c (.C, .cc, .c++ are C++ files) # is anything starting with -I, -D, -U or -C # is anything ending in .a or beginning with -l or -L # is anything else but should be a valid Python # identifier (letters, digits, underscores, beginning with non-digit) # # (As the makesetup script changes, it may recognize some other # arguments as well, e.g. *.so and *.sl as libraries. See the big # case statement in the makesetup script.) # # Lines can also have the form # # = # # which defines a Make variable definition inserted into Makefile.in # # Finally, if a line contains just the word "*shared*" (without the # quotes but with the stars), then the following modules will not be # built statically. The build process works like this: # # 1. Build all modules that are declared as static in Modules/Setup, # combine them into libpythonxy.a, combine that into python. # 2. Build all modules that are listed as shared in Modules/Setup. # 3. Invoke setup.py. That builds all modules that # a) are not builtin, and # b) are not listed in Modules/Setup, and # c) can be build on the target # # Therefore, modules declared to be shared will not be # included in the config.c file, nor in the list of objects to be # added to the library archive, and their linker options won't be # added to the linker options. Rules to create their .o files and # their shared libraries will still be added to the Makefile, and # their names will be collected in the Make variable SHAREDMODS. This # is used to build modules as shared libraries. (They can be # installed using "make sharedinstall", which is implied by the # toplevel "make install" target.) (For compatibility, # *noconfig* has the same effect as *shared*.) # # In addition, *static* explicitly declares the following modules to # be static. Lines containing "*static*" and "*shared*" may thus # alternate throughout this file. # NOTE: As a standard policy, as many modules as can be supported by a # platform should be present. The distribution comes with all modules # enabled that are supported by most platforms and don't require you # to ftp sources from elsewhere. # Some special rules to define PYTHONPATH. # Edit the definitions below to indicate which options you are using. # Don't add any whitespace or comments! # Directories where library files get installed. # DESTLIB is for Python modules; MACHDESTLIB for shared libraries. DESTLIB=$(LIBDEST) MACHDESTLIB=$(BINLIBDEST) # NOTE: all the paths are now relative to the prefix that is computed # at run time! # Standard path -- don't edit. # No leading colon since this is the first entry. # Empty since this is now just the runtime prefix. DESTPATH= # Site specific path components -- should begin with : if non-empty SITEPATH= # Standard path components for test modules TESTPATH= # Path components for machine- or system-dependent modules and shared libraries MACHDEPPATH=:plat-$(MACHDEP) EXTRAMACHDEPPATH= COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH) PYTHONPATH=$(COREPYTHONPATH) # The modules listed here can't be built as shared libraries for # various reasons; therefore they are listed here instead of in the # normal order. # This only contains the minimal set of modules required to run the # setup.py script in the root of the Python source tree. posix posixmodule.c # posix (UNIX) system calls errno errnomodule.c # posix (UNIX) errno values pwd pwdmodule.c # this is needed to find out the user's home dir # if $HOME is not set _sre _sre.c # Fredrik Lundh's new regular expressions _codecs _codecsmodule.c # access to the builtin codecs and codec registry _weakref _weakref.c # weak references _functools _functoolsmodule.c # Tools for working with functions and callable objects # access to ISO C locale support _locale _localemodule.c # -lintl # Standard I/O baseline _io -I$(srcdir)/Modules/_io _io/_iomodule.c _io/iobase.c _io/fileio.c _io/bytesio.c _io/bufferedio.c _io/textio.c _io/stringio.c # The zipimport module is always imported at startup. Having it as a # builtin module avoids some bootstrapping problems and reduces overhead. zipimport zipimport.c # The rest of the modules listed in this file are all commented out by # default. Usually they can be detected and built as dynamically # loaded modules by the new setup.py script added in Python 2.1. If # you're on a platform that doesn't support dynamic loading, want to # compile modules statically into the Python binary, or need to # specify some odd set of compiler switches, you can uncomment the # appropriate lines below. # ====================================================================== # The Python symtable module depends on .h files that setup.py doesn't track _symtable symtablemodule.c # Uncommenting the following line tells makesetup that all following # modules are to be built as shared libraries (see above for more # detail; also note that *static* reverses this effect): #*shared* # GNU readline. Unlike previous Python incarnations, GNU readline is # now incorporated in an optional module, configured in the Setup file # instead of by a configure script switch. You may have to insert a # -L option pointing to the directory where libreadline.* lives, # and you may have to change -ltermcap to -ltermlib or perhaps remove # it, depending on your system -- see the GNU readline instructions. # It's okay for this to be a shared library, too. #readline readline.c -lreadline -ltermcap # Modules that should always be present (non UNIX dependent): #array arraymodule.c # array objects #cmath cmathmodule.c _math.c # -lm # complex math library functions #math mathmodule.c _math.c # -lm # math library functions, e.g. sin() #_struct _struct.c # binary structure packing/unpacking #time timemodule.c # -lm # time operations and variables #operator operator.c # operator.add() and similar goodies #_weakref _weakref.c # basic weak reference support #_testcapi _testcapimodule.c # Python C API test module #_random _randommodule.c # Random number generator #_collections _collectionsmodule.c # Container types #itertools itertoolsmodule.c # Functions creating iterators for efficient looping #atexit atexitmodule.c # Register functions to be run at interpreter-shutdown #_elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI _elementtree.c # elementtree accelerator #_pickle _pickle.c # pickle accelerator #datetime datetimemodule.c # date/time type #_bisect _bisectmodule.c # Bisection algorithms #_heapq _heapqmodule.c # Heap queue algorithm #unicodedata unicodedata.c # static Unicode character database # Modules with some UNIX dependencies -- on by default: # (If you have a really backward UNIX, select and socket may not be # supported...) #fcntl fcntlmodule.c # fcntl(2) and ioctl(2) #spwd spwdmodule.c # spwd(3) #grp grpmodule.c # grp(3) #select selectmodule.c # select(2); not on ancient System V # Memory-mapped files (also works on Win32). #mmap mmapmodule.c # CSV file helper #_csv _csv.c # Socket module helper for socket(2) #_socket socketmodule.c # Socket module helper for SSL support; you must comment out the other # socket line above, and possibly edit the SSL variable: #SSL=/usr/local/ssl #_ssl _ssl.c \ # -DUSE_SSL -I$(SSL)/include -I$(SSL)/include/openssl \ # -L$(SSL)/lib -lssl -lcrypto # The crypt module is now disabled by default because it breaks builds # on many systems (where -lcrypt is needed), e.g. Linux (I believe). # # First, look at Setup.config; configure may have set this for you. #crypt cryptmodule.c # -lcrypt # crypt(3); needs -lcrypt on some systems # Some more UNIX dependent modules -- off by default, since these # are not supported by all UNIX systems: #nis nismodule.c -lnsl # Sun yellow pages -- not everywhere #termios termios.c # Steen Lumholt's termios module #resource resource.c # Jeremy Hylton's rlimit interface #_posixsubprocess _posixsubprocess.c # POSIX subprocess module helper # Multimedia modules -- off by default. # These don't work for 64-bit platforms!!! # #993173 says audioop works on 64-bit platforms, though. # These represent audio samples or images as strings: #audioop audioop.c # Operations on audio samples # Note that the _md5 and _sha modules are normally only built if the # system does not have the OpenSSL libs containing an optimized version. # The _md5 module implements the RSA Data Security, Inc. MD5 # Message-Digest Algorithm, described in RFC 1321. The necessary files # md5.c and md5.h are included here. #_md5 md5module.c md5.c # The _sha module implements the SHA checksum algorithms. # (NIST's Secure Hash Algorithms.) #_sha shamodule.c #_sha256 sha256module.c #_sha512 sha512module.c # The _tkinter module. # # The command for _tkinter is long and site specific. Please # uncomment and/or edit those parts as indicated. If you don't have a # specific extension (e.g. Tix or BLT), leave the corresponding line # commented out. (Leave the trailing backslashes in! If you # experience strange errors, you may want to join all uncommented # lines and remove the backslashes -- the backslash interpretation is # done by the shell's "read" command and it may not be implemented on # every system. # *** Always uncomment this (leave the leading underscore in!): # _tkinter _tkinter.c tkappinit.c -DWITH_APPINIT \ # *** Uncomment and edit to reflect where your Tcl/Tk libraries are: # -L/usr/local/lib \ # *** Uncomment and edit to reflect where your Tcl/Tk headers are: # -I/usr/local/include \ # *** Uncomment and edit to reflect where your X11 header files are: # -I/usr/X11R6/include \ # *** Or uncomment this for Solaris: # -I/usr/openwin/include \ # *** Uncomment and edit for Tix extension only: # -DWITH_TIX -ltix8.1.8.2 \ # *** Uncomment and edit for BLT extension only: # -DWITH_BLT -I/usr/local/blt/blt8.0-unoff/include -lBLT8.0 \ # *** Uncomment and edit for PIL (TkImaging) extension only: # (See http://www.pythonware.com/products/pil/ for more info) # -DWITH_PIL -I../Extensions/Imaging/libImaging tkImaging.c \ # *** Uncomment and edit for TOGL extension only: # -DWITH_TOGL togl.c \ # *** Uncomment and edit to reflect your Tcl/Tk versions: # -ltk8.2 -ltcl8.2 \ # *** Uncomment and edit to reflect where your X11 libraries are: # -L/usr/X11R6/lib \ # *** Or uncomment this for Solaris: # -L/usr/openwin/lib \ # *** Uncomment these for TOGL extension only: # -lGL -lGLU -lXext -lXmu \ # *** Uncomment for AIX: # -lld \ # *** Always uncomment this; X11 libraries to link with: # -lX11 # Lance Ellinghaus's syslog module #syslog syslogmodule.c # syslog daemon interface # Curses support, requring the System V version of curses, often # provided by the ncurses library. e.g. on Linux, link with -lncurses # instead of -lcurses). # # First, look at Setup.config; configure may have set this for you. #_curses _cursesmodule.c -lcurses -ltermcap # Wrapper for the panel library that's part of ncurses and SYSV curses. #_curses_panel _curses_panel.c -lpanel -lncurses # Modules that provide persistent dictionary-like semantics. You will # probably want to arrange for at least one of them to be available on # your machine, though none are defined by default because of library # dependencies. The Python module dbm/__init__.py provides an # implementation independent wrapper for these; dbm/dumb.py provides # similar functionality (but slower of course) implemented in Python. # The standard Unix dbm module has been moved to Setup.config so that # it will be compiled as a shared library by default. Compiling it as # a built-in module causes conflicts with the pybsddb3 module since it # creates a static dependency on an out-of-date version of db.so. # # First, look at Setup.config; configure may have set this for you. #_dbm _dbmmodule.c # dbm(3) may require -lndbm or similar # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm: # # First, look at Setup.config; configure may have set this for you. #_gdbm _gdbmmodule.c -I/usr/local/include -L/usr/local/lib -lgdbm # Helper module for various ascii-encoders #binascii binascii.c # Fred Drake's interface to the Python parser #parser parsermodule.c # Lee Busby's SIGFPE modules. # The library to link fpectl with is platform specific. # Choose *one* of the options below for fpectl: # For SGI IRIX (tested on 5.3): #fpectl fpectlmodule.c -lfpe # For Solaris with SunPro compiler (tested on Solaris 2.5 with SunPro C 4.2): # (Without the compiler you don't have -lsunmath.) #fpectl fpectlmodule.c -R/opt/SUNWspro/lib -lsunmath -lm # For other systems: see instructions in fpectlmodule.c. #fpectl fpectlmodule.c ... # Test module for fpectl. No extra libraries needed. #fpetest fpetestmodule.c # Andrew Kuchling's zlib module. # This require zlib 1.1.3 (or later). # See http://www.gzip.org/zlib/ #zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz # Interface to the Expat XML parser # # Expat was written by James Clark and is now maintained by a group of # developers on SourceForge; see www.libexpat.org for more # information. The pyexpat module was written by Paul Prescod after a # prototype by Jack Jansen. Source of Expat 1.95.2 is included in # Modules/expat/. Usage of a system shared libexpat.so/expat.dll is # not advised. # # More information on Expat can be found at www.libexpat.org. # #pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H -DUSE_PYEXPAT_CAPI # Hye-Shik Chang's CJKCodecs # multibytecodec is required for all the other CJK codec modules #_multibytecodec cjkcodecs/multibytecodec.c #_codecs_cn cjkcodecs/_codecs_cn.c #_codecs_hk cjkcodecs/_codecs_hk.c #_codecs_iso2022 cjkcodecs/_codecs_iso2022.c #_codecs_jp cjkcodecs/_codecs_jp.c #_codecs_kr cjkcodecs/_codecs_kr.c #_codecs_tw cjkcodecs/_codecs_tw.c # Example -- included for reference only: # xx xxmodule.c # Another example -- the 'xxsubtype' module shows C-level subtyping in action xxsubtype xxsubtype.c python3-stdlib-extensions-3.4.0/3.4/Modules/Setup.local0000644000000000000000000000256011232064444017517 0ustar # Edit this file for local setup changes array arraymodule.c # array objects math mathmodule.c # -lm # math library functions, e.g. sin() _struct _struct.c # binary structure packing/unpacking time timemodule.c # -lm # time operations and variables operator operator.c # operator.add() and similar goodies _random _randommodule.c # Random number generator _collections _collectionsmodule.c # Container types itertools itertoolsmodule.c # Functions creating iterators for efficient looping _elementtree -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H _elementtree.c # elementtree accelerator _pickle _pickle.c # pickle accelerator datetime datetimemodule.c # date/time type _bisect _bisectmodule.c # Bisection algorithms _heapq _heapqmodule.c # Heap queue algorithm unicodedata unicodedata.c # static Unicode character database fcntl fcntlmodule.c # fcntl(2) and ioctl(2) spwd spwdmodule.c # spwd(3) grp grpmodule.c # grp(3) select selectmodule.c # select(2); not on ancient System V _socket socketmodule.c syslog syslogmodule.c # syslog daemon interface binascii binascii.c _ctypes _ctypes/_ctypes.c _ctypes/callbacks.c _ctypes/callproc.c _ctypes/stgdict.c _ctypes/cfield.c _ctypes/malloc_closure.c -lffi zlib zlibmodule.c -I$(prefix)/include -L$(exec_prefix)/lib -lz pyexpat expat/xmlparse.c expat/xmlrole.c expat/xmltok.c pyexpat.c -I$(srcdir)/Modules/expat -DHAVE_EXPAT_CONFIG_H python3-stdlib-extensions-3.4.0/3.4/Modules/tkappinit.c0000644000000000000000000001232212313511423017542 0ustar /* appinit.c -- Tcl and Tk application initialization. The function Tcl_AppInit() below initializes various Tcl packages. It is called for each Tcl interpreter created by _tkinter.create(). It needs to be compiled with -DWITH_ flags for each package that you are statically linking with. You may have to add sections for packages not yet listed below. Note that those packages for which Tcl_StaticPackage() is called with a NULL first argument are known as "static loadable" packages to Tcl but not actually initialized. To use these, you have to load it explicitly, e.g. tkapp.eval("load {} Blt"). */ #include #include #include #include "tkinter.h" #ifdef TKINTER_PROTECT_LOADTK /* See Tkapp_TkInit in _tkinter.c for the usage of tk_load_faile */ static int tk_load_failed; #endif int Tcl_AppInit(Tcl_Interp *interp) { #ifdef WITH_MOREBUTTONS Tk_Window main_window; #endif const char *_tkinter_skip_tk_init; #ifdef TKINTER_PROTECT_LOADTK const char *_tkinter_tk_failed; #endif #ifdef TK_AQUA #ifndef MAX_PATH_LEN #define MAX_PATH_LEN 1024 #endif char tclLibPath[MAX_PATH_LEN], tkLibPath[MAX_PATH_LEN]; Tcl_Obj* pathPtr; /* pre- Tcl_Init code copied from tkMacOSXAppInit.c */ Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tcllibrary", tclLibPath, MAX_PATH_LEN, 0); if (tclLibPath[0] != '\0') { Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY); } if (tclLibPath[0] != '\0') { Tcl_SetVar(interp, "tcl_library", tclLibPath, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "tclDefaultLibrary", tclLibPath, TCL_GLOBAL_ONLY); Tcl_SetVar(interp, "tcl_pkgPath", tclLibPath, TCL_GLOBAL_ONLY); } #endif if (Tcl_Init (interp) == TCL_ERROR) return TCL_ERROR; #ifdef TK_AQUA /* pre- Tk_Init code copied from tkMacOSXAppInit.c */ Tk_MacOSXOpenBundleResources (interp, "com.tcltk.tklibrary", tkLibPath, MAX_PATH_LEN, 1); if (tclLibPath[0] != '\0') { pathPtr = Tcl_NewStringObj(tclLibPath, -1); } else { Tcl_Obj *pathPtr = TclGetLibraryPath(); } if (tkLibPath[0] != '\0') { Tcl_Obj *objPtr; Tcl_SetVar(interp, "tk_library", tkLibPath, TCL_GLOBAL_ONLY); objPtr = Tcl_NewStringObj(tkLibPath, -1); Tcl_ListObjAppendElement(NULL, pathPtr, objPtr); } TclSetLibraryPath(pathPtr); #endif #ifdef WITH_XXX /* Initialize modules that don't require Tk */ #endif _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY); if (_tkinter_skip_tk_init != NULL && strcmp(_tkinter_skip_tk_init, "1") == 0) { return TCL_OK; } #ifdef TKINTER_PROTECT_LOADTK _tkinter_tk_failed = Tcl_GetVar(interp, "_tkinter_tk_failed", TCL_GLOBAL_ONLY); if (tk_load_failed || ( _tkinter_tk_failed != NULL && strcmp(_tkinter_tk_failed, "1") == 0)) { Tcl_SetResult(interp, TKINTER_LOADTK_ERRMSG, TCL_STATIC); return TCL_ERROR; } #endif if (Tk_Init(interp) == TCL_ERROR) { #ifdef TKINTER_PROTECT_LOADTK tk_load_failed = 1; Tcl_SetVar(interp, "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY); #endif return TCL_ERROR; } #ifdef WITH_MOREBUTTONS main_window = Tk_MainWindow(interp); #else Tk_MainWindow(interp); #endif #ifdef TK_AQUA TkMacOSXInitAppleEvents(interp); TkMacOSXInitMenus(interp); #endif #ifdef WITH_MOREBUTTONS { extern Tcl_CmdProc studButtonCmd; extern Tcl_CmdProc triButtonCmd; Tcl_CreateCommand(interp, "studbutton", studButtonCmd, (ClientData) main_window, NULL); Tcl_CreateCommand(interp, "tributton", triButtonCmd, (ClientData) main_window, NULL); } #endif #ifdef WITH_PIL /* 0.2b5 and later -- not yet released as of May 14 */ { extern void TkImaging_Init(Tcl_Interp *); TkImaging_Init(interp); /* XXX TkImaging_Init() doesn't have the right return type */ /*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/ } #endif #ifdef WITH_PIL_OLD /* 0.2b4 and earlier */ { extern void TkImaging_Init(void); /* XXX TkImaging_Init() doesn't have the right prototype */ /*Tcl_StaticPackage(interp, "Imaging", TkImaging_Init, NULL);*/ } #endif #ifdef WITH_TIX { extern int Tix_Init(Tcl_Interp *interp); extern int Tix_SafeInit(Tcl_Interp *interp); Tcl_StaticPackage(NULL, "Tix", Tix_Init, Tix_SafeInit); } #endif #ifdef WITH_BLT { extern int Blt_Init(Tcl_Interp *); extern int Blt_SafeInit(Tcl_Interp *); Tcl_StaticPackage(NULL, "Blt", Blt_Init, Blt_SafeInit); } #endif #ifdef WITH_TOGL { /* XXX I've heard rumors that this doesn't work */ extern int Togl_Init(Tcl_Interp *); /* XXX Is there no Togl_SafeInit? */ Tcl_StaticPackage(NULL, "Togl", Togl_Init, NULL); } #endif #ifdef WITH_XXX #endif return TCL_OK; } python3-stdlib-extensions-3.4.0/3.4/Modules/tkinter.h0000644000000000000000000000144712250422247017237 0ustar #ifndef TKINTER_H #define TKINTER_H /* This header is used to share some macros between _tkinter.c and * tkappinit.c. * Be sure to include tk.h before including this header so * TK_VERSION_HEX is properly defined. */ /* TK_RELEASE_LEVEL is always one of the following: * TCL_ALPHA_RELEASE 0 * TCL_BETA_RELEASE 1 * TCL_FINAL_RELEASE 2 */ #define TK_VERSION_HEX ((TK_MAJOR_VERSION << 24) | \ (TK_MINOR_VERSION << 16) | \ (TK_RELEASE_SERIAL << 8) | \ (TK_RELEASE_LEVEL << 0)) /* Protect Tk 8.4.13 and older from a deadlock that happens when trying * to load tk after a failed attempt. */ #if TK_VERSION_HEX < 0x08040e02 #define TKINTER_PROTECT_LOADTK #define TKINTER_LOADTK_ERRMSG \ "Calling Tk_Init again after a previous call failed might deadlock" #endif #endif /* !TKINTER_H */ python3-stdlib-extensions-3.4.0/3.4/Modules/_tkinter.c0000644000000000000000000023326112313511423017365 0ustar /*********************************************************** Copyright (C) 1994 Steen Lumholt. All Rights Reserved ******************************************************************/ /* _tkinter.c -- Interface to libtk.a and libtcl.a. */ /* TCL/TK VERSION INFO: Only Tcl/Tk 8.3.1 and later are supported. Older versions are not supported. Use Python 2.6 or older if you cannot upgrade your Tcl/Tk libraries. */ /* XXX Further speed-up ideas, involving Tcl 8.0 features: - Register a new Tcl type, "Python callable", which can be called more efficiently and passed to Tcl_EvalObj() directly (if this is possible). */ #include "Python.h" #include #ifdef WITH_THREAD #include "pythread.h" #endif #ifdef MS_WINDOWS #include #endif #define CHECK_SIZE(size, elemsize) \ ((size_t)(size) <= Py_MAX((size_t)INT_MAX, UINT_MAX / (size_t)(elemsize))) /* Starting with Tcl 8.4, many APIs offer const-correctness. Unfortunately, making _tkinter correct for this API means to break earlier versions. USE_COMPAT_CONST allows to make _tkinter work with both 8.4 and earlier versions. Once Tcl releases before 8.4 don't need to be supported anymore, this should go. */ #define USE_COMPAT_CONST /* If Tcl is compiled for threads, we must also define TCL_THREAD. We define it always; if Tcl is not threaded, the thread functions in Tcl are empty. */ #define TCL_THREADS #ifdef TK_FRAMEWORK #include #include #else #include #include #endif #include "tkinter.h" /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ #ifndef CONST84_RETURN #define CONST84_RETURN #undef CONST #define CONST #endif #if TK_VERSION_HEX < 0x08030102 #error "Tk older than 8.3.1 not supported" #endif #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) #define HAVE_CREATEFILEHANDLER #endif #ifdef HAVE_CREATEFILEHANDLER /* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */ #ifndef TCL_UNIX_FD # ifdef TCL_WIN_SOCKET # define TCL_UNIX_FD (! TCL_WIN_SOCKET) # else # define TCL_UNIX_FD 1 # endif #endif /* Tcl_CreateFileHandler() changed several times; these macros deal with the messiness. In Tcl 8.0 and later, it is not available on Windows (and on Unix, only because Jack added it back); when available on Windows, it only applies to sockets. */ #ifdef MS_WINDOWS #define FHANDLETYPE TCL_WIN_SOCKET #else #define FHANDLETYPE TCL_UNIX_FD #endif /* If Tcl can wait for a Unix file descriptor, define the EventHook() routine which uses this to handle Tcl events while the user is typing commands. */ #if FHANDLETYPE == TCL_UNIX_FD #define WAIT_FOR_STDIN #endif #endif /* HAVE_CREATEFILEHANDLER */ #ifdef MS_WINDOWS #include #define WAIT_FOR_STDIN #endif #ifdef WITH_THREAD /* The threading situation is complicated. Tcl is not thread-safe, except when configured with --enable-threads. So we need to use a lock around all uses of Tcl. Previously, the Python interpreter lock was used for this. However, this causes problems when other Python threads need to run while Tcl is blocked waiting for events. To solve this problem, a separate lock for Tcl is introduced. Holding it is incompatible with holding Python's interpreter lock. The following four macros manipulate both locks together. ENTER_TCL and LEAVE_TCL are brackets, just like Py_BEGIN_ALLOW_THREADS and Py_END_ALLOW_THREADS. They should be used whenever a call into Tcl is made that could call an event handler, or otherwise affect the state of a Tcl interpreter. These assume that the surrounding code has the Python interpreter lock; inside the brackets, the Python interpreter lock has been released and the lock for Tcl has been acquired. Sometimes, it is necessary to have both the Python lock and the Tcl lock. (For example, when transferring data from the Tcl interpreter result to a Python string object.) This can be done by using different macros to close the ENTER_TCL block: ENTER_OVERLAP reacquires the Python lock (and restores the thread state) but doesn't release the Tcl lock; LEAVE_OVERLAP_TCL releases the Tcl lock. By contrast, ENTER_PYTHON and LEAVE_PYTHON are used in Tcl event handlers when the handler needs to use Python. Such event handlers are entered while the lock for Tcl is held; the event handler presumably needs to use Python. ENTER_PYTHON releases the lock for Tcl and acquires the Python interpreter lock, restoring the appropriate thread state, and LEAVE_PYTHON releases the Python interpreter lock and re-acquires the lock for Tcl. It is okay for ENTER_TCL/LEAVE_TCL pairs to be contained inside the code between ENTER_PYTHON and LEAVE_PYTHON. These locks expand to several statements and brackets; they should not be used in branches of if statements and the like. If Tcl is threaded, this approach won't work anymore. The Tcl interpreter is only valid in the thread that created it, and all Tk activity must happen in this thread, also. That means that the mainloop must be invoked in the thread that created the interpreter. Invoking commands from other threads is possible; _tkinter will queue an event for the interpreter thread, which will then execute the command and pass back the result. If the main thread is not in the mainloop, and invoking commands causes an exception; if the main loop is running but not processing events, the command invocation will block. In addition, for a threaded Tcl, a single global tcl_tstate won't be sufficient anymore, since multiple Tcl interpreters may simultaneously dispatch in different threads. So we use the Tcl TLS API. */ static PyThread_type_lock tcl_lock = 0; #ifdef TCL_THREADS static Tcl_ThreadDataKey state_key; typedef PyThreadState *ThreadSpecificData; #define tcl_tstate \ (*(PyThreadState**)Tcl_GetThreadData(&state_key, sizeof(PyThreadState*))) #else static PyThreadState *tcl_tstate = NULL; #endif #define ENTER_TCL \ { PyThreadState *tstate = PyThreadState_Get(); Py_BEGIN_ALLOW_THREADS \ if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; #define LEAVE_TCL \ tcl_tstate = NULL; \ if(tcl_lock)PyThread_release_lock(tcl_lock); Py_END_ALLOW_THREADS} #define ENTER_OVERLAP \ Py_END_ALLOW_THREADS #define LEAVE_OVERLAP_TCL \ tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); } #define ENTER_PYTHON \ { PyThreadState *tstate = tcl_tstate; tcl_tstate = NULL; \ if(tcl_lock) \ PyThread_release_lock(tcl_lock); PyEval_RestoreThread((tstate)); } #define LEAVE_PYTHON \ { PyThreadState *tstate = PyEval_SaveThread(); \ if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; } #define CHECK_TCL_APPARTMENT \ if (((TkappObject *)self)->threaded && \ ((TkappObject *)self)->thread_id != Tcl_GetCurrentThread()) { \ PyErr_SetString(PyExc_RuntimeError, \ "Calling Tcl from different appartment"); \ return 0; \ } #else #define ENTER_TCL #define LEAVE_TCL #define ENTER_OVERLAP #define LEAVE_OVERLAP_TCL #define ENTER_PYTHON #define LEAVE_PYTHON #define CHECK_TCL_APPARTMENT #endif #ifndef FREECAST #define FREECAST (char *) #endif /**** Tkapp Object Declaration ****/ static PyObject *Tkapp_Type; typedef struct { PyObject_HEAD Tcl_Interp *interp; int wantobjects; int threaded; /* True if tcl_platform[threaded] */ Tcl_ThreadId thread_id; int dispatching; /* We cannot include tclInt.h, as this is internal. So we cache interesting types here. */ Tcl_ObjType *BooleanType; Tcl_ObjType *ByteArrayType; Tcl_ObjType *DoubleType; Tcl_ObjType *IntType; Tcl_ObjType *ListType; Tcl_ObjType *ProcBodyType; Tcl_ObjType *StringType; } TkappObject; #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v)) #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ (void *) v, Py_REFCNT(v))) /**** Error Handling ****/ static PyObject *Tkinter_TclError; static int quitMainLoop = 0; static int errorInCmd = 0; static PyObject *excInCmd; static PyObject *valInCmd; static PyObject *trbInCmd; #ifdef TKINTER_PROTECT_LOADTK static int tk_load_failed = 0; #endif static PyObject * Tkinter_Error(PyObject *v) { PyErr_SetString(Tkinter_TclError, Tkapp_Result(v)); return NULL; } /**** Utils ****/ static int Tkinter_busywaitinterval = 20; #ifdef WITH_THREAD #ifndef MS_WINDOWS /* Millisecond sleep() for Unix platforms. */ static void Sleep(int milli) { /* XXX Too bad if you don't have select(). */ struct timeval t; t.tv_sec = milli/1000; t.tv_usec = (milli%1000) * 1000; select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &t); } #endif /* MS_WINDOWS */ /* Wait up to 1s for the mainloop to come up. */ static int WaitForMainloop(TkappObject* self) { int i; for (i = 0; i < 10; i++) { if (self->dispatching) return 1; Py_BEGIN_ALLOW_THREADS Sleep(100); Py_END_ALLOW_THREADS } if (self->dispatching) return 1; PyErr_SetString(PyExc_RuntimeError, "main thread is not in main loop"); return 0; } #endif /* WITH_THREAD */ #define ARGSZ 64 static PyObject * unicodeFromTclStringAndSize(const char *s, Py_ssize_t size) { PyObject *r = PyUnicode_DecodeUTF8(s, size, NULL); if (!r && PyErr_ExceptionMatches(PyExc_UnicodeDecodeError)) { /* Tcl encodes null character as \xc0\x80 */ if (memchr(s, '\xc0', size)) { char *buf, *q; const char *e = s + size; PyErr_Clear(); q = buf = (char *)PyMem_Malloc(size); if (buf == NULL) return NULL; while (s != e) { if (s + 1 != e && s[0] == '\xc0' && s[1] == '\x80') { *q++ = '\0'; s += 2; } else *q++ = *s++; } s = buf; size = q - s; r = PyUnicode_DecodeUTF8(s, size, NULL); PyMem_Free(buf); } } return r; } static PyObject * unicodeFromTclString(const char *s) { return unicodeFromTclStringAndSize(s, strlen(s)); } static PyObject * unicodeFromTclObj(Tcl_Obj *value) { int len; char *s = Tcl_GetStringFromObj(value, &len); return unicodeFromTclStringAndSize(s, len); } static PyObject * Split(char *list) { int argc; char **argv; PyObject *v; if (list == NULL) { Py_RETURN_NONE; } if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { /* Not a list. * Could be a quoted string containing funnies, e.g. {"}. * Return the string itself. */ return unicodeFromTclString(list); } if (argc == 0) v = PyUnicode_FromString(""); else if (argc == 1) v = unicodeFromTclString(argv[0]); else if ((v = PyTuple_New(argc)) != NULL) { int i; PyObject *w; for (i = 0; i < argc; i++) { if ((w = Split(argv[i])) == NULL) { Py_DECREF(v); v = NULL; break; } PyTuple_SetItem(v, i, w); } } Tcl_Free(FREECAST argv); return v; } /* In some cases, Tcl will still return strings that are supposed to be lists. SplitObj walks through a nested tuple, finding string objects that need to be split. */ static PyObject * SplitObj(PyObject *arg) { if (PyTuple_Check(arg)) { int i, size; PyObject *elem, *newelem, *result; size = PyTuple_Size(arg); result = NULL; /* Recursively invoke SplitObj for all tuple items. If this does not return a new object, no action is needed. */ for(i = 0; i < size; i++) { elem = PyTuple_GetItem(arg, i); newelem = SplitObj(elem); if (!newelem) { Py_XDECREF(result); return NULL; } if (!result) { int k; if (newelem == elem) { Py_DECREF(newelem); continue; } result = PyTuple_New(size); if (!result) return NULL; for(k = 0; k < i; k++) { elem = PyTuple_GetItem(arg, k); Py_INCREF(elem); PyTuple_SetItem(result, k, elem); } } PyTuple_SetItem(result, i, newelem); } if (result) return result; /* Fall through, returning arg. */ } else if (PyUnicode_Check(arg)) { int argc; char **argv; char *list = PyUnicode_AsUTF8(arg); if (list == NULL || Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { Py_INCREF(arg); return arg; } Tcl_Free(FREECAST argv); if (argc > 1) return Split(list); /* Fall through, returning arg. */ } else if (PyBytes_Check(arg)) { int argc; char **argv; char *list = PyBytes_AsString(arg); if (Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { Py_INCREF(arg); return arg; } Tcl_Free(FREECAST argv); if (argc > 1) return Split(PyBytes_AsString(arg)); /* Fall through, returning arg. */ } Py_INCREF(arg); return arg; } /**** Tkapp Object ****/ #ifndef WITH_APPINIT int Tcl_AppInit(Tcl_Interp *interp) { const char * _tkinter_skip_tk_init; if (Tcl_Init(interp) == TCL_ERROR) { PySys_WriteStderr("Tcl_Init error: %s\n", Tcl_GetStringResult(interp)); return TCL_ERROR; } _tkinter_skip_tk_init = Tcl_GetVar(interp, "_tkinter_skip_tk_init", TCL_GLOBAL_ONLY); if (_tkinter_skip_tk_init != NULL && strcmp(_tkinter_skip_tk_init, "1") == 0) { return TCL_OK; } #ifdef TKINTER_PROTECT_LOADTK if (tk_load_failed) { PySys_WriteStderr("Tk_Init error: %s\n", TKINTER_LOADTK_ERRMSG); return TCL_ERROR; } #endif if (Tk_Init(interp) == TCL_ERROR) { #ifdef TKINTER_PROTECT_LOADTK tk_load_failed = 1; #endif PySys_WriteStderr("Tk_Init error: %s\n", Tcl_GetStringResult(interp)); return TCL_ERROR; } return TCL_OK; } #endif /* !WITH_APPINIT */ /* Initialize the Tk application; see the `main' function in * `tkMain.c'. */ static void EnableEventHook(void); /* Forward */ static void DisableEventHook(void); /* Forward */ static TkappObject * Tkapp_New(char *screenName, char *className, int interactive, int wantobjects, int wantTk, int sync, char *use) { TkappObject *v; char *argv0; v = PyObject_New(TkappObject, (PyTypeObject *) Tkapp_Type); if (v == NULL) return NULL; Py_INCREF(Tkapp_Type); v->interp = Tcl_CreateInterp(); v->wantobjects = wantobjects; v->threaded = Tcl_GetVar2Ex(v->interp, "tcl_platform", "threaded", TCL_GLOBAL_ONLY) != NULL; v->thread_id = Tcl_GetCurrentThread(); v->dispatching = 0; #ifndef TCL_THREADS if (v->threaded) { PyErr_SetString(PyExc_RuntimeError, "Tcl is threaded but _tkinter is not"); Py_DECREF(v); return 0; } #endif #ifdef WITH_THREAD if (v->threaded && tcl_lock) { /* If Tcl is threaded, we don't need the lock. */ PyThread_free_lock(tcl_lock); tcl_lock = NULL; } #endif v->BooleanType = Tcl_GetObjType("boolean"); v->ByteArrayType = Tcl_GetObjType("bytearray"); v->DoubleType = Tcl_GetObjType("double"); v->IntType = Tcl_GetObjType("int"); v->ListType = Tcl_GetObjType("list"); v->ProcBodyType = Tcl_GetObjType("procbody"); v->StringType = Tcl_GetObjType("string"); /* Delete the 'exit' command, which can screw things up */ Tcl_DeleteCommand(v->interp, "exit"); if (screenName != NULL) Tcl_SetVar2(v->interp, "env", "DISPLAY", screenName, TCL_GLOBAL_ONLY); if (interactive) Tcl_SetVar(v->interp, "tcl_interactive", "1", TCL_GLOBAL_ONLY); else Tcl_SetVar(v->interp, "tcl_interactive", "0", TCL_GLOBAL_ONLY); /* This is used to get the application class for Tk 4.1 and up */ argv0 = (char*)ckalloc(strlen(className) + 1); if (!argv0) { PyErr_NoMemory(); Py_DECREF(v); return NULL; } strcpy(argv0, className); if (Py_ISUPPER(Py_CHARMASK(argv0[0]))) argv0[0] = Py_TOLOWER(Py_CHARMASK(argv0[0])); Tcl_SetVar(v->interp, "argv0", argv0, TCL_GLOBAL_ONLY); ckfree(argv0); if (! wantTk) { Tcl_SetVar(v->interp, "_tkinter_skip_tk_init", "1", TCL_GLOBAL_ONLY); } #ifdef TKINTER_PROTECT_LOADTK else if (tk_load_failed) { Tcl_SetVar(v->interp, "_tkinter_tk_failed", "1", TCL_GLOBAL_ONLY); } #endif /* some initial arguments need to be in argv */ if (sync || use) { char *args; int len = 0; if (sync) len += sizeof "-sync"; if (use) len += strlen(use) + sizeof "-use "; args = (char*)ckalloc(len); if (!args) { PyErr_NoMemory(); Py_DECREF(v); return NULL; } args[0] = '\0'; if (sync) strcat(args, "-sync"); if (use) { if (sync) strcat(args, " "); strcat(args, "-use "); strcat(args, use); } Tcl_SetVar(v->interp, "argv", args, TCL_GLOBAL_ONLY); ckfree(args); } if (Tcl_AppInit(v->interp) != TCL_OK) { PyObject *result = Tkinter_Error((PyObject *)v); #ifdef TKINTER_PROTECT_LOADTK if (wantTk) { const char *_tkinter_tk_failed; _tkinter_tk_failed = Tcl_GetVar(v->interp, "_tkinter_tk_failed", TCL_GLOBAL_ONLY); if ( _tkinter_tk_failed != NULL && strcmp(_tkinter_tk_failed, "1") == 0) { tk_load_failed = 1; } } #endif Py_DECREF((PyObject *)v); return (TkappObject *)result; } EnableEventHook(); return v; } #ifdef WITH_THREAD static void Tkapp_ThreadSend(TkappObject *self, Tcl_Event *ev, Tcl_Condition *cond, Tcl_Mutex *mutex) { Py_BEGIN_ALLOW_THREADS; Tcl_MutexLock(mutex); Tcl_ThreadQueueEvent(self->thread_id, ev, TCL_QUEUE_TAIL); Tcl_ThreadAlert(self->thread_id); Tcl_ConditionWait(cond, mutex, NULL); Tcl_MutexUnlock(mutex); Py_END_ALLOW_THREADS } #endif /** Tcl Eval **/ typedef struct { PyObject_HEAD Tcl_Obj *value; PyObject *string; /* This cannot cause cycles. */ } PyTclObject; static PyObject *PyTclObject_Type; #define PyTclObject_Check(v) ((v)->ob_type == (PyTypeObject *) PyTclObject_Type) static PyObject * newPyTclObject(Tcl_Obj *arg) { PyTclObject *self; self = PyObject_New(PyTclObject, (PyTypeObject *) PyTclObject_Type); if (self == NULL) return NULL; Py_INCREF(PyTclObject_Type); Tcl_IncrRefCount(arg); self->value = arg; self->string = NULL; return (PyObject*)self; } static void PyTclObject_dealloc(PyTclObject *self) { PyObject *tp = (PyObject *) Py_TYPE(self); Tcl_DecrRefCount(self->value); Py_XDECREF(self->string); PyObject_Del(self); Py_DECREF(tp); } static char* PyTclObject_TclString(PyObject *self) { return Tcl_GetString(((PyTclObject*)self)->value); } /* Like _str, but create Unicode if necessary. */ PyDoc_STRVAR(PyTclObject_string__doc__, "the string representation of this object, either as str or bytes"); static PyObject * PyTclObject_string(PyTclObject *self, void *ignored) { if (!self->string) { self->string = unicodeFromTclObj(self->value); if (!self->string) return NULL; } Py_INCREF(self->string); return self->string; } static PyObject * PyTclObject_str(PyTclObject *self, void *ignored) { if (self->string) { Py_INCREF(self->string); return self->string; } /* XXX Could chache result if it is non-ASCII. */ return unicodeFromTclObj(self->value); } static PyObject * PyTclObject_repr(PyTclObject *self) { PyObject *repr, *str = PyTclObject_str(self, NULL); if (str == NULL) return NULL; repr = PyUnicode_FromFormat("<%s object: %R>", self->value->typePtr->name, str); Py_DECREF(str); return repr; } #define TEST_COND(cond) ((cond) ? Py_True : Py_False) static PyObject * PyTclObject_richcompare(PyObject *self, PyObject *other, int op) { int result; PyObject *v; /* neither argument should be NULL, unless something's gone wrong */ if (self == NULL || other == NULL) { PyErr_BadInternalCall(); return NULL; } /* both arguments should be instances of PyTclObject */ if (!PyTclObject_Check(self) || !PyTclObject_Check(other)) { v = Py_NotImplemented; goto finished; } if (self == other) /* fast path when self and other are identical */ result = 0; else result = strcmp(Tcl_GetString(((PyTclObject *)self)->value), Tcl_GetString(((PyTclObject *)other)->value)); /* Convert return value to a Boolean */ switch (op) { case Py_EQ: v = TEST_COND(result == 0); break; case Py_NE: v = TEST_COND(result != 0); break; case Py_LE: v = TEST_COND(result <= 0); break; case Py_GE: v = TEST_COND(result >= 0); break; case Py_LT: v = TEST_COND(result < 0); break; case Py_GT: v = TEST_COND(result > 0); break; default: PyErr_BadArgument(); return NULL; } finished: Py_INCREF(v); return v; } PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); static PyObject* get_typename(PyTclObject* obj, void* ignored) { return unicodeFromTclString(obj->value->typePtr->name); } static PyGetSetDef PyTclObject_getsetlist[] = { {"typename", (getter)get_typename, NULL, get_typename__doc__}, {"string", (getter)PyTclObject_string, NULL, PyTclObject_string__doc__}, {0}, }; static PyType_Slot PyTclObject_Type_slots[] = { {Py_tp_dealloc, (destructor)PyTclObject_dealloc}, {Py_tp_repr, (reprfunc)PyTclObject_repr}, {Py_tp_str, (reprfunc)PyTclObject_str}, {Py_tp_getattro, PyObject_GenericGetAttr}, {Py_tp_richcompare, PyTclObject_richcompare}, {Py_tp_getset, PyTclObject_getsetlist}, {0, 0} }; static PyType_Spec PyTclObject_Type_spec = { "_tkinter.Tcl_Obj", sizeof(PyTclObject), 0, Py_TPFLAGS_DEFAULT, PyTclObject_Type_slots, }; static Tcl_Obj* AsObj(PyObject *value) { Tcl_Obj *result; long longVal; int overflow; if (PyBytes_Check(value)) return Tcl_NewStringObj(PyBytes_AS_STRING(value), PyBytes_GET_SIZE(value)); else if (PyBool_Check(value)) return Tcl_NewBooleanObj(PyObject_IsTrue(value)); else if (PyLong_CheckExact(value) && ((longVal = PyLong_AsLongAndOverflow(value, &overflow)), !overflow)) { /* If there is an overflow in the long conversion, fall through to default object handling. */ return Tcl_NewLongObj(longVal); } else if (PyFloat_Check(value)) return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); else if (PyTuple_Check(value)) { Tcl_Obj **argv; Py_ssize_t size, i; size = PyTuple_Size(value); if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) { PyErr_SetString(PyExc_OverflowError, "tuple is too long"); return NULL; } argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *)); if(!argv) return 0; for (i = 0; i < size; i++) argv[i] = AsObj(PyTuple_GetItem(value,i)); result = Tcl_NewListObj(PyTuple_Size(value), argv); ckfree(FREECAST argv); return result; } else if (PyUnicode_Check(value)) { void *inbuf; Py_ssize_t size; int kind; Tcl_UniChar *outbuf = NULL; Py_ssize_t i; size_t allocsize; if (PyUnicode_READY(value) == -1) return NULL; inbuf = PyUnicode_DATA(value); size = PyUnicode_GET_LENGTH(value); if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return NULL; } kind = PyUnicode_KIND(value); if (kind == sizeof(Tcl_UniChar)) return Tcl_NewUnicodeObj(inbuf, size); allocsize = ((size_t)size) * sizeof(Tcl_UniChar); outbuf = (Tcl_UniChar*)ckalloc(allocsize); /* Else overflow occurred, and we take the next exit */ if (!outbuf) { PyErr_NoMemory(); return NULL; } for (i = 0; i < size; i++) { Py_UCS4 ch = PyUnicode_READ(kind, inbuf, i); /* We cannot test for sizeof(Tcl_UniChar) directly, so we test for UTF-8 size instead. */ #if TCL_UTF_MAX == 3 if (ch >= 0x10000) { /* Tcl doesn't do UTF-16, yet. */ PyErr_Format(Tkinter_TclError, "character U+%x is above the range " "(U+0000-U+FFFF) allowed by Tcl", ch); ckfree(FREECAST outbuf); return NULL; } #endif outbuf[i] = ch; } result = Tcl_NewUnicodeObj(outbuf, size); ckfree(FREECAST outbuf); return result; } else if(PyTclObject_Check(value)) { Tcl_Obj *v = ((PyTclObject*)value)->value; Tcl_IncrRefCount(v); return v; } else { PyObject *v = PyObject_Str(value); if (!v) return 0; result = AsObj(v); Py_DECREF(v); return result; } } static PyObject* FromObj(PyObject* tkapp, Tcl_Obj *value) { PyObject *result = NULL; TkappObject *app = (TkappObject*)tkapp; if (value->typePtr == NULL) { return unicodeFromTclStringAndSize(value->bytes, value->length); } if (value->typePtr == app->BooleanType) { result = value->internalRep.longValue ? Py_True : Py_False; Py_INCREF(result); return result; } if (value->typePtr == app->ByteArrayType) { int size; char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); return PyBytes_FromStringAndSize(data, size); } if (value->typePtr == app->DoubleType) { return PyFloat_FromDouble(value->internalRep.doubleValue); } if (value->typePtr == app->IntType) { return PyLong_FromLong(value->internalRep.longValue); } if (value->typePtr == app->ListType) { int size; int i, status; PyObject *elem; Tcl_Obj *tcl_elem; status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size); if (status == TCL_ERROR) return Tkinter_Error(tkapp); result = PyTuple_New(size); if (!result) return NULL; for (i = 0; i < size; i++) { status = Tcl_ListObjIndex(Tkapp_Interp(tkapp), value, i, &tcl_elem); if (status == TCL_ERROR) { Py_DECREF(result); return Tkinter_Error(tkapp); } elem = FromObj(tkapp, tcl_elem); if (!elem) { Py_DECREF(result); return NULL; } PyTuple_SetItem(result, i, elem); } return result; } if (value->typePtr == app->ProcBodyType) { /* fall through: return tcl object. */ } if (value->typePtr == app->StringType) { return PyUnicode_FromKindAndData( sizeof(Tcl_UniChar), Tcl_GetUnicode(value), Tcl_GetCharLength(value)); } return newPyTclObject(value); } #ifdef WITH_THREAD /* This mutex synchronizes inter-thread command calls. */ TCL_DECLARE_MUTEX(call_mutex) typedef struct Tkapp_CallEvent { Tcl_Event ev; /* Must be first */ TkappObject *self; PyObject *args; int flags; PyObject **res; PyObject **exc_type, **exc_value, **exc_tb; Tcl_Condition *done; } Tkapp_CallEvent; #endif void Tkapp_CallDeallocArgs(Tcl_Obj** objv, Tcl_Obj** objStore, int objc) { int i; for (i = 0; i < objc; i++) Tcl_DecrRefCount(objv[i]); if (objv != objStore) ckfree(FREECAST objv); } /* Convert Python objects to Tcl objects. This must happen in the interpreter thread, which may or may not be the calling thread. */ static Tcl_Obj** Tkapp_CallArgs(PyObject *args, Tcl_Obj** objStore, int *pobjc) { Tcl_Obj **objv = objStore; Py_ssize_t objc = 0, i; if (args == NULL) /* do nothing */; else if (!PyTuple_Check(args)) { objv[0] = AsObj(args); if (objv[0] == 0) goto finally; objc = 1; Tcl_IncrRefCount(objv[0]); } else { objc = PyTuple_Size(args); if (objc > ARGSZ) { if (!CHECK_SIZE(objc, sizeof(Tcl_Obj *))) { PyErr_SetString(PyExc_OverflowError, "tuple is too long"); return NULL; } objv = (Tcl_Obj **)ckalloc(((size_t)objc) * sizeof(Tcl_Obj *)); if (objv == NULL) { PyErr_NoMemory(); objc = 0; goto finally; } } for (i = 0; i < objc; i++) { PyObject *v = PyTuple_GetItem(args, i); if (v == Py_None) { objc = i; break; } objv[i] = AsObj(v); if (!objv[i]) { /* Reset objc, so it attempts to clear objects only up to i. */ objc = i; goto finally; } Tcl_IncrRefCount(objv[i]); } } *pobjc = objc; return objv; finally: Tkapp_CallDeallocArgs(objv, objStore, objc); return NULL; } /* Convert the results of a command call into a Python objects. */ static PyObject* Tkapp_CallResult(TkappObject *self) { PyObject *res = NULL; Tcl_Obj *value = Tcl_GetObjResult(self->interp); if(self->wantobjects) { /* Not sure whether the IncrRef is necessary, but something may overwrite the interpreter result while we are converting it. */ Tcl_IncrRefCount(value); res = FromObj((PyObject*)self, value); Tcl_DecrRefCount(value); } else { res = unicodeFromTclObj(value); } return res; } #ifdef WITH_THREAD /* Tkapp_CallProc is the event procedure that is executed in the context of the Tcl interpreter thread. Initially, it holds the Tcl lock, and doesn't hold the Python lock. */ static int Tkapp_CallProc(Tkapp_CallEvent *e, int flags) { Tcl_Obj *objStore[ARGSZ]; Tcl_Obj **objv; int objc; int i; ENTER_PYTHON objv = Tkapp_CallArgs(e->args, objStore, &objc); if (!objv) { PyErr_Fetch(e->exc_type, e->exc_value, e->exc_tb); *(e->res) = NULL; } LEAVE_PYTHON if (!objv) goto done; i = Tcl_EvalObjv(e->self->interp, objc, objv, e->flags); ENTER_PYTHON if (i == TCL_ERROR) { *(e->res) = NULL; *(e->exc_type) = NULL; *(e->exc_tb) = NULL; *(e->exc_value) = PyObject_CallFunction( Tkinter_TclError, "s", Tcl_GetStringResult(e->self->interp)); } else { *(e->res) = Tkapp_CallResult(e->self); } LEAVE_PYTHON Tkapp_CallDeallocArgs(objv, objStore, objc); done: /* Wake up calling thread. */ Tcl_MutexLock(&call_mutex); Tcl_ConditionNotify(e->done); Tcl_MutexUnlock(&call_mutex); return 1; } #endif /* This is the main entry point for calling a Tcl command. It supports three cases, with regard to threading: 1. Tcl is not threaded: Must have the Tcl lock, then can invoke command in the context of the calling thread. 2. Tcl is threaded, caller of the command is in the interpreter thread: Execute the command in the calling thread. Since the Tcl lock will not be used, we can merge that with case 1. 3. Tcl is threaded, caller is in a different thread: Must queue an event to the interpreter thread. Allocation of Tcl objects needs to occur in the interpreter thread, so we ship the PyObject* args to the target thread, and perform processing there. */ static PyObject * Tkapp_Call(PyObject *selfptr, PyObject *args) { Tcl_Obj *objStore[ARGSZ]; Tcl_Obj **objv = NULL; int objc, i; PyObject *res = NULL; TkappObject *self = (TkappObject*)selfptr; int flags = TCL_EVAL_DIRECT | TCL_EVAL_GLOBAL; /* If args is a single tuple, replace with contents of tuple */ if (1 == PyTuple_Size(args)){ PyObject* item = PyTuple_GetItem(args, 0); if (PyTuple_Check(item)) args = item; } #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { /* We cannot call the command directly. Instead, we must marshal the parameters to the interpreter thread. */ Tkapp_CallEvent *ev; Tcl_Condition cond = NULL; PyObject *exc_type, *exc_value, *exc_tb; if (!WaitForMainloop(self)) return NULL; ev = (Tkapp_CallEvent*)ckalloc(sizeof(Tkapp_CallEvent)); ev->ev.proc = (Tcl_EventProc*)Tkapp_CallProc; ev->self = self; ev->args = args; ev->res = &res; ev->exc_type = &exc_type; ev->exc_value = &exc_value; ev->exc_tb = &exc_tb; ev->done = &cond; Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &call_mutex); if (res == NULL) { if (exc_type) PyErr_Restore(exc_type, exc_value, exc_tb); else PyErr_SetObject(Tkinter_TclError, exc_value); } Tcl_ConditionFinalize(&cond); } else #endif { objv = Tkapp_CallArgs(args, objStore, &objc); if (!objv) return NULL; ENTER_TCL i = Tcl_EvalObjv(self->interp, objc, objv, flags); ENTER_OVERLAP if (i == TCL_ERROR) Tkinter_Error(selfptr); else res = Tkapp_CallResult(self); LEAVE_OVERLAP_TCL Tkapp_CallDeallocArgs(objv, objStore, objc); } return res; } static PyObject * Tkapp_Eval(PyObject *self, PyObject *args) { char *script; PyObject *res = NULL; int err; if (!PyArg_ParseTuple(args, "s:eval", &script)) return NULL; CHECK_TCL_APPARTMENT; ENTER_TCL err = Tcl_Eval(Tkapp_Interp(self), script); ENTER_OVERLAP if (err == TCL_ERROR) res = Tkinter_Error(self); else res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_EvalFile(PyObject *self, PyObject *args) { char *fileName; PyObject *res = NULL; int err; if (!PyArg_ParseTuple(args, "s:evalfile", &fileName)) return NULL; CHECK_TCL_APPARTMENT; ENTER_TCL err = Tcl_EvalFile(Tkapp_Interp(self), fileName); ENTER_OVERLAP if (err == TCL_ERROR) res = Tkinter_Error(self); else res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_Record(PyObject *self, PyObject *args) { char *script; PyObject *res = NULL; int err; if (!PyArg_ParseTuple(args, "s", &script)) return NULL; CHECK_TCL_APPARTMENT; ENTER_TCL err = Tcl_RecordAndEval(Tkapp_Interp(self), script, TCL_NO_EVAL); ENTER_OVERLAP if (err == TCL_ERROR) res = Tkinter_Error(self); else res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_AddErrorInfo(PyObject *self, PyObject *args) { char *msg; if (!PyArg_ParseTuple(args, "s:adderrorinfo", &msg)) return NULL; CHECK_TCL_APPARTMENT; ENTER_TCL Tcl_AddErrorInfo(Tkapp_Interp(self), msg); LEAVE_TCL Py_RETURN_NONE; } /** Tcl Variable **/ typedef PyObject* (*EventFunc)(PyObject*, PyObject *args, int flags); #ifdef WITH_THREAD TCL_DECLARE_MUTEX(var_mutex) typedef struct VarEvent { Tcl_Event ev; /* must be first */ PyObject *self; PyObject *args; int flags; EventFunc func; PyObject **res; PyObject **exc_type; PyObject **exc_val; Tcl_Condition *cond; } VarEvent; #endif static int varname_converter(PyObject *in, void *_out) { char *s; char **out = (char**)_out; if (PyBytes_Check(in)) { if (PyBytes_Size(in) > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); return 0; } s = PyBytes_AsString(in); if (strlen(s) != PyBytes_Size(in)) { PyErr_SetString(PyExc_ValueError, "null byte in bytes object"); return 0; } *out = s; return 1; } if (PyUnicode_Check(in)) { Py_ssize_t size; s = PyUnicode_AsUTF8AndSize(in, &size); if (s == NULL) { return 0; } if (size > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return 0; } if (strlen(s) != size) { PyErr_SetString(PyExc_ValueError, "null character in string"); return 0; } *out = s; return 1; } if (PyTclObject_Check(in)) { *out = PyTclObject_TclString(in); return 1; } PyErr_Format(PyExc_TypeError, "must be str, bytes or Tcl_Obj, not %.50s", in->ob_type->tp_name); return 0; } #ifdef WITH_THREAD static void var_perform(VarEvent *ev) { *(ev->res) = ev->func(ev->self, ev->args, ev->flags); if (!*(ev->res)) { PyObject *exc, *val, *tb; PyErr_Fetch(&exc, &val, &tb); PyErr_NormalizeException(&exc, &val, &tb); *(ev->exc_type) = exc; *(ev->exc_val) = val; Py_DECREF(tb); } } static int var_proc(VarEvent* ev, int flags) { ENTER_PYTHON var_perform(ev); Tcl_MutexLock(&var_mutex); Tcl_ConditionNotify(ev->cond); Tcl_MutexUnlock(&var_mutex); LEAVE_PYTHON return 1; } #endif static PyObject* var_invoke(EventFunc func, PyObject *selfptr, PyObject *args, int flags) { #ifdef WITH_THREAD TkappObject *self = (TkappObject*)selfptr; if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { TkappObject *self = (TkappObject*)selfptr; VarEvent *ev; PyObject *res, *exc_type, *exc_val; Tcl_Condition cond = NULL; /* The current thread is not the interpreter thread. Marshal the call to the interpreter thread, then wait for completion. */ if (!WaitForMainloop(self)) return NULL; ev = (VarEvent*)ckalloc(sizeof(VarEvent)); ev->self = selfptr; ev->args = args; ev->flags = flags; ev->func = func; ev->res = &res; ev->exc_type = &exc_type; ev->exc_val = &exc_val; ev->cond = &cond; ev->ev.proc = (Tcl_EventProc*)var_proc; Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &var_mutex); Tcl_ConditionFinalize(&cond); if (!res) { PyErr_SetObject(exc_type, exc_val); Py_DECREF(exc_type); Py_DECREF(exc_val); return NULL; } return res; } #endif /* Tcl is not threaded, or this is the interpreter thread. */ return func(selfptr, args, flags); } static PyObject * SetVar(PyObject *self, PyObject *args, int flags) { char *name1, *name2; PyObject *newValue; PyObject *res = NULL; Tcl_Obj *newval, *ok; switch (PyTuple_GET_SIZE(args)) { case 2: if (!PyArg_ParseTuple(args, "O&O:setvar", varname_converter, &name1, &newValue)) return NULL; /* XXX Acquire tcl lock??? */ newval = AsObj(newValue); if (newval == NULL) return NULL; ENTER_TCL ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, NULL, newval, flags); ENTER_OVERLAP if (!ok) Tkinter_Error(self); else { res = Py_None; Py_INCREF(res); } LEAVE_OVERLAP_TCL break; case 3: if (!PyArg_ParseTuple(args, "ssO:setvar", &name1, &name2, &newValue)) return NULL; /* XXX must hold tcl lock already??? */ newval = AsObj(newValue); ENTER_TCL ok = Tcl_SetVar2Ex(Tkapp_Interp(self), name1, name2, newval, flags); ENTER_OVERLAP if (!ok) Tkinter_Error(self); else { res = Py_None; Py_INCREF(res); } LEAVE_OVERLAP_TCL break; default: PyErr_SetString(PyExc_TypeError, "setvar requires 2 to 3 arguments"); return NULL; } return res; } static PyObject * Tkapp_SetVar(PyObject *self, PyObject *args) { return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG); } static PyObject * Tkapp_GlobalSetVar(PyObject *self, PyObject *args) { return var_invoke(SetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); } static PyObject * GetVar(PyObject *self, PyObject *args, int flags) { char *name1, *name2=NULL; PyObject *res = NULL; Tcl_Obj *tres; if (!PyArg_ParseTuple(args, "O&|s:getvar", varname_converter, &name1, &name2)) return NULL; ENTER_TCL tres = Tcl_GetVar2Ex(Tkapp_Interp(self), name1, name2, flags); ENTER_OVERLAP if (tres == NULL) { PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self))); } else { if (((TkappObject*)self)->wantobjects) { res = FromObj(self, tres); } else { res = unicodeFromTclObj(tres); } } LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_GetVar(PyObject *self, PyObject *args) { return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG); } static PyObject * Tkapp_GlobalGetVar(PyObject *self, PyObject *args) { return var_invoke(GetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); } static PyObject * UnsetVar(PyObject *self, PyObject *args, int flags) { char *name1, *name2=NULL; int code; PyObject *res = NULL; if (!PyArg_ParseTuple(args, "s|s:unsetvar", &name1, &name2)) return NULL; ENTER_TCL code = Tcl_UnsetVar2(Tkapp_Interp(self), name1, name2, flags); ENTER_OVERLAP if (code == TCL_ERROR) res = Tkinter_Error(self); else { Py_INCREF(Py_None); res = Py_None; } LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_UnsetVar(PyObject *self, PyObject *args) { return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG); } static PyObject * Tkapp_GlobalUnsetVar(PyObject *self, PyObject *args) { return var_invoke(UnsetVar, self, args, TCL_LEAVE_ERR_MSG | TCL_GLOBAL_ONLY); } /** Tcl to Python **/ static PyObject * Tkapp_GetInt(PyObject *self, PyObject *args) { char *s; int v; if (PyTuple_Size(args) == 1) { PyObject* o = PyTuple_GetItem(args, 0); if (PyLong_Check(o)) { Py_INCREF(o); return o; } } if (!PyArg_ParseTuple(args, "s:getint", &s)) return NULL; if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR) return Tkinter_Error(self); return Py_BuildValue("i", v); } static PyObject * Tkapp_GetDouble(PyObject *self, PyObject *args) { char *s; double v; if (PyTuple_Size(args) == 1) { PyObject *o = PyTuple_GetItem(args, 0); if (PyFloat_Check(o)) { Py_INCREF(o); return o; } } if (!PyArg_ParseTuple(args, "s:getdouble", &s)) return NULL; if (Tcl_GetDouble(Tkapp_Interp(self), s, &v) == TCL_ERROR) return Tkinter_Error(self); return Py_BuildValue("d", v); } static PyObject * Tkapp_GetBoolean(PyObject *self, PyObject *args) { char *s; int v; if (PyTuple_Size(args) == 1) { PyObject *o = PyTuple_GetItem(args, 0); if (PyLong_Check(o)) { Py_INCREF(o); return o; } } if (!PyArg_ParseTuple(args, "s:getboolean", &s)) return NULL; if (Tcl_GetBoolean(Tkapp_Interp(self), s, &v) == TCL_ERROR) return Tkinter_Error(self); return PyBool_FromLong(v); } static PyObject * Tkapp_ExprString(PyObject *self, PyObject *args) { char *s; PyObject *res = NULL; int retval; if (!PyArg_ParseTuple(args, "s:exprstring", &s)) return NULL; CHECK_TCL_APPARTMENT; ENTER_TCL retval = Tcl_ExprString(Tkapp_Interp(self), s); ENTER_OVERLAP if (retval == TCL_ERROR) res = Tkinter_Error(self); else res = unicodeFromTclString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_ExprLong(PyObject *self, PyObject *args) { char *s; PyObject *res = NULL; int retval; long v; if (!PyArg_ParseTuple(args, "s:exprlong", &s)) return NULL; CHECK_TCL_APPARTMENT; ENTER_TCL retval = Tcl_ExprLong(Tkapp_Interp(self), s, &v); ENTER_OVERLAP if (retval == TCL_ERROR) res = Tkinter_Error(self); else res = Py_BuildValue("l", v); LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_ExprDouble(PyObject *self, PyObject *args) { char *s; PyObject *res = NULL; double v; int retval; if (!PyArg_ParseTuple(args, "s:exprdouble", &s)) return NULL; CHECK_TCL_APPARTMENT; PyFPE_START_PROTECT("Tkapp_ExprDouble", return 0) ENTER_TCL retval = Tcl_ExprDouble(Tkapp_Interp(self), s, &v); ENTER_OVERLAP PyFPE_END_PROTECT(retval) if (retval == TCL_ERROR) res = Tkinter_Error(self); else res = Py_BuildValue("d", v); LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_ExprBoolean(PyObject *self, PyObject *args) { char *s; PyObject *res = NULL; int retval; int v; if (!PyArg_ParseTuple(args, "s:exprboolean", &s)) return NULL; CHECK_TCL_APPARTMENT; ENTER_TCL retval = Tcl_ExprBoolean(Tkapp_Interp(self), s, &v); ENTER_OVERLAP if (retval == TCL_ERROR) res = Tkinter_Error(self); else res = Py_BuildValue("i", v); LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_SplitList(PyObject *self, PyObject *args) { char *list; int argc; char **argv; PyObject *arg, *v; int i; if (!PyArg_ParseTuple(args, "O:splitlist", &arg)) return NULL; if (PyTclObject_Check(arg)) { int objc; Tcl_Obj **objv; if (Tcl_ListObjGetElements(Tkapp_Interp(self), ((PyTclObject*)arg)->value, &objc, &objv) == TCL_ERROR) { return Tkinter_Error(self); } if (!(v = PyTuple_New(objc))) return NULL; for (i = 0; i < objc; i++) { PyObject *s = FromObj(self, objv[i]); if (!s || PyTuple_SetItem(v, i, s)) { Py_DECREF(v); return NULL; } } return v; } if (PyTuple_Check(arg)) { Py_INCREF(arg); return arg; } if (!PyArg_ParseTuple(args, "et:splitlist", "utf-8", &list)) return NULL; if (Tcl_SplitList(Tkapp_Interp(self), list, &argc, &argv) == TCL_ERROR) { PyMem_Free(list); return Tkinter_Error(self); } if (!(v = PyTuple_New(argc))) goto finally; for (i = 0; i < argc; i++) { PyObject *s = unicodeFromTclString(argv[i]); if (!s || PyTuple_SetItem(v, i, s)) { Py_DECREF(v); v = NULL; goto finally; } } finally: ckfree(FREECAST argv); PyMem_Free(list); return v; } static PyObject * Tkapp_Split(PyObject *self, PyObject *args) { PyObject *arg, *v; char *list; if (!PyArg_ParseTuple(args, "O:split", &arg)) return NULL; if (PyTclObject_Check(arg)) { Tcl_Obj *value = ((PyTclObject*)arg)->value; int objc; Tcl_Obj **objv; int i; if (Tcl_ListObjGetElements(Tkapp_Interp(self), value, &objc, &objv) == TCL_ERROR) { return FromObj(self, value); } if (objc == 0) return PyUnicode_FromString(""); if (objc == 1) return FromObj(self, objv[0]); if (!(v = PyTuple_New(objc))) return NULL; for (i = 0; i < objc; i++) { PyObject *s = FromObj(self, objv[i]); if (!s || PyTuple_SetItem(v, i, s)) { Py_DECREF(v); return NULL; } } return v; } if (PyTuple_Check(arg)) return SplitObj(arg); if (!PyArg_ParseTuple(args, "et:split", "utf-8", &list)) return NULL; v = Split(list); PyMem_Free(list); return v; } /** Tcl Command **/ /* Client data struct */ typedef struct { PyObject *self; PyObject *func; } PythonCmd_ClientData; static int PythonCmd_Error(Tcl_Interp *interp) { errorInCmd = 1; PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); LEAVE_PYTHON return TCL_ERROR; } /* This is the Tcl command that acts as a wrapper for Python * function or method. */ static int PythonCmd(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) { PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; PyObject *func, *arg, *res; int i, rv; Tcl_Obj *obj_res; ENTER_PYTHON /* TBD: no error checking here since we know, via the * Tkapp_CreateCommand() that the client data is a two-tuple */ func = data->func; /* Create argument list (argv1, ..., argvN) */ if (!(arg = PyTuple_New(argc - 1))) return PythonCmd_Error(interp); for (i = 0; i < (argc - 1); i++) { PyObject *s = unicodeFromTclString(argv[i + 1]); if (!s || PyTuple_SetItem(arg, i, s)) { Py_DECREF(arg); return PythonCmd_Error(interp); } } res = PyEval_CallObject(func, arg); Py_DECREF(arg); if (res == NULL) return PythonCmd_Error(interp); obj_res = AsObj(res); if (obj_res == NULL) { Py_DECREF(res); return PythonCmd_Error(interp); } else { Tcl_SetObjResult(interp, obj_res); rv = TCL_OK; } Py_DECREF(res); LEAVE_PYTHON return rv; } static void PythonCmdDelete(ClientData clientData) { PythonCmd_ClientData *data = (PythonCmd_ClientData *)clientData; ENTER_PYTHON Py_XDECREF(data->self); Py_XDECREF(data->func); PyMem_DEL(data); LEAVE_PYTHON } #ifdef WITH_THREAD TCL_DECLARE_MUTEX(command_mutex) typedef struct CommandEvent{ Tcl_Event ev; Tcl_Interp* interp; char *name; int create; int *status; ClientData *data; Tcl_Condition *done; } CommandEvent; static int Tkapp_CommandProc(CommandEvent *ev, int flags) { if (ev->create) *ev->status = Tcl_CreateCommand( ev->interp, ev->name, PythonCmd, ev->data, PythonCmdDelete) == NULL; else *ev->status = Tcl_DeleteCommand(ev->interp, ev->name); Tcl_MutexLock(&command_mutex); Tcl_ConditionNotify(ev->done); Tcl_MutexUnlock(&command_mutex); return 1; } #endif static PyObject * Tkapp_CreateCommand(PyObject *selfptr, PyObject *args) { TkappObject *self = (TkappObject*)selfptr; PythonCmd_ClientData *data; char *cmdName; PyObject *func; int err; if (!PyArg_ParseTuple(args, "sO:createcommand", &cmdName, &func)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "command not callable"); return NULL; } #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread() && !WaitForMainloop(self)) return NULL; #endif data = PyMem_NEW(PythonCmd_ClientData, 1); if (!data) return PyErr_NoMemory(); Py_INCREF(self); Py_INCREF(func); data->self = selfptr; data->func = func; #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; CommandEvent *ev = (CommandEvent*)ckalloc(sizeof(CommandEvent)); ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; ev->interp = self->interp; ev->create = 1; ev->name = cmdName; ev->data = (ClientData)data; ev->status = &err; ev->done = &cond; Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex); Tcl_ConditionFinalize(&cond); } else #endif { ENTER_TCL err = Tcl_CreateCommand( Tkapp_Interp(self), cmdName, PythonCmd, (ClientData)data, PythonCmdDelete) == NULL; LEAVE_TCL } if (err) { PyErr_SetString(Tkinter_TclError, "can't create Tcl command"); PyMem_DEL(data); return NULL; } Py_RETURN_NONE; } static PyObject * Tkapp_DeleteCommand(PyObject *selfptr, PyObject *args) { TkappObject *self = (TkappObject*)selfptr; char *cmdName; int err; if (!PyArg_ParseTuple(args, "s:deletecommand", &cmdName)) return NULL; #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; CommandEvent *ev; ev = (CommandEvent*)ckalloc(sizeof(CommandEvent)); ev->ev.proc = (Tcl_EventProc*)Tkapp_CommandProc; ev->interp = self->interp; ev->create = 0; ev->name = cmdName; ev->status = &err; ev->done = &cond; Tkapp_ThreadSend(self, (Tcl_Event*)ev, &cond, &command_mutex); Tcl_ConditionFinalize(&cond); } else #endif { ENTER_TCL err = Tcl_DeleteCommand(self->interp, cmdName); LEAVE_TCL } if (err == -1) { PyErr_SetString(Tkinter_TclError, "can't delete Tcl command"); return NULL; } Py_RETURN_NONE; } #ifdef HAVE_CREATEFILEHANDLER /** File Handler **/ typedef struct _fhcdata { PyObject *func; PyObject *file; int id; struct _fhcdata *next; } FileHandler_ClientData; static FileHandler_ClientData *HeadFHCD; static FileHandler_ClientData * NewFHCD(PyObject *func, PyObject *file, int id) { FileHandler_ClientData *p; p = PyMem_NEW(FileHandler_ClientData, 1); if (p != NULL) { Py_XINCREF(func); Py_XINCREF(file); p->func = func; p->file = file; p->id = id; p->next = HeadFHCD; HeadFHCD = p; } return p; } static void DeleteFHCD(int id) { FileHandler_ClientData *p, **pp; pp = &HeadFHCD; while ((p = *pp) != NULL) { if (p->id == id) { *pp = p->next; Py_XDECREF(p->func); Py_XDECREF(p->file); PyMem_DEL(p); } else pp = &p->next; } } static void FileHandler(ClientData clientData, int mask) { FileHandler_ClientData *data = (FileHandler_ClientData *)clientData; PyObject *func, *file, *arg, *res; ENTER_PYTHON func = data->func; file = data->file; arg = Py_BuildValue("(Oi)", file, (long) mask); res = PyEval_CallObject(func, arg); Py_DECREF(arg); if (res == NULL) { errorInCmd = 1; PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); } Py_XDECREF(res); LEAVE_PYTHON } static PyObject * Tkapp_CreateFileHandler(PyObject *self, PyObject *args) /* args is (file, mask, func) */ { FileHandler_ClientData *data; PyObject *file, *func; int mask, tfile; if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func)) return NULL; CHECK_TCL_APPARTMENT; tfile = PyObject_AsFileDescriptor(file); if (tfile < 0) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "bad argument list"); return NULL; } data = NewFHCD(func, file, tfile); if (data == NULL) return NULL; /* Ought to check for null Tcl_File object... */ ENTER_TCL Tcl_CreateFileHandler(tfile, mask, FileHandler, (ClientData) data); LEAVE_TCL Py_RETURN_NONE; } static PyObject * Tkapp_DeleteFileHandler(PyObject *self, PyObject *args) { PyObject *file; int tfile; if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file)) return NULL; CHECK_TCL_APPARTMENT; tfile = PyObject_AsFileDescriptor(file); if (tfile < 0) return NULL; DeleteFHCD(tfile); /* Ought to check for null Tcl_File object... */ ENTER_TCL Tcl_DeleteFileHandler(tfile); LEAVE_TCL Py_RETURN_NONE; } #endif /* HAVE_CREATEFILEHANDLER */ /**** Tktt Object (timer token) ****/ static PyObject *Tktt_Type; typedef struct { PyObject_HEAD Tcl_TimerToken token; PyObject *func; } TkttObject; static PyObject * Tktt_DeleteTimerHandler(PyObject *self, PyObject *args) { TkttObject *v = (TkttObject *)self; PyObject *func = v->func; if (!PyArg_ParseTuple(args, ":deletetimerhandler")) return NULL; if (v->token != NULL) { Tcl_DeleteTimerHandler(v->token); v->token = NULL; } if (func != NULL) { v->func = NULL; Py_DECREF(func); Py_DECREF(v); /* See Tktt_New() */ } Py_RETURN_NONE; } static PyMethodDef Tktt_methods[] = { {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS}, {NULL, NULL} }; static TkttObject * Tktt_New(PyObject *func) { TkttObject *v; v = PyObject_New(TkttObject, (PyTypeObject *) Tktt_Type); if (v == NULL) return NULL; Py_INCREF(Tktt_Type); Py_INCREF(func); v->token = NULL; v->func = func; /* Extra reference, deleted when called or when handler is deleted */ Py_INCREF(v); return v; } static void Tktt_Dealloc(PyObject *self) { TkttObject *v = (TkttObject *)self; PyObject *func = v->func; PyObject *tp = (PyObject *) Py_TYPE(self); Py_XDECREF(func); PyObject_Del(self); Py_DECREF(tp); } static PyObject * Tktt_Repr(PyObject *self) { TkttObject *v = (TkttObject *)self; return PyUnicode_FromFormat("", v, v->func == NULL ? ", handler deleted" : ""); } static PyType_Slot Tktt_Type_slots[] = { {Py_tp_dealloc, Tktt_Dealloc}, {Py_tp_repr, Tktt_Repr}, {Py_tp_methods, Tktt_methods}, {0, 0} }; static PyType_Spec Tktt_Type_spec = { "tktimertoken", sizeof(TkttObject), 0, Py_TPFLAGS_DEFAULT, Tktt_Type_slots, }; /** Timer Handler **/ static void TimerHandler(ClientData clientData) { TkttObject *v = (TkttObject *)clientData; PyObject *func = v->func; PyObject *res; if (func == NULL) return; v->func = NULL; ENTER_PYTHON res = PyEval_CallObject(func, NULL); Py_DECREF(func); Py_DECREF(v); /* See Tktt_New() */ if (res == NULL) { errorInCmd = 1; PyErr_Fetch(&excInCmd, &valInCmd, &trbInCmd); } else Py_DECREF(res); LEAVE_PYTHON } static PyObject * Tkapp_CreateTimerHandler(PyObject *self, PyObject *args) { int milliseconds; PyObject *func; TkttObject *v; if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "bad argument list"); return NULL; } CHECK_TCL_APPARTMENT; v = Tktt_New(func); if (v) { v->token = Tcl_CreateTimerHandler(milliseconds, TimerHandler, (ClientData)v); } return (PyObject *) v; } /** Event Loop **/ static PyObject * Tkapp_MainLoop(PyObject *selfptr, PyObject *args) { int threshold = 0; TkappObject *self = (TkappObject*)selfptr; #ifdef WITH_THREAD PyThreadState *tstate = PyThreadState_Get(); #endif if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold)) return NULL; CHECK_TCL_APPARTMENT; self->dispatching = 1; quitMainLoop = 0; while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && !errorInCmd) { int result; #ifdef WITH_THREAD if (self->threaded) { /* Allow other Python threads to run. */ ENTER_TCL result = Tcl_DoOneEvent(0); LEAVE_TCL } else { Py_BEGIN_ALLOW_THREADS if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = tstate; result = Tcl_DoOneEvent(TCL_DONT_WAIT); tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); if (result == 0) Sleep(Tkinter_busywaitinterval); Py_END_ALLOW_THREADS } #else result = Tcl_DoOneEvent(0); #endif if (PyErr_CheckSignals() != 0) { self->dispatching = 0; return NULL; } if (result < 0) break; } self->dispatching = 0; quitMainLoop = 0; if (errorInCmd) { errorInCmd = 0; PyErr_Restore(excInCmd, valInCmd, trbInCmd); excInCmd = valInCmd = trbInCmd = NULL; return NULL; } Py_RETURN_NONE; } static PyObject * Tkapp_DoOneEvent(PyObject *self, PyObject *args) { int flags = 0; int rv; if (!PyArg_ParseTuple(args, "|i:dooneevent", &flags)) return NULL; ENTER_TCL rv = Tcl_DoOneEvent(flags); LEAVE_TCL return Py_BuildValue("i", rv); } static PyObject * Tkapp_Quit(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":quit")) return NULL; quitMainLoop = 1; Py_RETURN_NONE; } static PyObject * Tkapp_InterpAddr(PyObject *self, PyObject *args) { if (!PyArg_ParseTuple(args, ":interpaddr")) return NULL; return PyLong_FromVoidPtr(Tkapp_Interp(self)); } static PyObject * Tkapp_TkInit(PyObject *self, PyObject *args) { Tcl_Interp *interp = Tkapp_Interp(self); const char * _tk_exists = NULL; int err; #ifdef TKINTER_PROTECT_LOADTK /* Up to Tk 8.4.13, Tk_Init deadlocks on the second call when the * first call failed. * To avoid the deadlock, we just refuse the second call through * a static variable. */ if (tk_load_failed) { PyErr_SetString(Tkinter_TclError, TKINTER_LOADTK_ERRMSG); return NULL; } #endif /* We want to guard against calling Tk_Init() multiple times */ CHECK_TCL_APPARTMENT; ENTER_TCL err = Tcl_Eval(Tkapp_Interp(self), "info exists tk_version"); ENTER_OVERLAP if (err == TCL_ERROR) { /* This sets an exception, but we cannot return right away because we need to exit the overlap first. */ Tkinter_Error(self); } else { _tk_exists = Tkapp_Result(self); } LEAVE_OVERLAP_TCL if (err == TCL_ERROR) { return NULL; } if (_tk_exists == NULL || strcmp(_tk_exists, "1") != 0) { if (Tk_Init(interp) == TCL_ERROR) { PyErr_SetString(Tkinter_TclError, Tcl_GetStringResult(Tkapp_Interp(self))); #ifdef TKINTER_PROTECT_LOADTK tk_load_failed = 1; #endif return NULL; } } Py_RETURN_NONE; } static PyObject * Tkapp_WantObjects(PyObject *self, PyObject *args) { int wantobjects = -1; if (!PyArg_ParseTuple(args, "|i:wantobjects", &wantobjects)) return NULL; if (wantobjects == -1) return PyBool_FromLong(((TkappObject*)self)->wantobjects); ((TkappObject*)self)->wantobjects = wantobjects; Py_RETURN_NONE; } static PyObject * Tkapp_WillDispatch(PyObject *self, PyObject *args) { ((TkappObject*)self)->dispatching = 1; Py_RETURN_NONE; } /**** Tkapp Method List ****/ static PyMethodDef Tkapp_methods[] = { {"willdispatch", Tkapp_WillDispatch, METH_NOARGS}, {"wantobjects", Tkapp_WantObjects, METH_VARARGS}, {"call", Tkapp_Call, METH_VARARGS}, {"eval", Tkapp_Eval, METH_VARARGS}, {"evalfile", Tkapp_EvalFile, METH_VARARGS}, {"record", Tkapp_Record, METH_VARARGS}, {"adderrorinfo", Tkapp_AddErrorInfo, METH_VARARGS}, {"setvar", Tkapp_SetVar, METH_VARARGS}, {"globalsetvar", Tkapp_GlobalSetVar, METH_VARARGS}, {"getvar", Tkapp_GetVar, METH_VARARGS}, {"globalgetvar", Tkapp_GlobalGetVar, METH_VARARGS}, {"unsetvar", Tkapp_UnsetVar, METH_VARARGS}, {"globalunsetvar", Tkapp_GlobalUnsetVar, METH_VARARGS}, {"getint", Tkapp_GetInt, METH_VARARGS}, {"getdouble", Tkapp_GetDouble, METH_VARARGS}, {"getboolean", Tkapp_GetBoolean, METH_VARARGS}, {"exprstring", Tkapp_ExprString, METH_VARARGS}, {"exprlong", Tkapp_ExprLong, METH_VARARGS}, {"exprdouble", Tkapp_ExprDouble, METH_VARARGS}, {"exprboolean", Tkapp_ExprBoolean, METH_VARARGS}, {"splitlist", Tkapp_SplitList, METH_VARARGS}, {"split", Tkapp_Split, METH_VARARGS}, {"createcommand", Tkapp_CreateCommand, METH_VARARGS}, {"deletecommand", Tkapp_DeleteCommand, METH_VARARGS}, #ifdef HAVE_CREATEFILEHANDLER {"createfilehandler", Tkapp_CreateFileHandler, METH_VARARGS}, {"deletefilehandler", Tkapp_DeleteFileHandler, METH_VARARGS}, #endif {"createtimerhandler", Tkapp_CreateTimerHandler, METH_VARARGS}, {"mainloop", Tkapp_MainLoop, METH_VARARGS}, {"dooneevent", Tkapp_DoOneEvent, METH_VARARGS}, {"quit", Tkapp_Quit, METH_VARARGS}, {"interpaddr", Tkapp_InterpAddr, METH_VARARGS}, {"loadtk", Tkapp_TkInit, METH_NOARGS}, {NULL, NULL} }; /**** Tkapp Type Methods ****/ static void Tkapp_Dealloc(PyObject *self) { PyObject *tp = (PyObject *) Py_TYPE(self); /*CHECK_TCL_APPARTMENT;*/ ENTER_TCL Tcl_DeleteInterp(Tkapp_Interp(self)); LEAVE_TCL PyObject_Del(self); Py_DECREF(tp); DisableEventHook(); } static PyType_Slot Tkapp_Type_slots[] = { {Py_tp_dealloc, Tkapp_Dealloc}, {Py_tp_methods, Tkapp_methods}, {0, 0} }; static PyType_Spec Tkapp_Type_spec = { "tkapp", sizeof(TkappObject), 0, Py_TPFLAGS_DEFAULT, Tkapp_Type_slots, }; /**** Tkinter Module ****/ typedef struct { PyObject* tuple; int size; /* current size */ int maxsize; /* allocated size */ } FlattenContext; static int _bump(FlattenContext* context, int size) { /* expand tuple to hold (at least) size new items. return true if successful, false if an exception was raised */ int maxsize = context->maxsize * 2; if (maxsize < context->size + size) maxsize = context->size + size; context->maxsize = maxsize; return _PyTuple_Resize(&context->tuple, maxsize) >= 0; } static int _flatten1(FlattenContext* context, PyObject* item, int depth) { /* add tuple or list to argument tuple (recursively) */ int i, size; if (depth > 1000) { PyErr_SetString(PyExc_ValueError, "nesting too deep in _flatten"); return 0; } else if (PyList_Check(item)) { size = PyList_GET_SIZE(item); /* preallocate (assume no nesting) */ if (context->size + size > context->maxsize && !_bump(context, size)) return 0; /* copy items to output tuple */ for (i = 0; i < size; i++) { PyObject *o = PyList_GET_ITEM(item, i); if (PyList_Check(o) || PyTuple_Check(o)) { if (!_flatten1(context, o, depth + 1)) return 0; } else if (o != Py_None) { if (context->size + 1 > context->maxsize && !_bump(context, 1)) return 0; Py_INCREF(o); PyTuple_SET_ITEM(context->tuple, context->size++, o); } } } else if (PyTuple_Check(item)) { /* same, for tuples */ size = PyTuple_GET_SIZE(item); if (context->size + size > context->maxsize && !_bump(context, size)) return 0; for (i = 0; i < size; i++) { PyObject *o = PyTuple_GET_ITEM(item, i); if (PyList_Check(o) || PyTuple_Check(o)) { if (!_flatten1(context, o, depth + 1)) return 0; } else if (o != Py_None) { if (context->size + 1 > context->maxsize && !_bump(context, 1)) return 0; Py_INCREF(o); PyTuple_SET_ITEM(context->tuple, context->size++, o); } } } else { PyErr_SetString(PyExc_TypeError, "argument must be sequence"); return 0; } return 1; } static PyObject * Tkinter_Flatten(PyObject* self, PyObject* args) { FlattenContext context; PyObject* item; if (!PyArg_ParseTuple(args, "O:_flatten", &item)) return NULL; context.maxsize = PySequence_Size(item); if (context.maxsize < 0) return NULL; if (context.maxsize == 0) return PyTuple_New(0); context.tuple = PyTuple_New(context.maxsize); if (!context.tuple) return NULL; context.size = 0; if (!_flatten1(&context, item,0)) return NULL; if (_PyTuple_Resize(&context.tuple, context.size)) return NULL; return context.tuple; } static PyObject * Tkinter_Create(PyObject *self, PyObject *args) { char *screenName = NULL; char *baseName = NULL; /* XXX this is not used anymore; try getting rid of it. */ char *className = NULL; int interactive = 0; int wantobjects = 0; int wantTk = 1; /* If false, then Tk_Init() doesn't get called */ int sync = 0; /* pass -sync to wish */ char *use = NULL; /* pass -use to wish */ className = "Tk"; if (!PyArg_ParseTuple(args, "|zssiiiiz:create", &screenName, &baseName, &className, &interactive, &wantobjects, &wantTk, &sync, &use)) return NULL; return (PyObject *) Tkapp_New(screenName, className, interactive, wantobjects, wantTk, sync, use); } static PyObject * Tkinter_setbusywaitinterval(PyObject *self, PyObject *args) { int new_val; if (!PyArg_ParseTuple(args, "i:setbusywaitinterval", &new_val)) return NULL; if (new_val < 0) { PyErr_SetString(PyExc_ValueError, "busywaitinterval must be >= 0"); return NULL; } Tkinter_busywaitinterval = new_val; Py_RETURN_NONE; } static char setbusywaitinterval_doc[] = "setbusywaitinterval(n) -> None\n\ \n\ Set the busy-wait interval in milliseconds between successive\n\ calls to Tcl_DoOneEvent in a threaded Python interpreter.\n\ It should be set to a divisor of the maximum time between\n\ frames in an animation."; static PyObject * Tkinter_getbusywaitinterval(PyObject *self, PyObject *args) { return PyLong_FromLong(Tkinter_busywaitinterval); } static char getbusywaitinterval_doc[] = "getbusywaitinterval() -> int\n\ \n\ Return the current busy-wait interval between successive\n\ calls to Tcl_DoOneEvent in a threaded Python interpreter."; static PyMethodDef moduleMethods[] = { {"_flatten", Tkinter_Flatten, METH_VARARGS}, {"create", Tkinter_Create, METH_VARARGS}, {"setbusywaitinterval",Tkinter_setbusywaitinterval, METH_VARARGS, setbusywaitinterval_doc}, {"getbusywaitinterval",(PyCFunction)Tkinter_getbusywaitinterval, METH_NOARGS, getbusywaitinterval_doc}, {NULL, NULL} }; #ifdef WAIT_FOR_STDIN static int stdin_ready = 0; #ifndef MS_WINDOWS static void MyFileProc(void *clientData, int mask) { stdin_ready = 1; } #endif #ifdef WITH_THREAD static PyThreadState *event_tstate = NULL; #endif static int EventHook(void) { #ifndef MS_WINDOWS int tfile; #endif #ifdef WITH_THREAD PyEval_RestoreThread(event_tstate); #endif stdin_ready = 0; errorInCmd = 0; #ifndef MS_WINDOWS tfile = fileno(stdin); Tcl_CreateFileHandler(tfile, TCL_READABLE, MyFileProc, NULL); #endif while (!errorInCmd && !stdin_ready) { int result; #ifdef MS_WINDOWS if (_kbhit()) { stdin_ready = 1; break; } #endif #if defined(WITH_THREAD) || defined(MS_WINDOWS) Py_BEGIN_ALLOW_THREADS if(tcl_lock)PyThread_acquire_lock(tcl_lock, 1); tcl_tstate = event_tstate; result = Tcl_DoOneEvent(TCL_DONT_WAIT); tcl_tstate = NULL; if(tcl_lock)PyThread_release_lock(tcl_lock); if (result == 0) Sleep(Tkinter_busywaitinterval); Py_END_ALLOW_THREADS #else result = Tcl_DoOneEvent(0); #endif if (result < 0) break; } #ifndef MS_WINDOWS Tcl_DeleteFileHandler(tfile); #endif if (errorInCmd) { errorInCmd = 0; PyErr_Restore(excInCmd, valInCmd, trbInCmd); excInCmd = valInCmd = trbInCmd = NULL; PyErr_Print(); } #ifdef WITH_THREAD PyEval_SaveThread(); #endif return 0; } #endif static void EnableEventHook(void) { #ifdef WAIT_FOR_STDIN if (PyOS_InputHook == NULL) { #ifdef WITH_THREAD event_tstate = PyThreadState_Get(); #endif PyOS_InputHook = EventHook; } #endif } static void DisableEventHook(void) { #ifdef WAIT_FOR_STDIN if (Tk_GetNumMainWindows() == 0 && PyOS_InputHook == EventHook) { PyOS_InputHook = NULL; } #endif } static struct PyModuleDef _tkintermodule = { PyModuleDef_HEAD_INIT, "_tkinter", NULL, -1, moduleMethods, NULL, NULL, NULL, NULL }; PyMODINIT_FUNC PyInit__tkinter(void) { PyObject *m, *uexe, *cexe, *o; #ifdef WITH_THREAD tcl_lock = PyThread_allocate_lock(); if (tcl_lock == NULL) return NULL; #endif m = PyModule_Create(&_tkintermodule); if (m == NULL) return NULL; o = PyErr_NewException("_tkinter.TclError", NULL, NULL); if (o == NULL) { Py_DECREF(m); return NULL; } Py_INCREF(o); if (PyModule_AddObject(m, "TclError", o)) { Py_DECREF(o); Py_DECREF(m); return NULL; } Tkinter_TclError = o; if (PyModule_AddIntConstant(m, "READABLE", TCL_READABLE)) { Py_DECREF(m); return NULL; } if (PyModule_AddIntConstant(m, "WRITABLE", TCL_WRITABLE)) { Py_DECREF(m); return NULL; } if (PyModule_AddIntConstant(m, "EXCEPTION", TCL_EXCEPTION)) { Py_DECREF(m); return NULL; } if (PyModule_AddIntConstant(m, "WINDOW_EVENTS", TCL_WINDOW_EVENTS)) { Py_DECREF(m); return NULL; } if (PyModule_AddIntConstant(m, "FILE_EVENTS", TCL_FILE_EVENTS)) { Py_DECREF(m); return NULL; } if (PyModule_AddIntConstant(m, "TIMER_EVENTS", TCL_TIMER_EVENTS)) { Py_DECREF(m); return NULL; } if (PyModule_AddIntConstant(m, "IDLE_EVENTS", TCL_IDLE_EVENTS)) { Py_DECREF(m); return NULL; } if (PyModule_AddIntConstant(m, "ALL_EVENTS", TCL_ALL_EVENTS)) { Py_DECREF(m); return NULL; } if (PyModule_AddIntConstant(m, "DONT_WAIT", TCL_DONT_WAIT)) { Py_DECREF(m); return NULL; } if (PyModule_AddStringConstant(m, "TK_VERSION", TK_VERSION)) { Py_DECREF(m); return NULL; } if (PyModule_AddStringConstant(m, "TCL_VERSION", TCL_VERSION)) { Py_DECREF(m); return NULL; } o = PyType_FromSpec(&Tkapp_Type_spec); if (o == NULL) { Py_DECREF(m); return NULL; } if (PyModule_AddObject(m, "TkappType", o)) { Py_DECREF(o); Py_DECREF(m); return NULL; } Tkapp_Type = o; o = PyType_FromSpec(&Tktt_Type_spec); if (o == NULL) { Py_DECREF(m); return NULL; } if (PyModule_AddObject(m, "TkttType", o)) { Py_DECREF(o); Py_DECREF(m); return NULL; } Tktt_Type = o; o = PyType_FromSpec(&PyTclObject_Type_spec); if (o == NULL) { Py_DECREF(m); return NULL; } if (PyModule_AddObject(m, "Tcl_Obj", o)) { Py_DECREF(o); Py_DECREF(m); return NULL; } PyTclObject_Type = o; #ifdef TK_AQUA /* Tk_MacOSXSetupTkNotifier must be called before Tcl's subsystems * start waking up. Note that Tcl_FindExecutable will do this, this * code must be above it! The original warning from * tkMacOSXAppInit.c is copied below. * * NB - You have to swap in the Tk Notifier BEFORE you start up the * Tcl interpreter for now. It probably should work to do this * in the other order, but for now it doesn't seem to. * */ Tk_MacOSXSetupTkNotifier(); #endif /* This helps the dynamic loader; in Unicode aware Tcl versions it also helps Tcl find its encodings. */ uexe = PyUnicode_FromWideChar(Py_GetProgramName(), -1); if (uexe) { cexe = PyUnicode_EncodeFSDefault(uexe); if (cexe) Tcl_FindExecutable(PyBytes_AsString(cexe)); Py_XDECREF(cexe); Py_DECREF(uexe); } if (PyErr_Occurred()) { Py_DECREF(m); return NULL; } #if 0 /* This was not a good idea; through bindings, Tcl_Finalize() may invoke Python code but at that point the interpreter and thread state have already been destroyed! */ Py_AtExit(Tcl_Finalize); #endif return m; } python3-stdlib-extensions-3.4.0/debian/0000755000000000000000000000000012313512422014701 5ustar python3-stdlib-extensions-3.4.0/debian/compat0000644000000000000000000000000210614062234016102 0ustar 5 python3-stdlib-extensions-3.4.0/debian/rules0000755000000000000000000001151012313512416015762 0ustar #!/usr/bin/make -f # -*- makefile -*- # Sample debian/rules that uses debhelper. # This file was originally written by Joey Hess and Craig Small. # As a special exception, when this file is copied by dh-make into a # dh-make output file, you may use that output file without restriction. # This special exception was added by Craig Small in version 0.37 of dh-make. # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 #rel_ext = $(strip $(shell dpkg-parsechangelog | awk -F- '/^Version:/ {print $$NF}')) PYVERS = $(shell py3versions -vs) PYVERS = 3.4 include /usr/share/dpkg/architecture.mk ifneq ($(DEB_BUILD_MULTIARCH),$(DEB_HOST_MULTIARCH)) SET_CROSS_ENV = PYTHONPATH=/usr/lib/python$*/plat-$(DEB_HOST_MULTIARCH) # FIXME: is this sufficient? SET_CROSS_ENV += _PYTHON_HOST_PLATFORM=$(DEB_HOST_GNU_CPU) endif p_tk = python3-tk p_gdbm = python3-gdbm d_tk = debian/$(p_tk) d_gdbm = debian/$(p_gdbm) build-arch: build build-indep: build build: build-stamp build-arch: build-stamp build-indep: build-stamp build-stamp: $(PYVERS:%=build-stamp-py%) $(PYVERS:%=dbg-stamp-py%) touch $@ build-stamp-py%: dh_testdir ln -sf /usr/lib/libBLT.2.4.so.8.5 $*/libBLT85.so ln -sf /usr/lib/libBLT.2.4.so.8.5 $*/libBLT85.so.8.5 cd $* && $(SET_CROSS_ENV) python$* setup.py build touch $@ dbg-stamp-py%: dh_testdir ln -sf /usr/lib/libBLT.2.4.so.8.5 $*/libBLT85.so ln -sf /usr/lib/libBLT.2.4.so.8.5 $*/libBLT85.so.8.5 cd $* && $(SET_CROSS_ENV) python$*-dbg setup.py build touch $@ clean: dh_testdir dh_testroot rm -f *stamp-* rm -rf 3.?/build rm -rf 3.?/libBLT* dh_clean install: build install-prereq $(PYVERS:%=install-stamp-py%) $(PYVERS:%=dbg-install-py%) rm -rf $(d_tk)/usr/share/pycentral rm -rf $(d_gdbm)/usr/share/pycentral install-prereq: dh_testdir dh_testroot dh_clean -k install-stamp-py%: build-stamp-py% cd $* && $(SET_CROSS_ENV) python$* setup.py install \ --root=$(CURDIR)/$(d_tk) --install-layout=deb mkdir -p $(d_tk)/usr/lib/python$*/lib-dynload ifeq (0,1) set -ex; \ for i in $(d_tk)/usr/lib/python3/*-packages/*.cpython-$(subst .,,$*)m.so; do \ b=$$(basename $$i .cpython-$(subst .,,$*)m.so); \ d=$${b}.cpython-$(subst .,,$*)m-$(DEB_HOST_MULTIARCH).so; \ mv $$i $(d_tk)/usr/lib/python$*/lib-dynload/$$d; \ done else mv $(d_tk)/usr/lib/python3/*-packages/*.so \ $(d_tk)/usr/lib/python$*/lib-dynload/ endif mkdir -p $(d_gdbm)/usr/lib/python$*/lib-dynload mv $(d_tk)/usr/lib/python$*/lib-dynload/_gdbm*.so \ $(d_gdbm)/usr/lib/python$*/lib-dynload/ rm -rf $(d_tk)/usr/lib/python3 dbg-install-py%: dbg-stamp-py% cd $* && $(SET_CROSS_ENV) python$*-dbg setup.py install \ --root=$(CURDIR)/$(d_tk)-dbg --install-layout=deb mkdir -p $(d_tk)-dbg/usr/lib/python$*/lib-dynload ifeq (0,1) set -ex; \ for i in $(d_tk)-dbg/usr/lib/python3/*-packages/*.cpython-$(subst .,,$*)dm.so; do \ b=$$(basename $$i .cpython-$(subst .,,$*)dm.so); \ d=$${b}.cpython-$(subst .,,$*)dm-$(DEB_HOST_MULTIARCH).so; \ mv $$i $(d_tk)-dbg/usr/lib/python$*/lib-dynload/$$d; \ done else mv $(d_tk)-dbg/usr/lib/python3/*-packages/*.so \ $(d_tk)-dbg/usr/lib/python$*/lib-dynload/ endif mkdir -p $(d_gdbm)-dbg/usr/lib/python$*/lib-dynload mv $(d_tk)-dbg/usr/lib/python$*/lib-dynload/_gdbm*.so \ $(d_gdbm)-dbg/usr/lib/python$*/lib-dynload/ rm -rf $(d_tk)-dbg/usr/lib/python3 # Build architecture-independent files here. binary-indep: build install # We have nothing to do by default. # Build architecture-dependent files here. binary-arch: build install dh_testdir dh_testroot dh_installchangelogs dh_installdocs -p$(p_gdbm) debian/README.Debian dh_installdocs -p$(p_tk) debian/README.Tk rm -rf $(d_gdbm)-dbg/usr/share/doc/$(p_gdbm)-dbg ln -s $(p_gdbm) $(d_gdbm)-dbg/usr/share/doc/$(p_gdbm)-dbg rm -rf $(d_tk)-dbg/usr/share/doc/$(p_tk)-dbg ln -s $(p_tk) $(d_tk)-dbg/usr/share/doc/$(p_tk)-dbg dh_strip -p$(p_gdbm) --dbg-package=$(p_gdbm)-dbg dh_strip -p$(p_tk) --dbg-package=$(p_tk)-dbg ifeq (0,1) ( \ echo 'python3:Depends=python3 (>= 3.3), python3 (<< 3.5)'; \ echo 'python3:Versions=3.3, 3.4'; \ echo 'python3:Provides=python3.3-gdbm, python3.4-gdbm'; \ ) >> debian/python3-gdbm.substvars ( \ echo 'python3:Depends=python3 (>= 3.3), python3 (<< 3.5)'; \ echo 'python3:Versions=3.3, 3.4'; \ echo 'python3:Provides=python3.3-tk, python3.4-tk'; \ ) >> debian/python3-tk.substvars else ( \ echo 'python3:Depends=python3 (>= 3.4), python3 (<< 3.5)'; \ echo 'python3:Versions=3.4'; \ echo 'python3:Provides=python3.4-gdbm'; \ ) >> debian/python3-gdbm.substvars ( \ echo 'python3:Depends=python3 (>= 3.4), python3 (<< 3.5)'; \ echo 'python3:Versions=3.4'; \ echo 'python3:Provides=python3.4-tk'; \ ) >> debian/python3-tk.substvars endif dh_compress dh_fixperms dh_installdeb dh_shlibdeps dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install python3-stdlib-extensions-3.4.0/debian/copyright0000644000000000000000000003325010614062234016642 0ustar This package was debianized by Matthias Klose on Wed, 7 Jun 2006 15:02:31 +0200. It was downloaded from http://python.org/, built by extracting the Tk and gdbm extensions from the upstream tarballs. Copyright: Upstream Author: Guido van Rossum and others. License: The following text includes the Python license and licenses and acknowledgements for incorporated software. The licenses can be read in the HTML and texinfo versions of the documentation as well, after installing the pythonx.y-doc package. Python License ============== A. HISTORY OF THE SOFTWARE ========================== Python was created in the early 1990s by Guido van Rossum at Stichting Mathematisch Centrum (CWI, see http://www.cwi.nl) in the Netherlands as a successor of a language called ABC. Guido remains Python's principal author, although it includes many contributions from others. In 1995, Guido continued his work on Python at the Corporation for National Research Initiatives (CNRI, see http://www.cnri.reston.va.us) in Reston, Virginia where he released several versions of the software. In May 2000, Guido and the Python core development team moved to BeOpen.com to form the BeOpen PythonLabs team. In October of the same year, the PythonLabs team moved to Digital Creations (now Zope Corporation, see http://www.zope.com). In 2001, the Python Software Foundation (PSF, see http://www.python.org/psf/) was formed, a non-profit organization created specifically to own Python-related Intellectual Property. Zope Corporation is a sponsoring member of the PSF. All Python releases are Open Source (see http://www.opensource.org for the Open Source Definition). Historically, most, but not all, Python releases have also been GPL-compatible; the table below summarizes the various releases. Release Derived Year Owner GPL- from compatible? (1) 0.9.0 thru 1.2 1991-1995 CWI yes 1.3 thru 1.5.2 1.2 1995-1999 CNRI yes 1.6 1.5.2 2000 CNRI no 2.0 1.6 2000 BeOpen.com no 1.6.1 1.6 2001 CNRI yes (2) 2.1 2.0+1.6.1 2001 PSF no 2.0.1 2.0+1.6.1 2001 PSF yes 2.1.1 2.1+2.0.1 2001 PSF yes 2.2 2.1.1 2001 PSF yes 2.1.2 2.1.1 2002 PSF yes 2.1.3 2.1.2 2002 PSF yes 2.2.1 2.2 2002 PSF yes 2.2.2 2.2.1 2002 PSF yes 2.2.3 2.2.2 2003 PSF yes 2.3 2.2.2 2002-2003 PSF yes 2.3.1 2.3 2002-2003 PSF yes 2.3.2 2.3.1 2002-2003 PSF yes 2.3.3 2.3.2 2002-2003 PSF yes 2.3.4 2.3.3 2004 PSF yes 2.4 2.3 2004 PSF yes 2.4.1 2.4.1 2005 PSF yes 2.4.2 2.4.1 2005 PSF yes 2.4.3 2.4.2 2006 PSF yes Footnotes: (1) GPL-compatible doesn't mean that we're distributing Python under the GPL. All Python licenses, unlike the GPL, let you distribute a modified version without making your changes open source. The GPL-compatible licenses make it possible to combine Python with other software that is released under the GPL; the others don't. (2) According to Richard Stallman, 1.6.1 is not GPL-compatible, because its license has a choice of law clause. According to CNRI, however, Stallman's lawyer has told CNRI's lawyer that 1.6.1 is "not incompatible" with the GPL. Thanks to the many outside volunteers who have worked under Guido's direction to make these releases possible. B. TERMS AND CONDITIONS FOR ACCESSING OR OTHERWISE USING PYTHON =============================================================== PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2 -------------------------------------------- 1. This LICENSE AGREEMENT is between the Python Software Foundation ("PSF"), and the Individual or Organization ("Licensee") accessing and otherwise using this software ("Python") in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, PSF hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python alone or in any derivative version, provided, however, that PSF's License Agreement and PSF's notice of copyright, i.e., "Copyright (c) 2001, 2002, 2003, 2004 Python Software Foundation; All Rights Reserved" are retained in Python alone or in any derivative version prepared by Licensee. 3. In the event Licensee prepares a derivative work that is based on or incorporates Python or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python. 4. PSF is making Python available to Licensee on an "AS IS" basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between PSF and Licensee. This License Agreement does not grant permission to use PSF trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By copying, installing or otherwise using Python, Licensee agrees to be bound by the terms and conditions of this License Agreement. BEOPEN.COM LICENSE AGREEMENT FOR PYTHON 2.0 ------------------------------------------- BEOPEN PYTHON OPEN SOURCE LICENSE AGREEMENT VERSION 1 1. This LICENSE AGREEMENT is between BeOpen.com ("BeOpen"), having an office at 160 Saratoga Avenue, Santa Clara, CA 95051, and the Individual or Organization ("Licensee") accessing and otherwise using this software in source or binary form and its associated documentation ("the Software"). 2. Subject to the terms and conditions of this BeOpen Python License Agreement, BeOpen hereby grants Licensee a non-exclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use the Software alone or in any derivative version, provided, however, that the BeOpen Python License is retained in the Software, alone or in any derivative version prepared by Licensee. 3. BeOpen is making the Software available to Licensee on an "AS IS" basis. BEOPEN MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, BEOPEN MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF THE SOFTWARE WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 4. BEOPEN SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 5. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 6. This License Agreement shall be governed by and interpreted in all respects by the law of the State of California, excluding conflict of law provisions. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between BeOpen and Licensee. This License Agreement does not grant permission to use BeOpen trademarks or trade names in a trademark sense to endorse or promote products or services of Licensee, or any third party. As an exception, the "BeOpen Python" logos available at http://www.pythonlabs.com/logos.html may be used according to the permissions granted on that web page. 7. By copying, installing or otherwise using the software, Licensee agrees to be bound by the terms and conditions of this License Agreement. CNRI LICENSE AGREEMENT FOR PYTHON 1.6.1 --------------------------------------- 1. This LICENSE AGREEMENT is between the Corporation for National Research Initiatives, having an office at 1895 Preston White Drive, Reston, VA 20191 ("CNRI"), and the Individual or Organization ("Licensee") accessing and otherwise using Python 1.6.1 software in source or binary form and its associated documentation. 2. Subject to the terms and conditions of this License Agreement, CNRI hereby grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce, analyze, test, perform and/or display publicly, prepare derivative works, distribute, and otherwise use Python 1.6.1 alone or in any derivative version, provided, however, that CNRI's License Agreement and CNRI's notice of copyright, i.e., "Copyright (c) 1995-2001 Corporation for National Research Initiatives; All Rights Reserved" are retained in Python 1.6.1 alone or in any derivative version prepared by Licensee. Alternately, in lieu of CNRI's License Agreement, Licensee may substitute the following text (omitting the quotes): "Python 1.6.1 is made available subject to the terms and conditions in CNRI's License Agreement. This Agreement together with Python 1.6.1 may be located on the Internet using the following unique, persistent identifier (known as a handle): 1895.22/1013. This Agreement may also be obtained from a proxy server on the Internet using the following URL: http://hdl.handle.net/1895.22/1013". 3. In the event Licensee prepares a derivative work that is based on or incorporates Python 1.6.1 or any part thereof, and wants to make the derivative work available to others as provided herein, then Licensee hereby agrees to include in any such work a brief summary of the changes made to Python 1.6.1. 4. CNRI is making Python 1.6.1 available to Licensee on an "AS IS" basis. CNRI MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, CNRI MAKES NO AND DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON 1.6.1 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. CNRI SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 1.6.1 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 1.6.1, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. 6. This License Agreement will automatically terminate upon a material breach of its terms and conditions. 7. This License Agreement shall be governed by the federal intellectual property law of the United States, including without limitation the federal copyright law, and, to the extent such U.S. federal law does not apply, by the law of the Commonwealth of Virginia, excluding Virginia's conflict of law provisions. Notwithstanding the foregoing, with regard to derivative works based on Python 1.6.1 that incorporate non-separable material that was previously distributed under the GNU General Public License (GPL), the law of the Commonwealth of Virginia shall govern this License Agreement only as to issues arising under or with respect to Paragraphs 4, 5, and 7 of this License Agreement. Nothing in this License Agreement shall be deemed to create any relationship of agency, partnership, or joint venture between CNRI and Licensee. This License Agreement does not grant permission to use CNRI trademarks or trade name in a trademark sense to endorse or promote products or services of Licensee, or any third party. 8. By clicking on the "ACCEPT" button where indicated, or by copying, installing or otherwise using Python 1.6.1, Licensee agrees to be bound by the terms and conditions of this License Agreement. ACCEPT CWI LICENSE AGREEMENT FOR PYTHON 0.9.0 THROUGH 1.2 -------------------------------------------------- Copyright (c) 1991 - 1995, Stichting Mathematisch Centrum Amsterdam, The Netherlands. All rights reserved. Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of Stichting Mathematisch Centrum or CWI not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. STICHTING MATHEMATISCH CENTRUM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH CENTRUM BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. python3-stdlib-extensions-3.4.0/debian/source.lintian-overrides0000644000000000000000000000017412124300332021556 0ustar # upstream package, split out from the python2.x sources python3-stdlib-extensions source: native-package-with-dash-version python3-stdlib-extensions-3.4.0/debian/README.Tk0000644000000000000000000000037210614062234016143 0ustar Tkinter documentation can be found at http://www.pythonware.com/library/index.htm more specific: http://www.pythonware.com/library/tkinter/introduction/index.htm http://www.pythonware.com/library/tkinter/an-introduction-to-tkinter.pdf python3-stdlib-extensions-3.4.0/debian/control0000644000000000000000000000403512276646635016334 0ustar Source: python3-stdlib-extensions Section: python Priority: optional Maintainer: Matthias Klose Build-Depends: debhelper (>= 5), libpython3-all-dev, libpython3-all-dbg, python3-all-dev:any, python3-all-dbg:any, libpython3.4-dev, libpython3.4-dbg, python3.4-dev:any, python3.4-dbg:any, tk-dev, blt-dev (>= 2.4z), libgdbm-dev Build-Conflicts: tcl8.0-dev, tk8.0-dev, tcl8.2-dev, tk8.2-dev, tcl8.3-dev, tk8.3-dev, tk8.4-dev Standards-Version: 3.9.5 Package: python3-tk Architecture: any Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} Provides: ${python3:Provides} Suggests: tix, python3-tk-dbg Description: Tkinter - Writing Tk applications with Python 3.x A module for writing portable GUI applications with Python 3.x using Tk. Also known as Tkinter. Package: python3-gdbm Architecture: any Multi-Arch: same Depends: ${python3:Depends}, ${shlibs:Depends}, ${misc:Depends} Provides: ${python3:Provides} Suggests: python3-gdbm-dbg Replaces: python3.0 (<< 3.0.1) Description: GNU dbm database support for Python 3.x GNU dbm database module for Python 3.x. Install this if you want to create or read GNU dbm database files with Python. Package: python3-tk-dbg Architecture: any Priority: extra Section: debug Depends: ${python3:Depends}, python3-tk (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: Tkinter - Writing Tk applications with Python 3.x (debug extension) A module for writing portable GUI applications with Python using Tk. Also known as Tkinter. . This package contains the extensions built for the python3 debug interpreter. Package: python3-gdbm-dbg Architecture: any Multi-Arch: same Priority: extra Section: debug Depends: ${python3:Depends}, python3-gdbm (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: GNU dbm database support for Python 3.x (debug extension) GNU dbm database module for Python 3.x. Install this if you want to create or read GNU dbm database files with Python. . This package contains the extensions built for the python3 debug interpreter. python3-stdlib-extensions-3.4.0/debian/README.Debian0000644000000000000000000000043010614062234016742 0ustar The documentation for this package is in /usr/share/doc/pythonX.Y, where X.Y is the Python version used. A draft of the "Debian Python Policy" can be found in /usr/share/doc/python Sometime it will be moved to /usr/share/doc/debian-policy in the debian-policy package. python3-stdlib-extensions-3.4.0/debian/changelog0000644000000000000000000001634512313512007016563 0ustar python3-stdlib-extensions (3.4.0-0ubuntu1) trusty; urgency=medium * Bump version to 3.4.0. * Stop building for 3.3. -- Matthias Klose Sun, 23 Mar 2014 08:57:18 +0100 python3-stdlib-extensions (3.3.4-1) unstable; urgency=medium * Bump version to 3.3.4. * Handle multiarch extension names. Closes: #735805. -- Matthias Klose Wed, 12 Feb 2014 11:29:15 +0100 python3-stdlib-extensions (3.3.3-2) unstable; urgency=medium * Build for python3.4. -- Matthias Klose Wed, 25 Dec 2013 22:41:17 +0100 python3-stdlib-extensions (3.3.3-1) unstable; urgency=low * Bump version to 3.3.3. * Make the packages Multi-Arch: same. Replace the dependency on python3 with libpython3-stdlib. * Allow the package to cross-build. -- Matthias Klose Wed, 27 Nov 2013 17:27:43 +0100 python3-stdlib-extensions (3.3.2-1) unstable; urgency=low * Bump version to 3.3.2. -- Matthias Klose Thu, 16 May 2013 01:17:07 +0200 python3-stdlib-extensions (3.3.1-1) unstable; urgency=low * Bump version to 3.3.1. * Allow the package to cross-build. -- Matthias Klose Sun, 07 Apr 2013 21:05:13 +0200 python3-stdlib-extensions (3.3.0-1) experimental; urgency=low * Python 3.3.0 release. -- Matthias Klose Tue, 09 Oct 2012 14:32:39 +0200 python3-stdlib-extensions (3.3.0~rc1-1) experimental; urgency=low * Python 3.3.0 release candidate 1. -- Matthias Klose Tue, 28 Aug 2012 10:10:02 +0200 python3-stdlib-extensions (3.3.0~a2-1) experimental; urgency=low * Python 3.3.0 alpha 2 release. -- Matthias Klose Mon, 09 Apr 2012 11:24:07 +0200 python3-stdlib-extensions (3.2.3-1) unstable; urgency=low * Python 3.2.3 release. - Remove uses of the C tolower()/toupper() which could break with a Turkish locale. - Improve _tkinter error message on unencodable character. * Bump standards version. * Remove Python 3.1 sources. -- Matthias Klose Wed, 21 Mar 2012 17:32:40 +0100 python3-stdlib-extensions (3.2-4) unstable; urgency=low * Fix FTBFS with multiarch locations. -- Matthias Klose Tue, 31 May 2011 17:29:08 +0200 python3-stdlib-extensions (3.2-2) unstable; urgency=low * Stop building for python3.1. -- Matthias Klose Tue, 19 Apr 2011 21:21:43 +0200 python3-stdlib-extensions (3.2-1) unstable; urgency=low * Python 3.2 release. -- Matthias Klose Mon, 21 Feb 2011 11:59:17 +0100 python3-stdlib-extensions (3.2~a3-1) experimental; urgency=low * Build for Python 3.2. -- Matthias Klose Tue, 12 Oct 2010 20:33:57 +0200 python3-stdlib-extensions (3.1.2-2) unstable; urgency=low * Fix build failure with changed site directory. -- Matthias Klose Tue, 28 Sep 2010 15:52:28 +0200 python3-stdlib-extensions (3.1.2-1) unstable; urgency=low * Python 3.1.2 release. -- Matthias Klose Sun, 21 Mar 2010 18:45:14 +0100 python3-stdlib-extensions (3.1.1-1) unstable; urgency=low * Bump to 3.1.1, update from the 3.1 branch 20100117. -- Matthias Klose Sun, 17 Jan 2010 14:17:04 +0100 python3-stdlib-extensions (3.1-1) experimental; urgency=low * Build extensions for 3.1. -- Matthias Klose Thu, 23 Jul 2009 17:25:34 +0200 python3-stdlib-extensions (3.0.1-0ubuntu3) jaunty; urgency=low * debian/rules (clean): Update for 3.x. -- Matthias Klose Tue, 17 Feb 2009 11:13:27 +0100 python3-stdlib-extensions (3.0.1-0ubuntu2) jaunty; urgency=low * Build for python3. -- Matthias Klose Mon, 16 Feb 2009 23:27:58 +0100 python-stdlib-extensions (2.5.4-0ubuntu2) jaunty; urgency=low * Fix build dependencies. -- Matthias Klose Mon, 16 Feb 2009 12:33:41 +0000 python-stdlib-extensions (2.5.4-0ubuntu1) jaunty; urgency=low * Build extensions for 2.6. -- Matthias Klose Mon, 16 Feb 2009 12:39:04 +0100 python-stdlib-extensions (2.5.2-1ubuntu1) intrepid; urgency=low * Fix build failure, linking with the correct BLT library. -- Matthias Klose Thu, 23 Oct 2008 20:55:54 +0000 python-stdlib-extensions (2.5.2-1) unstable; urgency=low * Bump the package version to 2.5.2. -- Matthias Klose Thu, 17 Apr 2008 21:27:50 +0000 python-stdlib-extensions (2.5.2-0ubuntu2) hardy; urgency=low * python-tk-dbg: Depend on python-tk, python-gdbm-dbg: Depend on python-gdbm. -- Matthias Klose Mon, 10 Mar 2008 18:00:36 +0000 python-stdlib-extensions (2.5.2-0ubuntu1) hardy; urgency=low * New upstream bugfix version. -- Matthias Klose Tue, 26 Feb 2008 11:27:59 +0000 python-stdlib-extensions (2.5.1-1ubuntu2) hardy; urgency=low * Build separate python-tk-dbg and python-gdbm-dbg packages. LP: #154020. -- Matthias Klose Thu, 03 Jan 2008 20:32:58 +0100 python-stdlib-extensions (2.5.1-1ubuntu1) gutsy; urgency=low * Bump the package version to 2.5.1 (no code change). -- Matthias Klose Thu, 26 Apr 2007 10:38:47 +0200 python-stdlib-extensions (2.5-0ubuntu1) feisty; urgency=low * Bump the package version to 2.5. * Set Ubuntu maintainer address. -- Matthias Klose Mon, 5 Mar 2007 19:30:55 +0100 python-stdlib-extensions (2.4.4-3) unstable; urgency=low * python-*-dbg: Add dependency to the python-* package. -- Matthias Klose Thu, 31 Jan 2008 01:00:21 +0100 python-stdlib-extensions (2.4.4-2) unstable; urgency=low * Build separate python-tk-dbg and python-gdbm-dbg packages. -- Matthias Klose Tue, 01 Jan 2008 20:41:45 +0100 python-stdlib-extensions (2.4.4-1) unstable; urgency=low * Update modules to the 2.4.4 and 2.5 releases. -- Matthias Klose Fri, 20 Oct 2006 00:33:37 +0200 python-stdlib-extensions (2.4.3-4) unstable; urgency=low * Update 2.5 extensions, taken from the 2.5c1 release. -- Matthias Klose Wed, 30 Aug 2006 16:42:16 +0000 python-stdlib-extensions (2-2) unstable; urgency=high * Remove the conflicts with the python2.x versions; now the python2.x packages conflict with python-tk (<< 2.3.4-2). Closes: #380597. -- Matthias Klose Mon, 31 Jul 2006 16:58:23 +0000 python-stdlib-extensions (2-1) unstable; urgency=low * Add 2.5 extensions, taken from the 2.5beta2 release. * Build the extensions for python2.5 as well. Closes: #380125. * Remove lib-tk from the package, moved to python2.x. -- Matthias Klose Sun, 30 Jul 2006 17:58:40 +0200 python-stdlib-extensions (1-1ubuntu1) edgy; urgency=low * Do build the extensions for the supported Python versions only. -- Matthias Klose Wed, 5 Jul 2006 04:49:33 +0000 python-stdlib-extensions (1-1) unstable; urgency=low * Build python-tk and python-gdbm from a separate source to include the extensions for all supported python versions into one binary package. * Initial release, split out from the python2.x packages. - 2.4 taken from the 2.4 branch (20060607). - 2.3 taken from the 2.3.5 release. -- Matthias Klose Wed, 7 Jun 2006 03:02:31 +0200