python-stdlib-extensions-2.7.12/0000775000000000000000000000000013205563663013501 5ustar python-stdlib-extensions-2.7.12/debian/0000775000000000000000000000000013205563663014723 5ustar python-stdlib-extensions-2.7.12/debian/copyright0000664000000000000000000003325010614062234016646 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. python-stdlib-extensions-2.7.12/debian/compat0000664000000000000000000000000213024737646016124 0ustar 9 python-stdlib-extensions-2.7.12/debian/control0000664000000000000000000000402513024737646016332 0ustar Source: python-stdlib-extensions Section: python Priority: optional Maintainer: Matthias Klose Build-Depends: debhelper (>= 9), python-all-dev (>= 2.7.11-1~), python-all-dbg, tk8.6-dev, blt-dev (>= 2.4z-9), libgdbm-dev Build-Conflicts: tcl8.4-dev, tk8.4-dev, tcl8.5-dev, tk8.5-dev XS-Python-Version: 2.7 Standards-Version: 3.9.8 Package: python-tk Architecture: any Depends: ${python:Depends}, blt (>= 2.4z-9), ${shlibs:Depends}, ${misc:Depends} Conflicts: python2.3-tk, python2.4-tk Replaces: python2.3-tk, python2.4-tk Provides: ${python:Provides} Suggests: tix, python-tk-dbg Description: Tkinter - Writing Tk applications with Python A module for writing portable GUI applications with Python using Tk. Also known as Tkinter. Package: python-gdbm Architecture: any Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends} Conflicts: python2.3-gdbm, python2.4-gdbm Replaces: python2.3-gdbm, python2.4-gdbm, python2.6 (<< 2.6.1-0ubuntu6) Provides: ${python:Provides} Suggests: python-gdbm-dbg Description: GNU dbm database support for Python GNU dbm database module for Python. Install this if you want to create or read GNU dbm database files with Python. Package: python-tk-dbg Architecture: any Section: debug Priority: extra Depends: ${python:Depends}, python-tk (= ${binary:Version}), blt (>= 2.4z-9), ${shlibs:Depends}, ${misc:Depends} Description: Tkinter - Writing Tk applications with Python (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 Python debug interpreter. Package: python-gdbm-dbg Architecture: any Section: debug Priority: extra Depends: ${python:Depends}, python-gdbm (= ${binary:Version}), ${shlibs:Depends}, ${misc:Depends} Description: GNU dbm database support for Python (debug extension) GNU dbm database module for Python. Install this if you want to create or read GNU dbm database files with Python. . This package contains the extensions built for the Python debug interpreter. python-stdlib-extensions-2.7.12/debian/python-gdbm.overrides0000664000000000000000000000013511261710044021061 0ustar # these belong to the standard library python-gdbm binary: third-party-package-in-python-dir python-stdlib-extensions-2.7.12/debian/python-tk-dbg.overrides0000664000000000000000000000013711261710055021324 0ustar # these belong to the standard library python-tk-dbg binary: third-party-package-in-python-dir python-stdlib-extensions-2.7.12/debian/README.Debian0000664000000000000000000000043010614062234016746 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. python-stdlib-extensions-2.7.12/debian/python-gdbm-dbg.overrides0000664000000000000000000000014111261710035021610 0ustar # these belong to the standard library python-gdbm-dbg binary: third-party-package-in-python-dir python-stdlib-extensions-2.7.12/debian/source.lintian-overrides0000664000000000000000000000017312123711452021571 0ustar # upstream package, split out from the python2.x sources python-stdlib-extensions source: native-package-with-dash-version python-stdlib-extensions-2.7.12/debian/README.Tk0000664000000000000000000000037210614062234016147 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 python-stdlib-extensions-2.7.12/debian/python-tk.overrides0000664000000000000000000000013311261710064020566 0ustar # these belong to the standard library python-tk binary: third-party-package-in-python-dir python-stdlib-extensions-2.7.12/debian/rules0000775000000000000000000001012512632017700015767 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}')) #pkgver = 2.4.3-$(shell expr $(rel_ext) + 0) #pkgver = 2.4.3-3ubuntu1 PYVERS = $(shell pyversions -vs) p_tk = python-tk p_gdbm = python-gdbm d_tk = debian/$(p_tk) d_gdbm = debian/$(p_gdbm) build-arch: build build-indep: build build: 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.6 $*/libBLT85.so ln -sf /usr/lib/libBLT.2.4.so.8.6 $*/libBLT85.so.8.6 cd $* && python$* setup.py build touch $@ dbg-stamp-py%: dh_testdir ln -sf /usr/lib/libBLT.2.4.so.8.6 $*/libBLT85.so ln -sf /usr/lib/libBLT.2.4.so.8.6 $*/libBLT85.so.8.6 cd $* && python$*-dbg setup.py build touch $@ clean: dh_testdir dh_testroot rm -f *stamp* rm -rf 2.?/build rm -rf 2.?/libBLT* dh_clean install: build install-prereq $(PYVERS:%=install-stamp-py%) $(PYVERS:%=dbg-install-py%) install-prereq: dh_testdir dh_testroot dh_prep install-stamp-py%: build-stamp-py% cd $* && python$* setup.py install \ --root=$(CURDIR)/$(d_tk) --install-layout=deb mkdir -p $(d_tk)/usr/lib/python$*/lib-dynload mv $(d_tk)/usr/lib/python$*/*-packages/_tkinter.so \ $(d_tk)/usr/lib/python$*/lib-dynload/ mkdir -p $(d_gdbm)/usr/lib/python$*/lib-dynload mv $(d_tk)/usr/lib/python$*/*-packages/gdbm.so \ $(d_gdbm)/usr/lib/python$*/lib-dynload/ rm -rf $(d_tk)/usr/lib/python$*/*-packages # cp -a $*/Lib/lib-tk $(d_tk)/usr/lib/python$*/ dbg-install-py%: dbg-stamp-py% cd $* && python$*-dbg setup.py install \ --root=$(CURDIR)/$(d_tk)-dbg --install-layout=deb mkdir -p $(d_tk)-dbg/usr/lib/python$*/lib-dynload mv $(d_tk)-dbg/usr/lib/python$*/*-packages/_tkinter_d.so \ $(d_tk)-dbg/usr/lib/python$*/lib-dynload/ mkdir -p $(d_gdbm)-dbg/usr/lib/python$*/lib-dynload mv $(d_tk)-dbg/usr/lib/python$*/*-packages/gdbm_d.so \ $(d_gdbm)-dbg/usr/lib/python$*/lib-dynload/ rm -rf $(d_tk)-dbg/usr/lib/python$*/*-packages # 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 for p in $(p_gdbm) $(p_gdbm)-dbg $(p_tk) $(p_tk)-dbg; do \ mkdir -p debian/$$p/usr/share/lintian/overrides; \ cp debian/$$p.overrides debian/$$p/usr/share/lintian/overrides/$$p; \ done 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 ( \ echo 'python:Depends=python (>= 2.7), python (<< 2.8)'; \ echo 'python:Provides=python2.7-gdbm'; \ echo 'python:Versions=2.7'; \ ) >> debian/$(p_gdbm).substvars ( \ echo 'python:Depends=python-dbg (>= 2.7), python-dbg (<< 2.8)'; \ echo 'python:Provides=python2.7-gdbm-dbg'; \ echo 'python:Versions=2.7'; \ ) >> debian/$(p_gdbm)-dbg.substvars ( \ echo 'python:Depends=python (>= 2.7), python (<< 2.8)'; \ echo 'python:Provides=python2.7-tk'; \ echo 'python:Versions=2.7'; \ ) >> debian/$(p_tk).substvars ( \ echo 'python:Depends=python-dbg (>= 2.7), python-dbg (<< 2.8)'; \ echo 'python:Provides=python2.7-tk-dbg'; \ echo 'python:Versions=2.7'; \ ) >> debian/$(p_tk)-dbg.substvars dh_compress dh_fixperms dh_installdeb dh_shlibdeps # dh_gencontrol -u-v$(pkgver) dh_gencontrol dh_md5sums dh_builddeb binary: binary-indep binary-arch .PHONY: build clean binary-indep binary-arch binary install python-stdlib-extensions-2.7.12/debian/changelog0000664000000000000000000001617213205534431016573 0ustar python-stdlib-extensions (2.7.12-1~16.04) xenial-proposed; urgency=medium * SRU: LP: #1591895. Backport 2.7.12 to 16.04 LTS. -- Matthias Klose Thu, 23 Nov 2017 13:02:55 +0100 python-stdlib-extensions (2.7.12-1) unstable; urgency=medium * Python 2.7.12 release. * Bump standards and debhelper versions. -- Matthias Klose Fri, 16 Dec 2016 11:19:18 +0100 python-stdlib-extensions (2.7.11-2) unstable; urgency=medium * Python 2.7.11 release. -- Matthias Klose Wed, 09 Dec 2015 13:30:24 +0100 python-stdlib-extensions (2.7.9-1) unstable; urgency=medium * Bump version to 2.7.9 (no changes). -- Matthias Klose Thu, 11 Dec 2014 09:41:00 +0100 python-stdlib-extensions (2.7.8-2) unstable; urgency=medium * Update from the 2.7 branch. -- Matthias Klose Fri, 03 Oct 2014 17:08:19 +0200 python-stdlib-extensions (2.7.8-1) unstable; urgency=medium * Bump version to 2.7.8. * Rebuild for blt 2.5. Closes: #753901. -- Matthias Klose Tue, 08 Jul 2014 10:58:36 +0200 python-stdlib-extensions (2.7.7-2) unstable; urgency=medium * Build for Tcl/Tk 8.6. -- Matthias Klose Fri, 13 Jun 2014 13:17:07 +0200 python-stdlib-extensions (2.7.7-1) unstable; urgency=medium * Bump version to 2.7.7. -- Matthias Klose Wed, 04 Jun 2014 10:18:23 +0200 python-stdlib-extensions (2.7.5-1) unstable; urgency=low * Bump version to 2.7.5. * Stop building for Python 2.6. -- Matthias Klose Wed, 15 May 2013 19:33:20 +0200 python-stdlib-extensions (2.7.3-1) unstable; urgency=low * Bump version to 2.7.3. - Remove uses of the C tolower()/toupper() which could break with a Turkish locale. * Set standards version to 3.9.3. -- Matthias Klose Wed, 21 Mar 2012 15:48:52 +0100 python-stdlib-extensions (2.7.1-3) unstable; urgency=low * Fix FTBFS with multiarch locations. -- Matthias Klose Wed, 04 May 2011 12:17:28 +0200 python-stdlib-extensions (2.7.1-2) unstable; urgency=low * Stop building for python2.5. -- Matthias Klose Tue, 19 Apr 2011 21:17:39 +0200 python-stdlib-extensions (2.7.1-1) unstable; urgency=low * Bump version to 2.7.1. -- Matthias Klose Tue, 15 Mar 2011 05:01:10 +0100 python-stdlib-extensions (2.7-2) experimental; urgency=low * Update extensions from the 2.6 and 2.7 branches. -- Matthias Klose Tue, 12 Oct 2010 21:14:04 +0200 python-stdlib-extensions (2.7-1) experimental; urgency=low * Bump version to 2.7. -- Matthias Klose Sun, 11 Jul 2010 11:34:55 +0200 python-stdlib-extensions (2.6.5-0ubuntu2) lucid; urgency=low * Fix build dependencies (remove 2.4). -- Matthias Klose Sat, 20 Mar 2010 06:12:32 +0100 python-stdlib-extensions (2.6.5-0ubuntu1) lucid; urgency=low * Bump version to 2.6.5. * Remove files for 2.4 and 2.5. -- Matthias Klose Sat, 20 Mar 2010 05:12:57 +0100 python-stdlib-extensions (2.6.4-0ubuntu1) karmic-proposed; urgency=low * Bump version to 2.6.4. LP: #464668. -- Matthias Klose Fri, 30 Oct 2009 13:06:25 +0100 python-stdlib-extensions (2.6.3-0ubuntu1) karmic; urgency=low * Bump version to 2.6.3. -- Matthias Klose Sat, 03 Oct 2009 19:48:52 +0200 python-stdlib-extensions (2.6.2-0ubuntu1) jaunty; urgency=low * Bump version to 2.6.2. -- Matthias Klose Sat, 18 Apr 2009 10:53:31 +0200 python-stdlib-extensions (2.6.1-0ubuntu2) jaunty; urgency=low * Update _tkinter.c to 2009-03-19, addresses issues #1581476, #1731706, #5193, #4792, apply fixes for 2.5 as well. -- Matthias Klose Thu, 19 Mar 2009 11:39:48 +0100 python-stdlib-extensions (2.6.1-0ubuntu1) jaunty; urgency=low * Bump version to 2.6.1. -- Matthias Klose Mon, 02 Mar 2009 14:46:01 +0100 python-stdlib-extensions (2.5.4-1) experimental; urgency=low * Build extensions for 2.6. -- Matthias Klose Sun, 01 Mar 2009 13:58:20 +0100 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 python-stdlib-extensions-2.7.12/2.7/0000775000000000000000000000000013205563663014007 5ustar python-stdlib-extensions-2.7.12/2.7/Modules/0000775000000000000000000000000011414662521015410 5ustar python-stdlib-extensions-2.7.12/2.7/Modules/gdbmmodule.c0000664000000000000000000003674712733576153017726 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(register 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, register 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_SetString(PyExc_KeyError, PyString_AS_STRING((PyStringObject *)key)); return NULL; } v = PyString_FromStringAndSize(drec.dptr, drec.dsize); free(drec.dptr); return v; } 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 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_SetString(PyExc_KeyError, PyString_AS_STRING((PyStringObject *)v)); return -1; } } else { if (!PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize)) { PyErr_SetString(PyExc_TypeError, "gdbm mappings have 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; } static int dbm_contains(register dbmobject *dp, PyObject *arg) { datum key; if ((dp)->di_dbm == NULL) { PyErr_SetString(DbmError, "GDBM object has already been closed"); return -1; } if (!PyString_Check(arg)) { PyErr_Format(PyExc_TypeError, "gdbm key must be string, not %.100s", arg->ob_type->tp_name); return -1; } key.dptr = PyString_AS_STRING(arg); key.dsize = PyString_GET_SIZE(arg); return gdbm_exists(dp->di_dbm, key); } static PySequenceMethods dbm_as_sequence = { (lenfunc)dbm_length, /*_length*/ 0, /*sq_concat*/ 0, /*sq_repeat*/ 0, /*sq_item*/ 0, /*sq_slice*/ 0, /*sq_ass_item*/ 0, /*sq_ass_slice*/ (objobjproc)dbm_contains, /*sq_contains*/ 0, /*sq_inplace_concat*/ 0 /*sq_inplace_repeat*/ }; 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(register dbmobject *dp, PyObject *unused) { if (dp->di_dbm) gdbm_close(dp->di_dbm); dp->di_dbm = NULL; Py_INCREF(Py_None); return Py_None; } PyDoc_STRVAR(dbm_keys__doc__, "keys() -> list_of_keys\n\ Get a list of all keys in the database."); static PyObject * dbm_keys(register dbmobject *dp, PyObject *unused) { register 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 = PyString_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; } PyDoc_STRVAR(dbm_has_key__doc__, "has_key(key) -> boolean\n\ Find out whether or not the database contains a given key."); static PyObject * dbm_has_key(register dbmobject *dp, PyObject *args) { datum key; if (!PyArg_ParseTuple(args, "s#:has_key", &key.dptr, &key.dsize)) return NULL; check_dbmobject_open(dp); return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key)); } 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(register dbmobject *dp, PyObject *unused) { register PyObject *v; datum key; check_dbmobject_open(dp); key = gdbm_firstkey(dp->di_dbm); if (key.dptr) { v = PyString_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(register dbmobject *dp, PyObject *args) { register 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 = PyString_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(register 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(register dbmobject *dp, PyObject *unused) { check_dbmobject_open(dp); gdbm_sync(dp->di_dbm); Py_INCREF(Py_None); return Py_None; } static PyMethodDef dbm_methods[] = { {"close", (PyCFunction)dbm_close, METH_NOARGS, dbm_close__doc__}, {"keys", (PyCFunction)dbm_keys, METH_NOARGS, dbm_keys__doc__}, {"has_key", (PyCFunction)dbm_has_key, METH_VARARGS, dbm_has_key__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__}, {NULL, NULL} /* sentinel */ }; static PyObject * dbm_getattr(dbmobject *dp, char *name) { return Py_FindMethod(dbm_methods, (PyObject *)dp, name); } static PyTypeObject Dbmtype = { PyVarObject_HEAD_INIT(0, 0) "gdbm.gdbm", sizeof(dbmobject), 0, (destructor)dbm_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ (getattrfunc)dbm_getattr, /*tp_getattr*/ 0, /*tp_setattr*/ 0, /*tp_compare*/ 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*/ }; /* ----------------------------------------------------------------- */ 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 }, }; PyMODINIT_FUNC initgdbm(void) { PyObject *m, *d, *s; Dbmtype.ob_type = &PyType_Type; m = Py_InitModule4("gdbm", dbmmodule_methods, gdbmmodule__doc__, (PyObject *)NULL, PYTHON_API_VERSION); if (m == NULL) return; d = PyModule_GetDict(m); DbmError = PyErr_NewException("gdbm.error", NULL, NULL); if (DbmError != NULL) { PyDict_SetItemString(d, "error", DbmError); s = PyString_FromString(dbmmodule_open_flags); PyDict_SetItemString(d, "open_flags", s); Py_DECREF(s); } } python-stdlib-extensions-2.7.12/2.7/Modules/Setup0000664000000000000000000004355111350733562016446 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= # Path component for the Tkinter-related modules # The TKPATH variable is always enabled, to save you the effort. TKPATH=:lib-tk # Path component for old modules. OLDPATH=:lib-old COREPYTHONPATH=$(DESTPATH)$(SITEPATH)$(TESTPATH)$(MACHDEPPATH)$(EXTRAMACHDEPPATH)$(TKPATH)$(OLDPATH) 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 # 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 # The SGI specific GL module: GLHACK=-Dclear=__GLclear #gl glmodule.c cgensupport.c -I$(srcdir) $(GLHACK) -lgl -lX11 # Pure module. Cannot be linked dynamically. # -DWITH_QUANTIFY, -DWITH_PURIFY, or -DWITH_ALL_PURE #WHICH_PURE_PRODUCTS=-DWITH_ALL_PURE #PURE_INCLS=-I/usr/local/include #PURE_STUBLIBS=-L/usr/local/lib -lpurify_stubs -lquantify_stubs #pure puremodule.c $(WHICH_PURE_PRODUCTS) $(PURE_INCLS) $(PURE_STUBLIBS) # 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 #strop stropmodule.c # String manipulations #_functools _functoolsmodule.c # Tools for working with functions and callable objects #_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 #unicodedata unicodedata.c # static Unicode character database # access to ISO C locale support #_locale _localemodule.c # -lintl # 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 # 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 #imageop imageop.c # Operations on images # 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 # SGI IRIX specific modules -- off by default. # These module work on any SGI machine: # *** gl must be enabled higher up in this file *** #fm fmmodule.c $(GLHACK) -lfm -lgl # Font Manager #sgi sgimodule.c # sgi.nap() and a few more # This module requires the header file # /usr/people/4Dgifts/iristools/include/izoom.h: #imgfile imgfile.c -limage -lgutil -lgl -lm # Image Processing Utilities # These modules require the Multimedia Development Option (I think): #al almodule.c -laudio # Audio Library #cd cdmodule.c -lcdaudio -lds -lmediad # CD Audio Library #cl clmodule.c -lcl -lawareaudio # Compression Library #sv svmodule.c yuvconvert.c -lsvideo -lXext -lX11 # Starter Video # The FORMS library, by Mark Overmars, implements user interface # components such as dialogs and buttons using SGI's GL and FM # libraries. You must ftp the FORMS library separately from # ftp://ftp.cs.ruu.nl/pub/SGI/FORMS. It was tested with FORMS 2.2a. # NOTE: if you want to be able to use FORMS and curses simultaneously # (or both link them statically into the same binary), you must # compile all of FORMS with the cc option "-Dclear=__GLclear". # The FORMS variable must point to the FORMS subdirectory of the forms # toplevel directory: #FORMS=/ufs/guido/src/forms/FORMS #fl flmodule.c -I$(FORMS) $(GLHACK) $(FORMS)/libforms.a -lfm -lgl # SunOS specific modules -- off by default: #sunaudiodev sunaudiodev.c # A Linux specific module -- off by default; this may also work on # some *BSDs. #linuxaudiodev linuxaudiodev.c # George Neville-Neil's timing module: #timing timingmodule.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 # Generic (SunOS / SVR4) dynamic loading module. # This is not needed for dynamic loading of Python modules -- # it is a highly experimental and dangerous device for calling # *arbitrary* C functions in *arbitrary* shared libraries: #dl dlmodule.c # 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 anydbm.py provides an # implementation independent wrapper for these; dumbdbm.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 # Sleepycat Berkeley DB interface. # # This requires the Sleepycat DB code, see http://www.sleepycat.com/ # The earliest supported version of that library is 3.0, the latest # supported version is 4.0 (4.1 is specifically not supported, as that # changes the semantics of transactional databases). A list of available # releases can be found at # # http://www.sleepycat.com/update/index.html # # Edit the variables DB and DBLIBVERto point to the db top directory # and the subdirectory of PORT where you built it. #DB=/usr/local/BerkeleyDB.4.0 #DBLIBVER=4.0 #DBINC=$(DB)/include #DBLIB=$(DB)/lib #_bsddb _bsddb.c -I$(DBINC) -L$(DBLIB) -ldb-$(DBLIBVER) # Historical Berkeley DB 1.85 # # This module is deprecated; the 1.85 version of the Berkeley DB library has # bugs that can cause data corruption. If you can, use later versions of the # library instead, available from . #DB=/depot/sundry/src/berkeley-db/db.1.85 #DBPORT=$(DB)/PORT/irix.5.3 #bsddb185 bsddbmodule.c -I$(DBPORT)/include -I$(DBPORT) $(DBPORT)/libdb.a # Helper module for various ascii-encoders #binascii binascii.c # Fred Drake's interface to the Python parser #parser parsermodule.c # cStringIO and cPickle #cStringIO cStringIO.c #cPickle cPickle.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 python-stdlib-extensions-2.7.12/2.7/Modules/Setup.local0000664000000000000000000000005111414662155017523 0ustar # Edit this file for local setup changes python-stdlib-extensions-2.7.12/2.7/Modules/tkinter.h0000664000000000000000000000231412733576154017254 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_HEX_VERSION 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_HEX_VERSION ((TK_MAJOR_VERSION << 24) | \ (TK_MINOR_VERSION << 16) | \ (TK_RELEASE_LEVEL << 8) | \ (TK_RELEASE_SERIAL << 0)) /* TK_VERSION_HEX packs fields in wrong order, not suitable for comparing of * non-final releases. Left for backward compatibility. */ #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_HEX_VERSION < 0x0804020e #define TKINTER_PROTECT_LOADTK #define TKINTER_LOADTK_ERRMSG \ "Calling Tk_Init again after a previous call failed might deadlock" #endif #endif /* !TKINTER_H */ python-stdlib-extensions-2.7.12/2.7/Modules/tkappinit.c0000664000000000000000000001216312733576154017575 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) { Tk_Window main_window; 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; } main_window = Tk_MainWindow(interp); #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; } python-stdlib-extensions-2.7.12/2.7/Modules/_tkinter.c0000664000000000000000000030117112733576153017410 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 /* Allow using this code in Python 2.[12] */ #ifndef PyDoc_STRVAR #define PyDoc_STRVAR(name,str) static char name[] = str #endif #ifndef PyMODINIT_FUNC #define PyMODINIT_FUNC void #endif #ifndef PyBool_Check #define PyBool_Check(o) 0 #define PyBool_FromLong PyInt_FromLong #endif #define CHECK_SIZE(size, elemsize) \ ((size_t)(size) <= (size_t)INT_MAX && \ (size_t)(size) <= 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_HEX_VERSION < 0x08030201 #error "Tk older than 8.3.1 not supported" #endif /* Unicode conversion assumes that Tcl_UniChar is two bytes. We cannot test this directly, so we test UTF-8 size instead, expecting that TCL_UTF_MAX is changed if Tcl ever supports either UTF-16 or UCS-4. Redhat 8 sets TCL_UTF_MAX to 6, and uses wchar_t for Tcl_Unichar. This is also ok as long as Python uses UCS-4, as well. */ #if TCL_UTF_MAX != 3 && !(defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==6) #error "unsupported Tcl configuration" #endif #if TK_HEX_VERSION >= 0x08050208 && TK_HEX_VERSION < 0x08060000 || \ TK_HEX_VERSION >= 0x08060200 #define HAVE_LIBTOMMAMTH #include #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 PyTypeObject 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. */ const Tcl_ObjType *OldBooleanType; const Tcl_ObjType *BooleanType; const Tcl_ObjType *ByteArrayType; const Tcl_ObjType *DoubleType; const Tcl_ObjType *IntType; const Tcl_ObjType *WideIntType; const Tcl_ObjType *BignumType; const Tcl_ObjType *ListType; const Tcl_ObjType *ProcBodyType; const Tcl_ObjType *StringType; } TkappObject; #define Tkapp_Check(v) (Py_TYPE(v) == &Tkapp_Type) #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; #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 */ static char * AsString(PyObject *value, PyObject *tmp) { if (PyString_Check(value)) return PyString_AsString(value); #ifdef Py_USING_UNICODE else if (PyUnicode_Check(value)) { PyObject *v = PyUnicode_AsUTF8String(value); if (v == NULL) return NULL; if (PyList_Append(tmp, v) != 0) { Py_DECREF(v); return NULL; } Py_DECREF(v); return PyString_AsString(v); } #endif else { PyObject *v = PyObject_Str(value); if (v == NULL) return NULL; if (PyList_Append(tmp, v) != 0) { Py_DECREF(v); return NULL; } Py_DECREF(v); return PyString_AsString(v); } } #define ARGSZ 64 static char * Merge(PyObject *args) { PyObject *tmp = NULL; char *argvStore[ARGSZ]; char **argv = NULL; int fvStore[ARGSZ]; int *fv = NULL; Py_ssize_t argc = 0, fvc = 0, i; char *res = NULL; if (!(tmp = PyList_New(0))) return NULL; argv = argvStore; fv = fvStore; if (args == NULL) argc = 0; else if (!PyTuple_Check(args)) { argc = 1; fv[0] = 0; if (!(argv[0] = AsString(args, tmp))) goto finally; } else { argc = PyTuple_Size(args); if (argc > ARGSZ) { if (!CHECK_SIZE(argc, sizeof(char *))) { PyErr_SetString(PyExc_OverflowError, "tuple is too long"); goto finally; } argv = (char **)attemptckalloc((size_t)argc * sizeof(char *)); fv = (int *)attemptckalloc((size_t)argc * sizeof(int)); if (argv == NULL || fv == NULL) { PyErr_NoMemory(); goto finally; } } for (i = 0; i < argc; i++) { PyObject *v = PyTuple_GetItem(args, i); if (PyTuple_Check(v)) { fv[i] = 1; if (!(argv[i] = Merge(v))) goto finally; fvc++; } else if (v == Py_None) { argc = i; break; } else { fv[i] = 0; if (!(argv[i] = AsString(v, tmp))) goto finally; fvc++; } } } res = Tcl_Merge(argc, argv); if (res == NULL) PyErr_SetString(Tkinter_TclError, "merge failed"); finally: for (i = 0; i < fvc; i++) if (fv[i]) { ckfree(argv[i]); } if (argv != argvStore) ckfree(FREECAST argv); if (fv != fvStore) ckfree(FREECAST fv); Py_DECREF(tmp); return res; } #ifdef Py_USING_UNICODE static PyObject * unicode_FromTclStringAndSize(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) { PyErr_NoMemory(); 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; } #endif static PyObject * fromTclStringAndSize(const char *s, Py_ssize_t size) { PyObject *r; #ifdef Py_USING_UNICODE Py_ssize_t i; /* If Tcl string contains any bytes with the top bit set, it's UTF-8 and we should decode it to Unicode */ for (i = 0; i < size; i++) if (s[i] & 0x80) break; if (i != size) { /* It isn't an ASCII string. */ r = unicode_FromTclStringAndSize(s, size); if (r) return r; PyErr_Clear(); } #endif r = PyString_FromStringAndSize(s, size); return r; } static PyObject * fromTclString(const char *s) { return fromTclStringAndSize(s, strlen(s)); } static PyObject * Split(char *list) { int argc; char **argv; PyObject *v; if (list == NULL) { Py_INCREF(Py_None); return Py_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 PyString_FromString(list); } if (argc == 0) v = PyString_FromString(""); else if (argc == 1) v = PyString_FromString(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 (PyString_Check(arg)) { int argc; char **argv; char *list = PyString_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(PyString_AsString(arg)); /* Fall through, returning arg. */ } else if (PyUnicode_Check(arg)) { int argc; char **argv; char *list; PyObject *s = PyUnicode_AsUTF8String(arg); if (s == NULL) { Py_INCREF(arg); return arg; } list = PyString_AsString(s); if (list == NULL || Tcl_SplitList((Tcl_Interp *)NULL, list, &argc, &argv) != TCL_OK) { Py_DECREF(s); Py_INCREF(arg); return arg; } Tcl_Free(FREECAST argv); if (argc > 1) { PyObject *v = Split(list); Py_DECREF(s); return v; } Py_DECREF(s); /* 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 *baseName, char *className, int interactive, int wantobjects, int wantTk, int sync, char *use) { TkappObject *v; char *argv0; v = PyObject_New(TkappObject, &Tkapp_Type); if (v == NULL) return NULL; 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->OldBooleanType = Tcl_GetObjType("boolean"); v->BooleanType = Tcl_GetObjType("booleanString"); v->ByteArrayType = Tcl_GetObjType("bytearray"); v->DoubleType = Tcl_GetObjType("double"); v->IntType = Tcl_GetObjType("int"); v->WideIntType = Tcl_GetObjType("wideInt"); v->BignumType = Tcl_GetObjType("bignum"); 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*)attemptckalloc(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*)attemptckalloc(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; staticforward PyTypeObject PyTclObject_Type; #define PyTclObject_Check(v) ((v)->ob_type == &PyTclObject_Type) static PyObject * newPyTclObject(Tcl_Obj *arg) { PyTclObject *self; self = PyObject_New(PyTclObject, &PyTclObject_Type); if (self == NULL) return NULL; Tcl_IncrRefCount(arg); self->value = arg; self->string = NULL; return (PyObject*)self; } static void PyTclObject_dealloc(PyTclObject *self) { Tcl_DecrRefCount(self->value); Py_XDECREF(self->string); PyObject_Del(self); } static PyObject * PyTclObject_str(PyTclObject *self) { if (self->string && PyString_Check(self->string)) { Py_INCREF(self->string); return self->string; } /* XXX Could cache value if it is an ASCII string. */ return PyString_FromString(Tcl_GetString(self->value)); } 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 string or Unicode"); static PyObject * PyTclObject_string(PyTclObject *self, void *ignored) { if (!self->string) { int len; char *s = Tcl_GetStringFromObj(self->value, &len); self->string = fromTclStringAndSize(s, len); if (!self->string) return NULL; } Py_INCREF(self->string); return self->string; } #ifdef Py_USING_UNICODE PyDoc_STRVAR(PyTclObject_unicode__doc__, "convert argument to unicode"); static PyObject * PyTclObject_unicode(PyTclObject *self, void *ignored) { char *s; int len; if (self->string && PyUnicode_Check(self->string)) { Py_INCREF(self->string); return self->string; } /* XXX Could chache result if it is non-ASCII. */ s = Tcl_GetStringFromObj(self->value, &len); return unicode_FromTclStringAndSize(s, len); } #endif static PyObject * PyTclObject_repr(PyTclObject *self) { char buf[50]; PyOS_snprintf(buf, 50, "<%s object at %p>", self->value->typePtr->name, self->value); return PyString_FromString(buf); } static int PyTclObject_cmp(PyTclObject *self, PyTclObject *other) { int res; res = strcmp(Tcl_GetString(self->value), Tcl_GetString(other->value)); if (res < 0) return -1; if (res > 0) return 1; return 0; } PyDoc_STRVAR(get_typename__doc__, "name of the Tcl type"); static PyObject* get_typename(PyTclObject* obj, void* ignored) { return PyString_FromString(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 PyMethodDef PyTclObject_methods[] = { #ifdef Py_USING_UNICODE {"__unicode__", (PyCFunction)PyTclObject_unicode, METH_NOARGS, PyTclObject_unicode__doc__}, #endif {0} }; statichere PyTypeObject PyTclObject_Type = { PyObject_HEAD_INIT(NULL) 0, /*ob_size*/ "_tkinter.Tcl_Obj", /*tp_name*/ sizeof(PyTclObject), /*tp_basicsize*/ 0, /*tp_itemsize*/ /* methods */ (destructor)PyTclObject_dealloc, /*tp_dealloc*/ 0, /*tp_print*/ 0, /*tp_getattr*/ 0, /*tp_setattr*/ (cmpfunc)PyTclObject_cmp, /*tp_compare*/ (reprfunc)PyTclObject_repr, /*tp_repr*/ 0, /*tp_as_number*/ 0, /*tp_as_sequence*/ 0, /*tp_as_mapping*/ 0, /*tp_hash*/ 0, /*tp_call*/ (reprfunc)PyTclObject_str, /*tp_str*/ PyObject_GenericGetAttr,/*tp_getattro*/ 0, /*tp_setattro*/ 0, /*tp_as_buffer*/ Py_TPFLAGS_DEFAULT, /*tp_flags*/ 0, /*tp_doc*/ 0, /*tp_traverse*/ 0, /*tp_clear*/ 0, /*tp_richcompare*/ 0, /*tp_weaklistoffset*/ 0, /*tp_iter*/ 0, /*tp_iternext*/ PyTclObject_methods, /*tp_methods*/ 0, /*tp_members*/ PyTclObject_getsetlist, /*tp_getset*/ 0, /*tp_base*/ 0, /*tp_dict*/ 0, /*tp_descr_get*/ 0, /*tp_descr_set*/ 0, /*tp_dictoffset*/ 0, /*tp_init*/ 0, /*tp_alloc*/ 0, /*tp_new*/ 0, /*tp_free*/ 0, /*tp_is_gc*/ }; #if PY_SIZE_MAX > INT_MAX #define CHECK_STRING_LENGTH(s) do { \ if (s != NULL && strlen(s) >= INT_MAX) { \ PyErr_SetString(PyExc_OverflowError, "string is too long"); \ return NULL; \ } } while(0) #else #define CHECK_STRING_LENGTH(s) #endif #ifdef HAVE_LIBTOMMAMTH static Tcl_Obj* asBignumObj(PyObject *value) { Tcl_Obj *result; int neg; PyObject *hexstr; char *hexchars; mp_int bigValue; neg = Py_SIZE(value) < 0; hexstr = _PyLong_Format(value, 16, 0, 1); if (hexstr == NULL) return NULL; hexchars = PyString_AsString(hexstr); if (hexchars == NULL) { Py_DECREF(hexstr); return NULL; } hexchars += neg + 2; /* skip sign and "0x" */ mp_init(&bigValue); if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) { mp_clear(&bigValue); Py_DECREF(hexstr); PyErr_NoMemory(); return NULL; } Py_DECREF(hexstr); bigValue.sign = neg ? MP_NEG : MP_ZPOS; result = Tcl_NewBignumObj(&bigValue); mp_clear(&bigValue); if (result == NULL) { PyErr_NoMemory(); return NULL; } return result; } #endif static Tcl_Obj* AsObj(PyObject *value) { Tcl_Obj *result; if (PyString_Check(value)) return Tcl_NewStringObj(PyString_AS_STRING(value), PyString_GET_SIZE(value)); if (PyBool_Check(value)) return Tcl_NewBooleanObj(PyObject_IsTrue(value)); if (PyInt_Check(value)) return Tcl_NewLongObj(PyInt_AS_LONG(value)); if (PyLong_CheckExact(value)) { int overflow; long longValue; #ifdef TCL_WIDE_INT_TYPE Tcl_WideInt wideValue; #endif longValue = PyLong_AsLongAndOverflow(value, &overflow); if (!overflow) { return Tcl_NewLongObj(longValue); } /* If there is an overflow in the long conversion, fall through to wideInt handling. */ #ifdef TCL_WIDE_INT_TYPE if (_PyLong_AsByteArray((PyLongObject *)value, (unsigned char *)(void *)&wideValue, sizeof(wideValue), #ifdef WORDS_BIGENDIAN 0, #else 1, #endif /* signed */ 1) == 0) { return Tcl_NewWideIntObj(wideValue); } PyErr_Clear(); #endif /* If there is an overflow in the wideInt conversion, fall through to bignum handling. */ #ifdef HAVE_LIBTOMMAMTH return asBignumObj(value); #endif /* If there is no wideInt or bignum support, fall through to default object handling. */ } if (PyFloat_Check(value)) return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); if (PyTuple_Check(value)) { Tcl_Obj **argv; Py_ssize_t size, i; size = PyTuple_Size(value); if (size == 0) return Tcl_NewListObj(0, NULL); if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) { PyErr_SetString(PyExc_OverflowError, "tuple is too long"); return NULL; } argv = (Tcl_Obj **) attemptckalloc(((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; } #ifdef Py_USING_UNICODE if (PyUnicode_Check(value)) { Py_UNICODE *inbuf = PyUnicode_AS_UNICODE(value); Py_ssize_t size = PyUnicode_GET_SIZE(value); /* This #ifdef assumes that Tcl uses UCS-2. See TCL_UTF_MAX test above. */ #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX == 3 Tcl_UniChar *outbuf = NULL; Py_ssize_t i; size_t allocsize; if (size == 0) return Tcl_NewUnicodeObj((const void *)"", 0); if (!CHECK_SIZE(size, sizeof(Tcl_UniChar))) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return NULL; } if (sizeof(Py_UNICODE) == sizeof(Tcl_UniChar)) return Tcl_NewUnicodeObj(inbuf, size); allocsize = ((size_t)size) * sizeof(Tcl_UniChar); if (allocsize >= size) outbuf = (Tcl_UniChar*)attemptckalloc(allocsize); /* Else overflow occurred, and we take the next exit */ if (!outbuf) { PyErr_NoMemory(); return NULL; } for (i = 0; i < size; i++) { if (inbuf[i] >= 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", (int)inbuf[i]); ckfree(FREECAST outbuf); return NULL; } outbuf[i] = inbuf[i]; } result = Tcl_NewUnicodeObj(outbuf, size); ckfree(FREECAST outbuf); return result; #else return Tcl_NewUnicodeObj(inbuf, size); #endif } #endif if(PyTclObject_Check(value)) { Tcl_Obj *v = ((PyTclObject*)value)->value; Tcl_IncrRefCount(v); return v; } { PyObject *v = PyObject_Str(value); if (!v) return 0; result = AsObj(v); Py_DECREF(v); return result; } } static PyObject * fromBoolean(PyObject* tkapp, Tcl_Obj *value) { int boolValue; if (Tcl_GetBooleanFromObj(Tkapp_Interp(tkapp), value, &boolValue) == TCL_ERROR) return Tkinter_Error(tkapp); return PyBool_FromLong(boolValue); } #ifdef TCL_WIDE_INT_TYPE static PyObject* fromWideIntObj(PyObject* tkapp, Tcl_Obj *value) { Tcl_WideInt wideValue; if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL_OK) { #ifdef HAVE_LONG_LONG if (sizeof(wideValue) <= SIZEOF_LONG_LONG) return PyLong_FromLongLong(wideValue); #endif return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue, sizeof(wideValue), #ifdef WORDS_BIGENDIAN 0, #else 1, #endif /* signed */ 1); } return NULL; } #endif #ifdef HAVE_LIBTOMMAMTH static PyObject* fromBignumObj(PyObject* tkapp, Tcl_Obj *value) { mp_int bigValue; unsigned long numBytes; unsigned char *bytes; PyObject *res; if (Tcl_GetBignumFromObj(Tkapp_Interp(tkapp), value, &bigValue) != TCL_OK) return Tkinter_Error(tkapp); numBytes = mp_unsigned_bin_size(&bigValue); bytes = PyMem_Malloc(numBytes); if (bytes == NULL) { mp_clear(&bigValue); return PyErr_NoMemory(); } if (mp_to_unsigned_bin_n(&bigValue, bytes, &numBytes) != MP_OKAY) { mp_clear(&bigValue); PyMem_Free(bytes); return PyErr_NoMemory(); } res = _PyLong_FromByteArray(bytes, numBytes, /* big-endian */ 0, /* unsigned */ 0); PyMem_Free(bytes); if (res != NULL && bigValue.sign == MP_NEG) { PyObject *res2 = PyNumber_Negative(res); Py_DECREF(res); res = res2; } mp_clear(&bigValue); return res; } #endif static PyObject* FromObj(PyObject* tkapp, Tcl_Obj *value) { PyObject *result = NULL; TkappObject *app = (TkappObject*)tkapp; Tcl_Interp *interp = Tkapp_Interp(tkapp); if (value->typePtr == NULL) { result = fromTclStringAndSize(value->bytes, value->length); return result; } if (value->typePtr == app->BooleanType || value->typePtr == app->OldBooleanType) { return fromBoolean(tkapp, value); } if (value->typePtr == app->ByteArrayType) { int size; char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); return PyString_FromStringAndSize(data, size); } if (value->typePtr == app->DoubleType) { return PyFloat_FromDouble(value->internalRep.doubleValue); } if (value->typePtr == app->IntType) { long longValue; if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK) return PyInt_FromLong(longValue); /* If there is an error in the long conversion, fall through to wideInt handling. */ } #ifdef TCL_WIDE_INT_TYPE if (value->typePtr == app->IntType || value->typePtr == app->WideIntType) { result = fromWideIntObj(tkapp, value); if (result != NULL || PyErr_Occurred()) return result; Tcl_ResetResult(interp); /* If there is an error in the wideInt conversion, fall through to bignum handling. */ } #endif #ifdef HAVE_LIBTOMMAMTH if (value->typePtr == app->IntType || value->typePtr == app->WideIntType || value->typePtr == app->BignumType) { return fromBignumObj(tkapp, value); } #endif if (value->typePtr == app->ListType) { int size; int i, status; PyObject *elem; Tcl_Obj *tcl_elem; status = Tcl_ListObjLength(interp, 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(interp, 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) { #ifdef Py_USING_UNICODE #if defined(Py_UNICODE_WIDE) && TCL_UTF_MAX==3 PyObject *result; int size; Tcl_UniChar *input; Py_UNICODE *output; size = Tcl_GetCharLength(value); result = PyUnicode_FromUnicode(NULL, size); if (!result) return NULL; input = Tcl_GetUnicode(value); output = PyUnicode_AS_UNICODE(result); while (size--) *output++ = *input++; return result; #else return PyUnicode_FromUnicode(Tcl_GetUnicode(value), Tcl_GetCharLength(value)); #endif #else int size; char *c; c = Tcl_GetStringFromObj(value, &size); return PyString_FromStringAndSize(c, size); #endif } #if TK_HEX_VERSION >= 0x08050000 if (app->BooleanType == NULL && strcmp(value->typePtr->name, "booleanString") == 0) { /* booleanString type is not registered in Tcl */ app->BooleanType = value->typePtr; return fromBoolean(tkapp, value); } #endif #ifdef HAVE_LIBTOMMAMTH if (app->BignumType == NULL && strcmp(value->typePtr->name, "bignum") == 0) { /* bignum type is not registered in Tcl */ app->BignumType = value->typePtr; return fromBignumObj(tkapp, value); } #endif 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 **)attemptckalloc(((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 { int len; const char *s = Tcl_GetStringFromObj(value, &len); res = fromTclStringAndSize(s, len); } 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*)attemptckalloc(sizeof(Tkapp_CallEvent)); if (ev == NULL) { PyErr_NoMemory(); return NULL; } 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_GlobalCall(PyObject *self, PyObject *args) { /* Could do the same here as for Tkapp_Call(), but this is not used much, so I can't be bothered. Unfortunately Tcl doesn't export a way for the user to do what all its Global* variants do (save and reset the scope pointer, call the local version, restore the saved scope pointer). */ char *cmd; PyObject *res = NULL; CHECK_TCL_APPARTMENT; cmd = Merge(args); if (cmd) { int err; ENTER_TCL err = Tcl_GlobalEval(Tkapp_Interp(self), cmd); ENTER_OVERLAP if (err == TCL_ERROR) res = Tkinter_Error(self); else res = PyString_FromString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL ckfree(cmd); } 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_STRING_LENGTH(script); CHECK_TCL_APPARTMENT; ENTER_TCL err = Tcl_Eval(Tkapp_Interp(self), script); ENTER_OVERLAP if (err == TCL_ERROR) res = Tkinter_Error(self); else res = PyString_FromString(Tkapp_Result(self)); LEAVE_OVERLAP_TCL return res; } static PyObject * Tkapp_GlobalEval(PyObject *self, PyObject *args) { char *script; PyObject *res = NULL; int err; if (!PyArg_ParseTuple(args, "s:globaleval", &script)) return NULL; CHECK_TCL_APPARTMENT; ENTER_TCL err = Tcl_GlobalEval(Tkapp_Interp(self), script); ENTER_OVERLAP if (err == TCL_ERROR) res = Tkinter_Error(self); else res = PyString_FromString(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_STRING_LENGTH(fileName); CHECK_TCL_APPARTMENT; ENTER_TCL err = Tcl_EvalFile(Tkapp_Interp(self), fileName); ENTER_OVERLAP if (err == TCL_ERROR) res = Tkinter_Error(self); else res = PyString_FromString(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:record", &script)) return NULL; CHECK_STRING_LENGTH(script); 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 = PyString_FromString(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_STRING_LENGTH(msg); CHECK_TCL_APPARTMENT; ENTER_TCL Tcl_AddErrorInfo(Tkapp_Interp(self), msg); LEAVE_TCL Py_INCREF(Py_None); return Py_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 (PyString_Check(in)) { if (PyString_Size(in) > INT_MAX) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return 0; } s = PyString_AsString(in); if (strlen(s) != PyString_Size(in)) { 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 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*)attemptckalloc(sizeof(VarEvent)); if (ev == NULL) { PyErr_NoMemory(); return NULL; } 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; CHECK_STRING_LENGTH(name1); CHECK_STRING_LENGTH(name2); /* 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; CHECK_STRING_LENGTH(name2); 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 { int len; char *s = Tcl_GetStringFromObj(tres, &len); res = PyString_FromStringAndSize(s, len); } } 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; CHECK_STRING_LENGTH(name1); CHECK_STRING_LENGTH(name2); 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; #if defined(TCL_WIDE_INT_TYPE) || defined(HAVE_LIBTOMMAMTH) Tcl_Obj *value; PyObject *result; #else int intValue; #endif if (PyTuple_Size(args) == 1) { PyObject* o = PyTuple_GetItem(args, 0); if (PyInt_Check(o) || PyLong_Check(o)) { Py_INCREF(o); return o; } } if (!PyArg_ParseTuple(args, "s:getint", &s)) return NULL; CHECK_STRING_LENGTH(s); #if defined(TCL_WIDE_INT_TYPE) || defined(HAVE_LIBTOMMAMTH) value = Tcl_NewStringObj(s, -1); if (value == NULL) return Tkinter_Error(self); /* Don't use Tcl_GetInt() because it returns ambiguous result for value in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform). Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform). */ #ifdef HAVE_LIBTOMMAMTH result = fromBignumObj(self, value); #else result = fromWideIntObj(self, value); #endif Tcl_DecrRefCount(value); if (result != NULL) return PyNumber_Int(result); if (PyErr_Occurred()) return NULL; #else if (Tcl_GetInt(Tkapp_Interp(self), s, &intValue) == TCL_OK) return PyInt_FromLong(intValue); #endif return Tkinter_Error(self); } 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; CHECK_STRING_LENGTH(s); 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 *arg) { char *s; int v; if (PyInt_Check(arg)) /* int or bool */ return PyBool_FromLong(PyInt_AS_LONG(arg)); if (PyLong_Check(arg)) return PyBool_FromLong(Py_SIZE(arg) != 0); if (PyTclObject_Check(arg)) { if (Tcl_GetBooleanFromObj(Tkapp_Interp(self), ((PyTclObject*)arg)->value, &v) == TCL_ERROR) return Tkinter_Error(self); return PyBool_FromLong(v); } if (!PyArg_Parse(arg, "s:getboolean", &s)) return NULL; CHECK_STRING_LENGTH(s); 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_STRING_LENGTH(s); CHECK_TCL_APPARTMENT; ENTER_TCL retval = Tcl_ExprString(Tkapp_Interp(self), s); ENTER_OVERLAP if (retval == TCL_ERROR) res = Tkinter_Error(self); else res = PyString_FromString(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_STRING_LENGTH(s); 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_STRING_LENGTH(s); 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_STRING_LENGTH(s); 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; CHECK_STRING_LENGTH(list); 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 = PyString_FromString(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 PyString_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; CHECK_STRING_LENGTH(list); v = Split(list); PyMem_Free(list); return v; } static PyObject * Tkapp_Merge(PyObject *self, PyObject *args) { char *s = Merge(args); PyObject *res = NULL; if (s) { res = PyString_FromString(s); ckfree(s); } return res; } /** 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 = fromTclString(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; CHECK_STRING_LENGTH(cmdName); 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*)attemptckalloc(sizeof(CommandEvent)); if (ev == NULL) { PyErr_NoMemory(); PyMem_DEL(data); return NULL; } 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_INCREF(Py_None); return Py_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; CHECK_STRING_LENGTH(cmdName); #ifdef WITH_THREAD if (self->threaded && self->thread_id != Tcl_GetCurrentThread()) { Tcl_Condition cond = NULL; CommandEvent *ev; ev = (CommandEvent*)attemptckalloc(sizeof(CommandEvent)); if (ev == NULL) { PyErr_NoMemory(); return NULL; } 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_INCREF(Py_None); return Py_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 (!self && Py_Py3kWarningFlag) { if (PyErr_Warn(PyExc_DeprecationWarning, "_tkinter.createfilehandler is gone in 3.x") < 0) return NULL; } if (!PyArg_ParseTuple(args, "OiO:createfilehandler", &file, &mask, &func)) return NULL; #ifdef WITH_THREAD if (!self && !tcl_lock) { /* We don't have the Tcl lock since Tcl is threaded. */ PyErr_SetString(PyExc_RuntimeError, "_tkinter.createfilehandler not supported " "for threaded Tcl"); return NULL; } #endif if (self) { 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_INCREF(Py_None); return Py_None; } static PyObject * Tkapp_DeleteFileHandler(PyObject *self, PyObject *args) { PyObject *file; int tfile; if (!self && Py_Py3kWarningFlag) { if (PyErr_Warn(PyExc_DeprecationWarning, "_tkinter.deletefilehandler is gone in 3.x") < 0) return NULL; } if (!PyArg_ParseTuple(args, "O:deletefilehandler", &file)) return NULL; #ifdef WITH_THREAD if (!self && !tcl_lock) { /* We don't have the Tcl lock since Tcl is threaded. */ PyErr_SetString(PyExc_RuntimeError, "_tkinter.deletefilehandler not supported " "for threaded Tcl"); return NULL; } #endif if (self) { 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_INCREF(Py_None); return Py_None; } #endif /* HAVE_CREATEFILEHANDLER */ /**** Tktt Object (timer token) ****/ static PyTypeObject 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_INCREF(Py_None); return Py_None; } static PyMethodDef Tktt_methods[] = { {"deletetimerhandler", Tktt_DeleteTimerHandler, METH_VARARGS}, {NULL, NULL} }; static TkttObject * Tktt_New(PyObject *func) { TkttObject *v; v = PyObject_New(TkttObject, &Tktt_Type); if (v == NULL) return NULL; 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; Py_XDECREF(func); PyObject_Del(self); } static PyObject * Tktt_Repr(PyObject *self) { TkttObject *v = (TkttObject *)self; char buf[100]; PyOS_snprintf(buf, sizeof(buf), "", v, v->func == NULL ? ", handler deleted" : ""); return PyString_FromString(buf); } static PyObject * Tktt_GetAttr(PyObject *self, char *name) { return Py_FindMethod(Tktt_methods, self, name); } static PyTypeObject Tktt_Type = { PyVarObject_HEAD_INIT(NULL, 0) "tktimertoken", /*tp_name */ sizeof(TkttObject), /*tp_basicsize */ 0, /*tp_itemsize */ Tktt_Dealloc, /*tp_dealloc */ 0, /*tp_print */ Tktt_GetAttr, /*tp_getattr */ 0, /*tp_setattr */ 0, /*tp_compare */ Tktt_Repr, /*tp_repr */ 0, /*tp_as_number */ 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ 0, /*tp_hash */ }; /** 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 (!self && Py_Py3kWarningFlag) { if (PyErr_Warn(PyExc_DeprecationWarning, "_tkinter.createtimerhandler is gone in 3.x") < 0) return NULL; } if (!PyArg_ParseTuple(args, "iO:createtimerhandler", &milliseconds, &func)) return NULL; if (!PyCallable_Check(func)) { PyErr_SetString(PyExc_TypeError, "bad argument list"); return NULL; } #ifdef WITH_THREAD if (!self && !tcl_lock) { /* We don't have the Tcl lock since Tcl is threaded. */ PyErr_SetString(PyExc_RuntimeError, "_tkinter.createtimerhandler not supported " "for threaded Tcl"); return NULL; } #endif if (self) { 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 (!self && Py_Py3kWarningFlag) { if (PyErr_Warn(PyExc_DeprecationWarning, "_tkinter.mainloop is gone in 3.x") < 0) return NULL; } if (!PyArg_ParseTuple(args, "|i:mainloop", &threshold)) return NULL; #ifdef WITH_THREAD if (!self && !tcl_lock) { /* We don't have the Tcl lock since Tcl is threaded. */ PyErr_SetString(PyExc_RuntimeError, "_tkinter.mainloop not supported " "for threaded Tcl"); return NULL; } #endif if (self) { CHECK_TCL_APPARTMENT; self->dispatching = 1; } quitMainLoop = 0; while (Tk_GetNumMainWindows() > threshold && !quitMainLoop && !errorInCmd) { int result; #ifdef WITH_THREAD if (self && 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) { if (self) self->dispatching = 0; return NULL; } if (result < 0) break; } if (self) self->dispatching = 0; quitMainLoop = 0; if (errorInCmd) { errorInCmd = 0; PyErr_Restore(excInCmd, valInCmd, trbInCmd); excInCmd = valInCmd = trbInCmd = NULL; return NULL; } Py_INCREF(Py_None); return Py_None; } static PyObject * Tkapp_DoOneEvent(PyObject *self, PyObject *args) { int flags = 0; int rv; if (!self && Py_Py3kWarningFlag) { if (PyErr_Warn(PyExc_DeprecationWarning, "_tkinter.dooneevent is gone in 3.x") < 0) return NULL; } 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 (!self && Py_Py3kWarningFlag) { if (PyErr_Warn(PyExc_DeprecationWarning, "_tkinter.quit is gone in 3.x") < 0) return NULL; } if (!PyArg_ParseTuple(args, ":quit")) return NULL; quitMainLoop = 1; Py_INCREF(Py_None); return Py_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_INCREF(Py_None); return Py_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_INCREF(Py_None); return Py_None; } static PyObject * Tkapp_WillDispatch(PyObject *self, PyObject *args) { ((TkappObject*)self)->dispatching = 1; Py_INCREF(Py_None); return Py_None; } /* Convert Python string or any buffer compatible object to Tcl byte-array * object. Use it to pass binary data (e.g. image's data) to Tcl/Tk commands. */ static PyObject * Tkapp_CreateByteArray(PyObject *self, PyObject *args) { Py_buffer view; Tcl_Obj* obj; PyObject *res = NULL; if (!PyArg_ParseTuple(args, "s*:_createbytearray", &view)) return NULL; if (view.len >= INT_MAX) { PyErr_SetString(PyExc_OverflowError, "string is too long"); return NULL; } obj = Tcl_NewByteArrayObj(view.buf, (int)view.len); if (obj == NULL) { PyBuffer_Release(&view); return Tkinter_Error(self); } res = newPyTclObject(obj); PyBuffer_Release(&view); return res; } /**** Tkapp Method List ****/ static PyMethodDef Tkapp_methods[] = { {"willdispatch", Tkapp_WillDispatch, METH_NOARGS}, {"wantobjects", Tkapp_WantObjects, METH_VARARGS}, {"call", Tkapp_Call, METH_VARARGS}, {"globalcall", Tkapp_GlobalCall, METH_VARARGS}, {"eval", Tkapp_Eval, METH_VARARGS}, {"globaleval", Tkapp_GlobalEval, 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_O}, {"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}, {"merge", Tkapp_Merge, 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}, {"_createbytearray", Tkapp_CreateByteArray, METH_VARARGS}, {NULL, NULL} }; /**** Tkapp Type Methods ****/ static void Tkapp_Dealloc(PyObject *self) { /*CHECK_TCL_APPARTMENT;*/ ENTER_TCL Tcl_DeleteInterp(Tkapp_Interp(self)); LEAVE_TCL PyObject_Del(self); DisableEventHook(); } static PyObject * Tkapp_GetAttr(PyObject *self, char *name) { return Py_FindMethod(Tkapp_methods, self, name); } static PyTypeObject Tkapp_Type = { PyVarObject_HEAD_INIT(NULL, 0) "tkapp", /*tp_name */ sizeof(TkappObject), /*tp_basicsize */ 0, /*tp_itemsize */ Tkapp_Dealloc, /*tp_dealloc */ 0, /*tp_print */ Tkapp_GetAttr, /*tp_getattr */ 0, /*tp_setattr */ 0, /*tp_compare */ 0, /*tp_repr */ 0, /*tp_as_number */ 0, /*tp_as_sequence */ 0, /*tp_as_mapping */ 0, /*tp_hash */ }; /**** 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; 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 */ baseName = strrchr(Py_GetProgramName(), '/'); if (baseName != NULL) baseName++; else baseName = Py_GetProgramName(); className = "Tk"; if (!PyArg_ParseTuple(args, "|zssiiiiz:create", &screenName, &baseName, &className, &interactive, &wantobjects, &wantTk, &sync, &use)) return NULL; CHECK_STRING_LENGTH(screenName); CHECK_STRING_LENGTH(baseName); CHECK_STRING_LENGTH(className); CHECK_STRING_LENGTH(use); return (PyObject *) Tkapp_New(screenName, baseName, 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_INCREF(Py_None); return Py_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 PyInt_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}, #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}, {"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 } /* all errors will be checked in one fell swoop in init_tkinter() */ static void ins_long(PyObject *d, char *name, long val) { PyObject *v = PyInt_FromLong(val); if (v) { PyDict_SetItemString(d, name, v); Py_DECREF(v); } } static void ins_string(PyObject *d, char *name, char *val) { PyObject *v = PyString_FromString(val); if (v) { PyDict_SetItemString(d, name, v); Py_DECREF(v); } } PyMODINIT_FUNC init_tkinter(void) { PyObject *m, *d; Py_TYPE(&Tkapp_Type) = &PyType_Type; #ifdef WITH_THREAD tcl_lock = PyThread_allocate_lock(); #endif m = Py_InitModule("_tkinter", moduleMethods); if (m == NULL) return; d = PyModule_GetDict(m); Tkinter_TclError = PyErr_NewException("_tkinter.TclError", NULL, NULL); PyDict_SetItemString(d, "TclError", Tkinter_TclError); ins_long(d, "READABLE", TCL_READABLE); ins_long(d, "WRITABLE", TCL_WRITABLE); ins_long(d, "EXCEPTION", TCL_EXCEPTION); ins_long(d, "WINDOW_EVENTS", TCL_WINDOW_EVENTS); ins_long(d, "FILE_EVENTS", TCL_FILE_EVENTS); ins_long(d, "TIMER_EVENTS", TCL_TIMER_EVENTS); ins_long(d, "IDLE_EVENTS", TCL_IDLE_EVENTS); ins_long(d, "ALL_EVENTS", TCL_ALL_EVENTS); ins_long(d, "DONT_WAIT", TCL_DONT_WAIT); ins_string(d, "TK_VERSION", TK_VERSION); ins_string(d, "TCL_VERSION", TCL_VERSION); PyDict_SetItemString(d, "TkappType", (PyObject *)&Tkapp_Type); Py_TYPE(&Tktt_Type) = &PyType_Type; PyDict_SetItemString(d, "TkttType", (PyObject *)&Tktt_Type); Py_TYPE(&PyTclObject_Type) = &PyType_Type; PyDict_SetItemString(d, "Tcl_Obj", (PyObject *)&PyTclObject_Type); #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. */ Tcl_FindExecutable(Py_GetProgramName()); if (PyErr_Occurred()) return; #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 } python-stdlib-extensions-2.7.12/2.7/setup.py0000664000000000000000000011267512356733400015527 0ustar # Autodetecting setup.py script for building the Python extensions # __version__ = "$Revision: 82272 $" import sys, os, imp, re, optparse from glob import glob from platform import machine as platform_machine 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.spawn import find_executable # Were we compiled --with-pydebug or with #define Py_DEBUG? COMPILED_WITH_PYDEBUG = hasattr(sys, 'gettotalrefcount') # 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' (at the front) if 1) 'dir' is not already in 'dirlist' 2) 'dir' actually exists, and is a directory.""" if dir is not None and os.path.isdir(dir) and dir not in dirlist: dirlist.insert(0, dir) 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 sys.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 sys.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 sys.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 sys.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 sys.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 sys.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 missing = self.detect_modules() # 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/ and adding Python's include directory to the path. (srcdir,) = sysconfig.get_config_vars('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')] # Platform-dependent module source and include directories incdirlist = [] platform = self.get_platform() if platform == 'darwin' and ("--disable-toolbox-glue" not in sysconfig.get_config_var("CONFIG_ARGS")): # Mac OS X also includes some mac-specific modules macmoddir = os.path.join(srcdir, 'Mac/Modules') moddirlist.append(macmoddir) incdirlist.append(os.path.join(srcdir, 'Mac/Include')) # 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('platinclude'), "*.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) # platform specific include directories ext.include_dirs.extend(incdirlist) # 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,cflags) = sysconfig.get_config_vars('CCSHARED','CFLAGS') args['compiler_so'] = compiler + ' ' + ccshared + ' ' + 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), 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 self.get_platform() == 'darwin' and ( sys.maxint > 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 self.get_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))) try: imp.load_dynamic(ext.name, ext_filename) except ImportError, 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 get_platform(self): # Get value of sys.platform for platform in ['cygwin', 'beos', 'darwin', 'atheos', 'osf1']: if sys.platform.startswith(platform): return platform return sys.platform def detect_modules(self): # Ensure that /usr/local is always used # On Debian /usr/local is always used, so we don't include it twice #add_dir_to_list(self.compiler.library_dirs, '/usr/local/lib') #add_dir_to_list(self.compiler.include_dirs, '/usr/local/include') # 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.prefix) != '/usr': 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")) try: have_unicode = unicode except NameError: have_unicode = 0 # 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. gnu_triplet = os.popen('dpkg-architecture -qDEB_HOST_MULTIARCH 2>/dev/null || dpkg-architecture -qDEB_HOST_GNU_TYPE').readline()[:-1] lib_dirs = self.compiler.library_dirs + [ os.path.join('/lib', gnu_triplet), os.path.join('/usr/lib', gnu_triplet), '/lib', '/usr/lib', ] inc_dirs = self.compiler.include_dirs + ['/usr/include'] inc_dirs.append(os.path.join('/usr/include', gnu_triplet)) exts = [] missing = [] config_h = sysconfig.get_config_h_filename() config_h_vars = sysconfig.parse_config_h(open(config_h)) platform = self.get_platform() srcdir = sysconfig.get_config_var('srcdir') # Check for AtheOS which has libraries in non-standard locations if platform == 'atheos': lib_dirs += ['/system/libs', '/atheos/autolnk/lib'] lib_dirs += os.getenv('LIBRARY_PATH', '').split(os.pathsep) inc_dirs += ['/system/include', '/atheos/autolnk/include'] inc_dirs += os.getenv('C_INCLUDE_PATH', '').split(os.pathsep) # OSF/1 and Unixware have some stuff in /usr/ccs/lib (like -ldb) if platform in ['osf1', 'unixware7', 'openunix8']: lib_dirs += ['/usr/ccs/lib'] if 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 platform in ['darwin', 'beos']: math_libs = [] # XXX Omitted modules: gl, pure, dl, SGI-specific modules # # The following modules are all pretty straightforward, and compile # on pretty much any POSIXish platform. # dbm_order = ['gdbm'] # Anthony Baxter's gdbm module. GNU dbm(3) will require -lgdbm: if ('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) if is_macosx_sdk_path(F): fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(os.path.join(sysroot, F[1:]),)) else: fp = os.popen("file %s/Tk.framework/Tk | grep 'for architecture'"%(F,)) detected_archs = [] for ln in fp: a = ln.split()[-1] if a in archs: detected_archs.append(ln.split()[-1]) fp.close() 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. platform = self.get_platform() if (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 sys.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 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 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, 'BLT85'): defs.append( ('WITH_BLT', 1) ) libs.append('BLT85') elif self.compiler.find_library_file(lib_dirs + added_lib_dirs, 'BLT86'): defs.append( ('WITH_BLT', 1) ) libs.append('BLT86') 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 platform in ['aix3', 'aix4']: libs.append('ld') # Finally, link with the X11 libraries (not appropriate on cygwin) if 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) ## # Uncomment these lines if you want to play with xxmodule.c ## ext = Extension('xx', ['xxmodule.c']) ## 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 \ def configure_ctypes_darwin(self, ext): # Darwin (OS X) uses preconfigured files, in # the Modules/_ctypes/libffi_osx directory. srcdir = sysconfig.get_config_var('srcdir') ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules', '_ctypes', 'libffi_osx')) sources = [os.path.join(ffi_srcdir, p) for p in ['ffi.c', 'x86/darwin64.S', 'x86/x86-darwin.S', 'x86/x86-ffi_darwin.c', 'x86/x86-ffi64.c', 'powerpc/ppc-darwin.S', 'powerpc/ppc-darwin_closure.S', 'powerpc/ppc-ffi_darwin.c', 'powerpc/ppc64-darwin_closure.S', ]] # Add .S (preprocessed assembly) to C compiler source extensions. self.compiler.src_extensions.append('.S') include_dirs = [os.path.join(ffi_srcdir, 'include'), os.path.join(ffi_srcdir, 'powerpc')] ext.include_dirs.extend(include_dirs) ext.sources.extend(sources) return True def configure_ctypes(self, ext): if not self.use_system_libffi: if sys.platform == 'darwin': return self.configure_ctypes_darwin(ext) srcdir = sysconfig.get_config_var('srcdir') ffi_builddir = os.path.join(self.build_temp, 'libffi') ffi_srcdir = os.path.abspath(os.path.join(srcdir, 'Modules', '_ctypes', 'libffi')) ffi_configfile = os.path.join(ffi_builddir, 'fficonfig.py') from distutils.dep_util import newer_group config_sources = [os.path.join(ffi_srcdir, fname) for fname in os.listdir(ffi_srcdir) if os.path.isfile(os.path.join(ffi_srcdir, fname))] if self.force or newer_group(config_sources, ffi_configfile): from distutils.dir_util import mkpath mkpath(ffi_builddir) config_args = [] # Pass empty CFLAGS because we'll just append the resulting # CFLAGS to Python's; -g or -O2 is to be avoided. cmd = "cd %s && env CFLAGS='' '%s/configure' %s" \ % (ffi_builddir, ffi_srcdir, " ".join(config_args)) res = os.system(cmd) if res or not os.path.exists(ffi_configfile): print "Failed to configure _ctypes module" return False fficonfig = {} with open(ffi_configfile) as f: exec f in fficonfig # Add .S (preprocessed assembly) to C compiler source extensions. self.compiler.src_extensions.append('.S') include_dirs = [os.path.join(ffi_builddir, 'include'), ffi_builddir, os.path.join(ffi_srcdir, 'src')] extra_compile_args = fficonfig['ffi_cflags'].split() ext.sources.extend(os.path.join(ffi_srcdir, f) for f in fficonfig['ffi_sources']) ext.include_dirs.extend(include_dirs) ext.extra_compile_args.extend(extra_compile_args) return True def detect_ctypes(self, inc_dirs, lib_dirs): self.use_system_libffi = False include_dirs = [] extra_compile_args = [] extra_link_args = [] sources = ['_ctypes/_ctypes.c', '_ctypes/callbacks.c', '_ctypes/callproc.c', '_ctypes/stgdict.c', '_ctypes/cfield.c', '_ctypes/malloc_closure.c'] depends = ['_ctypes/ctypes.h'] if sys.platform == 'darwin': sources.append('_ctypes/darwin/dlfcn_simple.c') extra_compile_args.append('-DMACOSX') include_dirs.append('_ctypes/darwin') # XXX Is this still needed? ## extra_link_args.extend(['-read_only_relocs', 'warning']) elif sys.platform == 'sunos5': # XXX This shouldn't be necessary; it appears that some # of the assembler code is non-PIC (i.e. it has relocations # when it shouldn't. The proper fix would be to rewrite # the assembler code to be PIC. # This only works with GCC; the Sun compiler likely refuses # this option. If you want to compile ctypes with the Sun # compiler, please research a proper solution, instead of # finding some -z option for the Sun compiler. extra_link_args.append('-mimpure-text') elif sys.platform.startswith('hp-ux'): extra_link_args.append('-fPIC') ext = Extension('_ctypes', include_dirs=include_dirs, extra_compile_args=extra_compile_args, extra_link_args=extra_link_args, libraries=[], sources=sources, depends=depends) ext_test = Extension('_ctypes_test', sources=['_ctypes/_ctypes_test.c']) self.extensions.extend([ext, ext_test]) if not '--with-system-ffi' in sysconfig.get_config_var("CONFIG_ARGS"): return if sys.platform == 'darwin': # OS X 10.5 comes with libffi.dylib; the include files are # in /usr/include/ffi inc_dirs.append('/usr/include/ffi') ffi_inc = [sysconfig.get_config_var("LIBFFI_INCLUDEDIR")] if not ffi_inc or ffi_inc[0] == '': ffi_inc = find_file('ffi.h', [], inc_dirs) if ffi_inc is not None: ffi_h = ffi_inc[0] + '/ffi.h' fp = open(ffi_h) while 1: line = fp.readline() if not line: ffi_inc = None break if line.startswith('#define LIBFFI_H'): break ffi_lib = None if ffi_inc is not None: for lib_name in ('ffi_convenience', 'ffi_pic', 'ffi'): if (self.compiler.find_library_file(lib_dirs, lib_name)): ffi_lib = lib_name break if ffi_inc and ffi_lib: ext.include_dirs.extend(ffi_inc) ext.libraries.append(ffi_lib) self.use_system_libffi = True 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, 0644, 0755) self.set_dir_modes(self.install_dir, 0755) 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 os.path.walk(dirname, self.set_dir_modes_visitor, mode) def set_dir_modes_visitor(self, mode, dirname, names): if os.path.islink(dirname): return log.info("changing mode of %s to %o", dirname, mode) if not self.dry_run: os.chmod(dirname, 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 = filter(None, CLASSIFIERS.split("\n")), 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'])], # Scripts to install scripts = [] ) # --install-platlib if __name__ == '__main__': main()