python-defaults-2.7.12/0000775000000000000000000000000013205532536011625 5ustar python-defaults-2.7.12/autoscripts/0000775000000000000000000000000012057417145014207 5ustar python-defaults-2.7.12/autoscripts/postinst-pycompile0000664000000000000000000000011312057417145020007 0ustar if which pycompile >/dev/null 2>&1; then pycompile -p #PACKAGE# #ARGS# fi python-defaults-2.7.12/autoscripts/preinst-pycentral-clean0000664000000000000000000000035112057417145020674 0ustar # make sure python-central files are removed before new package is installed if [ "$1" = upgrade ] && [ -f /var/lib/pycentral/#PACKAGE#.pkgremove ] then pycentral pkgremove #PACKAGE# rm -f /var/lib/pycentral/#PACKAGE#.pkgremove fi python-defaults-2.7.12/autoscripts/prerm-pyclean0000664000000000000000000000025312057417145016710 0ustar if which pyclean >/dev/null 2>&1; then pyclean -p #PACKAGE# #ARGS# else dpkg -L #PACKAGE# | grep \.py$ | while read file do rm -f "${file}"[co] >/dev/null done fi python-defaults-2.7.12/dh_python2.10000664000000000000000000002160712374331373013775 0ustar .\" Man page generated from reStructuredText. . .TH DH_PYTHON2 1 "" "" "" .SH NAME dh_python2 \- calculates Python dependencies, adds maintainer scripts to byte compile files, etc. . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .INDENT 0.0 .INDENT 3.5 dh_python2 \-p PACKAGE [\-V [X.Y][\-][A.B]] DIR_OR_FILE [\-X REGEXPR] .UNINDENT .UNINDENT .SH DESCRIPTION .SS QUICK GUIDE FOR MAINTAINERS .INDENT 0.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 if necessary, describe supported Python versions via X\-Python\-Version field in debian/control, .IP \(bu 2 build\-depend on python or python\-all or python\-all\-dev (>= 2.6.6\-3~), .IP \(bu 2 build module/application using its standard build system, remember to build extensions for all supported Python versions (loop over \fBpyversions \-vr\fP), .IP \(bu 2 install files to the \fIstandard\fP locations, add \fI\-\-install\-layout=deb\fP to setup.py\(aqs install command if your package is using distutils, .IP \(bu 2 add \fIpython2\fP to dh\(aqs \-\-with option, or: .IP \(bu 2 \fIinclude /usr/share/cdbs/1/class/python\-distutils.mk\fP in debian/rules and depend on \fIcdbs (>= 0.4.90)\fP, or: .IP \(bu 2 call \fBdh_python2\fP in the \fIbinary\-*\fP target, .IP \(bu 2 add \fI${python:Depends}\fP to Depends .UNINDENT .UNINDENT .UNINDENT .SS NOTES .sp In order to support more than one Python version in the same binary package, dh_python2 (unlike dh_pycentral and dh_pysupport) creates symlinks to all supported Python versions at build time. It means binNMU (or sourceful upload in case of architecture independent packages) is required once a list of supported Python version is changed. It\(aqs faster and more robust than its competitors, though. .SS dependencies .sp dh_python2 tries to translate Python dependencies from requires.txt file to Debian dependencies. Use debian/pydist\-overrides or \-\-no\-guessing\-deps option to override it if the guess is incorrect. If you want dh_python2 to generate more strict dependencies (f.e. to avoid ABI problems) create debian/python\-foo.pydist file. See /usr/share/doc/python\-doc/README.PyDist (provided by python\-doc package) for more information. If the pydist file contains PEP386 flag or set of (uscan like) rules, dh_python2 will make the depedency versioned (version requirements are ignored by default). .SS namespace feature .sp dh_python2 parses Egg\(aqs namespace_packages.txt files (in addition to \-\-namespace command line argument(s)) and drops empty __init__.py files from binary package. pycompile will regenerate them at install time and pyclean will remove them at uninstall time (if they\(aqre no longer used in installed packages). It\(aqs still a good idea to provide __init__.py file in one of binary packages (even if all other packages use this feature). .SS private dirs .sp \fI/usr/share/foo\fP, \fI/usr/share/games/foo\fP, \fI/usr/lib/foo\fP and \fI/usr/lib/games/foo\fP private directories are scanned for Python files by default (where \fIfoo\fP is binary package name). If your package is shipping Python files in some other directory, add another dh_python2 call in debian/rules with directory name as an argument \- you can use different set of options in this call. If you need to change options (f.e. a list of supported Python versions) for a private directory that is checked by default, invoke dh_python2 with \-\-skip\-private option and add another call with a path to this directory and new options. .SS debug packages .sp In binary packages which name ends with \fI\-dbg\fP, all files in \fI/usr/lib/python2.X/{site,dist}\-packages/\fP directory that have extensions different than \fIso\fP or \fIh\fP are removed by default. Use \-\-no\-dbg\-cleaning option to disable this feature. .SS pyinstall files .sp Files listed in debian/pkg.pyinstall file will be installed as public modules for all requested Python versions (dh_install doesn\(aqt know about python\(aqs site\- vs. dist\-packages issue). .sp Syntax: \fBpath/to/file [VERSION_RANGE] [NAMESPACE]\fP .sp debian directory is automatically removed from the path, so you can place your files in debian/ directory and install them from this location (if you want to install them in "debian" namespace, set NAMESPACE to debian). If NAMESPACE is set, all listed files will be installed in .../dist\-packages/NAMESPACE/ directory. .INDENT 0.0 .TP .B Examples: .INDENT 7.0 .IP \(bu 2 \fBfoo.py\fP installs .../dist\-packages/foo.py for all supported Python versions .IP \(bu 2 \fBfoo/bar.py 2.6\-\fP installs .../dist\-packages/foo/bar.py for versions >= 2.6 .IP \(bu 2 \fBfoo/bar.py spam\fP installs .../dist\-packages/spam/bar.py .IP \(bu 2 \fBdebian/*.py spam.egg 2.5\fP installs .../python2.5/site\-packages/spam/egg/*.py files .UNINDENT .UNINDENT .SS pyremove files .sp If you want to remove some files installed by build system (from all supported Python versions or only from a subset of these versions), add them to debian/pkg.pyremove file. .INDENT 0.0 .TP .B Examples: .INDENT 7.0 .IP \(bu 2 \fB*.pth\fP removes .pth files from .../dist\-packages/ .IP \(bu 2 \fBbar/baz.py 2.5\fP removes .../python2.5/site\-packages/bar/baz.py .UNINDENT .UNINDENT .SS overriding supported / default Python versions .sp If you want to override system\(aqs list of supported Python versions or the default one (f.e. to build a package that includes symlinks for older version of Python or compile .py files only for given interpreter version), you can do that via \fIDEBPYTHON_SUPPORTED\fP and/or \fIDEBPYTHON_DEFAULT\fP env. variables. .sp Example: \fB2.5,2.7\fP limits the list of supported Python versions to Python 2.5 and Python 2.7. .SH OPTIONS .INDENT 0.0 .TP .B \-\-version show program\(aqs version number and exit .TP .B \-h\fP,\fB \-\-help show help message and exit .TP .B \-\-no\-guessing\-versions disable guessing other supported Python versions .TP .B \-\-no\-guessing\-deps disable guessing dependencies .TP .B \-\-no\-dbg\-cleaning do not remove any files from debug packages .TP .B \-\-no\-shebang\-rewrite do not rewrite shebangs .TP .B \-\-skip\-private don\(aqt check private directories .TP .B \-v\fP,\fB \-\-verbose turn verbose mode on .TP .B \-i\fP,\fB \-\-indep act on architecture independent packages .TP .B \-a\fP,\fB \-\-arch act on architecture dependent packages .TP .B \-q\fP,\fB \-\-quiet be quiet .TP .BI \-p \ PACKAGE\fP,\fB \ \-\-package\fB= PACKAGE act on the package named PACKAGE .TP .BI \-N \ NO_PACKAGE\fP,\fB \ \-\-no\-package\fB= NO_PACKAGE do not act on the specified package .TP .BI \-V \ VRANGE specify list of supported Python versions. See pycompile(1) for examples .TP .BI \-X \ REGEXPR\fP,\fB \ \-\-exclude\fB= REGEXPR exclude items that match given REGEXPR. You may use this option multiple times to build up a list of things to exclude. .TP .B \-\-compile\-all compile all files from given private directory in postinst/rtupdate not just the ones provided by the package (i.e. do not pass the \-\-package parameter to pycompile/pyclean) .TP .BI \-\-depends\fB= DEPENDS translate given requirements into Debian dependencies and add them to ${python:Depends}. Use it for missing items in requires.txt .TP .BI \-\-recommends\fB= RECOMMENDS translate given requirements into Debian dependencies and add them to ${python:Recommends} .TP .BI \-\-suggests\fB= SUGGESTS translate given requirements into Debian dependencies and add them to ${python:Suggests} .TP .B \-\-namespace use this option (multiple time if necessary) if namespace_packages.txt is not complete .TP .B \-\-ignore\-namespace ignore Egg\(aqs namespace declaration and \-\-namespace option. This option will disable removing (and recreating at install time) empty __init__.py files. Removing namespace_packages.txt from egg\-info directory has the same effect. .TP .B \-\-clean\-pycentral generate maintainer script that will remove byte code generated by python\-central helper .TP .BI \-\-shebang\fB= COMMAND use given command as shebang in scripts .TP .B \-\-ignore\-shebangs do not translate shebangs into Debian dependencies .UNINDENT .SH SEE ALSO .INDENT 0.0 .IP \(bu 2 /usr/share/doc/python/python\-policy.txt.gz .IP \(bu 2 /usr/share/doc/python\-doc/README.PyDist (python\-doc package) .IP \(bu 2 pycompile(1), pyclean(1) .IP \(bu 2 dh_python3(1), py3compile(1), py3clean(1) .IP \(bu 2 Wiki page about converting package to dh_python2: \fI\%http://wiki.debian.org/Python/TransitionToDHPython2\fP .UNINDENT .SH AUTHOR Piotr Ożarowski, 2012-2013 .\" Generated by docutils manpage writer. . python-defaults-2.7.12/dh_python20000775000000000000000000007454312442272363013647 0ustar #! /usr/bin/python # -*- coding: UTF-8 -*- vim: et ts=4 sw=4 # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from __future__ import with_statement import logging import os import re import sys from filecmp import dircmp, cmpfiles, cmp as fcmp from optparse import OptionParser, SUPPRESS_HELP from os.path import isabs, isdir, islink, exists, join, normpath, realpath,\ split from shutil import rmtree, copy as fcopy from stat import ST_MODE, S_IXUSR, S_IXGRP, S_IXOTH from debpython.debhelper import DebHelper from debpython.depends import Dependencies from debpython.version import SUPPORTED, DEFAULT, \ debsorted, getver, vrepr, parse_pycentral_vrange, \ get_requested_versions, parse_vrange, vrange_str import debpython.namespace as ns from debpython.pydist import validate as validate_pydist, \ PUBLIC_DIR_RE from debpython.tools import sitedir, relative_symlink, \ fix_shebang, shebang2pyver, \ so2pyver, clean_egg_name, \ pyinstall, pyremove from debpython.option import Option # initialize script logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: ' '%(message)s') log = logging.getLogger(__name__) os.umask(022) EGGnPTH_RE = re.compile(r'(.*?)(-py\d\.\d+)?(.*?)(\.egg-info|\.pth)$') # naming conventions used in the file: # * version - tuple of integers # * ver - string representation of version # * vrange - version range, pair of max and min versions # * fn - file name (without path) # * fpath - file path ### FILES ###################################################### def fix_locations(package): """Move files to the right location.""" found_versions = {} for version in SUPPORTED: ver = vrepr(version) to_check = [i % ver for i in (\ 'usr/local/lib/python%s/site-packages', 'usr/local/lib/python%s/dist-packages', 'var/lib/python-support/python%s', 'usr/lib/pymodules/python%s')] if version >= (2, 6): to_check.append("usr/lib/python%s/site-packages" % ver) dstdir = sitedir(version, package) for location in to_check: srcdir = "debian/%s/%s" % (package, location) if isdir(srcdir): if ver in found_versions: log.error('files for version %s ' 'found in two locations:\n %s\n %s', ver, location, found_versions[ver]) exit(2) log.info('Python %s should install files in %s. ' 'Did you forget "--install-layout=deb"?', ver, sitedir(version)) if not isdir(dstdir): os.makedirs(dstdir) # TODO: what about relative symlinks? log.debug('moving files from %s to %s', srcdir, dstdir) os.renames(srcdir, dstdir) found_versions[ver] = location # do the same with debug locations dbg_to_check = ['usr/lib/debug/%s' % i for i in to_check] dbg_to_check.append("usr/lib/debug/usr/lib/pyshared/python%s" % ver) dstdir = sitedir(version, package, gdb=True) for location in dbg_to_check: srcdir = "debian/%s/%s" % (package, location) if isdir(srcdir): if not isdir(dstdir): os.makedirs(dstdir) log.debug('moving files from %s to %s', srcdir, dstdir) os.renames(srcdir, dstdir) ### SHARING FILES ############################################## def share(package, stats, options): """Move files to /usr/share/pyshared/ if possible.""" if package.endswith('-dbg'): # nothing to share in debug packages return pubvers = debsorted(i for i in stats['public_vers'] if i[0] == 2) if len(pubvers) > 1: for pos, version1 in enumerate(pubvers): dir1 = sitedir(version1, package) for version2 in pubvers[pos + 1:]: dir2 = sitedir(version2, package) dc = dircmp(dir1, dir2) share_2x(dir1, dir2, dc) elif len(pubvers) == 1: # don't install into pyshared anymore pass if options.guess_versions and pubvers: for version in get_requested_versions(options.vrange): if version not in pubvers: log.debug('guessing files for Python %s', vrepr(version)) versions_without_ext = debsorted(set(pubvers) -\ stats['ext']) if not versions_without_ext: log.error('extension for python%s is missing. ' 'Build extensions for all supported Python ' 'versions (`pyversions -vr`) or adjust ' 'X-Python-Version field or pass ' '--no-guessing-versions to dh_python2', vrepr(version)) exit(3) srcver = versions_without_ext[0] if srcver in stats['public_vers']: stats['public_vers'].add(version) share_2x(sitedir(srcver, package), sitedir(version, package)) # remove duplicates stats['requires.txt'] = set(realpath(i) for i in stats['requires.txt']) stats['nsp.txt'] = set(realpath(i) for i in stats['nsp.txt']) def move_to_pyshared(dir1): # dir1 starts with debian/packagename/usr/lib/pythonX.Y/*-packages/ debian, package, path = dir1.split('/', 2) dstdir = join(debian, package, 'usr/share/pyshared/', \ '/'.join(dir1.split('/')[6:])) fext = lambda fname: fname.rsplit('.', 1)[-1] for i in os.listdir(dir1): fpath1 = join(dir1, i) if isdir(fpath1) and not islink(fpath1): if any(fn for fn in os.listdir(fpath1) if fext(fn) != 'so'): # at least one file that is not an extension move_to_pyshared(join(dir1, i)) else: if fext(i) == 'so': continue fpath2 = join(dstdir, i) if not exists(fpath2): if not exists(dstdir): os.makedirs(dstdir) if islink(fpath1): fpath1_target = os.readlink(fpath1) if isabs(fpath1_target): os.symlink(fpath1_target, fpath2) else: fpath1_target = normpath(join(dir1, fpath1_target)) relative_symlink(fpath1_target, fpath2) os.remove(fpath1) else: os.rename(fpath1, fpath2) relative_symlink(fpath2, fpath1) def create_ext_links(dir1): """Create extension symlinks in /usr/lib/pyshared/pythonX.Y. These symlinks are used to let dpkg detect file conflicts with python-support and python-central packages. """ debian, package, path = dir1.split('/', 2) python, _, module_subpath = path[8:].split('/', 2) dstdir = join(debian, package, 'usr/lib/pyshared/', python, module_subpath) for i in os.listdir(dir1): fpath1 = join(dir1, i) if isdir(fpath1): create_ext_links(fpath1) elif i.rsplit('.', 1)[-1] == 'so': fpath2 = join(dstdir, i) if exists(fpath2): continue if not exists(dstdir): os.makedirs(dstdir) relative_symlink(fpath1, join(dstdir, i)) def create_public_links(dir1, vrange, root=''): """Create public module symlinks for given directory.""" debian, package, path = dir1.split('/', 2) versions = get_requested_versions(vrange) for fn in os.listdir(dir1): fpath1 = join(dir1, fn) if isdir(fpath1): create_public_links(fpath1, vrange, join(root, fn)) else: for version in versions: dstdir = join(sitedir(version, package), root) if not exists(dstdir): os.makedirs(dstdir) relative_symlink(fpath1, join(dstdir, fn)) def share_2x(dir1, dir2, dc=None): """Move common files to pyshared and create symlinks in original locations.""" debian, package, path = dir2.split('/', 2) # dir1 starts with debian/packagename/usr/lib/pythonX.Y/*-packages/ dstdir = join(debian, package, 'usr/share/pyshared/', \ '/'.join(dir1.split('/')[6:])) if not exists(dstdir) and not islink(dir1): os.makedirs(dstdir) if dc is None: # guess/copy mode if not exists(dir2): os.makedirs(dir2) common_dirs = [] common_files = [] for i in os.listdir(dir1): subdir1 = join(dir1, i) if isdir(subdir1) and not islink(subdir1): common_dirs.append([i, None]) else: # directories with .so files will be blocked earlier common_files.append(i) elif islink(dir1): # skip this symlink in pyshared # (dpkg has problems with symlinks anyway) common_dirs = [] common_files = [] else: common_dirs = dc.subdirs.iteritems() common_files = dc.common_files # dircmp returns common names only, lets check files more carefully... common_files = cmpfiles(dir1, dir2, common_files, shallow=False)[0] for fn in common_files: if 'so' in fn.split('.'): # foo.so, bar.so.0.1.2, etc. # in unlikely case where extensions are exactly the same continue fpath1 = join(dir1, fn) fpath2 = join(dir2, fn) fpath3 = join(dstdir, fn) # do not touch symlinks created by previous loop or other tools if dc and not islink(fpath1): # replace with a link to pyshared if not exists(fpath3): os.rename(fpath1, fpath3) relative_symlink(fpath3, fpath1) elif fcmp(fpath3, fpath1, shallow=False): os.remove(fpath1) relative_symlink(fpath3, fpath1) if dc is None: # guess/copy mode if islink(fpath1): # ralative links will work as well, it's always the same level os.symlink(os.readlink(fpath1), fpath2) else: if exists(fpath3): # cannot share it, pyshared contains another copy fcopy(fpath1, fpath2) else: # replace with a link to pyshared os.rename(fpath1, fpath3) relative_symlink(fpath3, fpath1) relative_symlink(fpath3, fpath2) elif exists(fpath2) and exists(fpath3) and \ fcmp(fpath2, fpath3, shallow=False): os.remove(fpath2) relative_symlink(fpath3, fpath2) for dn, dc in common_dirs: share_2x(join(dir1, dn), join(dir2, dn), dc) ### PACKAGE DETAILS ############################################ def scan(package, dname=None, options=None): """Gather statistics about Python files in given package.""" r = {'requires.txt': set(), 'nsp.txt': set(), 'shebangs': set(), 'public_vers': set(), 'private_dirs': {}, 'compile': False, 'ext': set()} dbg_package = package.endswith('-dbg') if not dname: proot = "debian/%s" % package if dname is False: private_to_check = [] else: private_to_check = [i % package for i in ('usr/lib/%s', 'usr/lib/games/%s', 'usr/share/%s', 'usr/share/games/%s')] else: # scan private directory *only* dname = dname.strip('/') proot = join('debian', package, dname) private_to_check = [dname] for root, dirs, file_names in os.walk(proot): # ignore Python 3.X locations if '/usr/lib/python3' in root or\ '/usr/local/lib/python3' in root: # warn only once if root[root.find('/lib/python'):].count('/') == 2: log.warning('Python 3.x location detected, ' 'please use dh_python3: %s', root) continue bin_dir = private_dir = None public_dir = PUBLIC_DIR_RE.match(root) if public_dir: version = getver(public_dir.group(1)) if root.endswith('-packages'): r['public_vers'].add(version) else: # TODO: find a way to specify Python version private # extension was build for version = False for i in private_to_check: if root.startswith(join('debian', package, i)): private_dir = '/' + i break else: # i.e. not public_dir and not private_dir if len(root.split('/', 6)) < 6 and (\ root.endswith('/sbin') or root.endswith('/bin') or\ root.endswith('/usr/games')): # /(s)bin or /usr/(s)bin or /usr/games bin_dir = root # handle some EGG related data (.egg-info dirs) for name in dirs: if name.endswith('.egg-info'): if dbg_package and options.clean_dbg_pkg: rmtree(join(root, name)) dirs.remove(name) continue clean_name = clean_egg_name(name) if clean_name != name: log.info('renaming %s to %s', name, clean_name) os.rename(join(root, name), join(root, clean_name)) dirs[dirs.index(name)] = clean_name if root.endswith('.egg-info'): if 'requires.txt' in file_names: r['requires.txt'].add(join(root, 'requires.txt')) if 'namespace_packages.txt' in file_names: r['nsp.txt'].add(join(root, 'namespace_packages.txt')) continue # check files for fn in sorted(file_names): # sorted() to make sure .so files are handled before .so.foo fpath = join(root, fn) if not exists(fpath): # could be removed while handling .so symlinks if islink(fpath) and '.so.' in split(fpath)[-1]: # dangling symlink to (now removed/renamed) .so file # which wasn't removed yet (see test3's quux.so.0) log.info('removing symlink: %s', fpath) os.remove(fpath) continue fext = fn.rsplit('.', 1)[-1] if fext in ('pyc', 'pyo'): os.remove(fpath) continue if public_dir: if fext == 'so' and islink(fpath): dstfpath = fpath links = set() while islink(dstfpath): links.add(dstfpath) dstfpath = join(root, os.readlink(dstfpath)) if exists(dstfpath) and '.so.' in split(dstfpath)[-1]: # rename .so.$FOO symlinks, remove other ones for lpath in links: log.info('removing symlink: %s', lpath) os.remove(lpath) log.info('renaming %s to %s', dstfpath, fn) os.rename(dstfpath, fpath) if dbg_package and options.clean_dbg_pkg and \ fext not in ('so', 'h'): os.remove(join(root, fn)) continue elif private_dir: if exists(fpath): mode = os.stat(fpath)[ST_MODE] if mode & S_IXUSR or mode & S_IXGRP or mode & S_IXOTH: if (options.no_shebang_rewrite or \ fix_shebang(fpath, options.shebang)) and \ not options.ignore_shebangs: res = shebang2pyver(fpath) if res: r['private_dirs'].setdefault(private_dir, {})\ .setdefault('shebangs', set()).add(res) if public_dir or private_dir: if fext == 'so': so_version = so2pyver(join(root, fn)) if so_version: if public_dir: if version != so_version: log.error('extension linked to libpython%s ' 'and shipped in python%s\'s dist-' 'packages: %s', vrepr(so_version), vrepr(version), fn) exit(7) log.warn('public extension linked with ' 'libpython%s: %s', vrepr(so_version), fn) elif not version: version = so_version (r if public_dir else r['private_dirs'].setdefault(private_dir, {}))\ .setdefault('ext', set()).add(version) continue elif fext == 'py': (r if public_dir else r['private_dirs'].setdefault(private_dir, {}))\ ['compile'] = True continue # .egg-info files if fn.endswith('.egg-info'): clean_name = clean_egg_name(fn) if clean_name != fn: log.info('renaming %s to %s', fn, clean_name) os.rename(join(root, fn), join(root, clean_name)) continue # search for scripts in bin dirs if bin_dir: if (options.no_shebang_rewrite or \ fix_shebang(fpath, options.shebang)) and \ not options.ignore_shebangs: res = shebang2pyver(fpath) if res: r['shebangs'].add(res) if dbg_package and options.clean_dbg_pkg: # remove empty directories in -dbg packages proot = proot + '/usr/lib' for root, dirs, file_names in os.walk(proot, topdown=False): if '-packages/' in root and not file_names: try: os.rmdir(root) except Exception: pass log.debug("package %s details = %s", package, r) return r ################################################################ def main(): log.warn('Please add dh-python package to Build-Depends') usage = '%prog -p PACKAGE [-V [X.Y][-][A.B]] DIR [-X REGEXPR]\n' parser = OptionParser(usage, version='%prog 2.1', option_class=Option) parser.add_option('--no-guessing-versions', action='store_false', dest='guess_versions', default=True, help='disable guessing other supported Python versions') parser.add_option('--no-guessing-deps', action='store_false', dest='guess_deps', default=True, help='disable guessing dependencies') parser.add_option('--skip-private', action='store_true', default=False, help='don\'t check private directories') parser.add_option('-v', '--verbose', action='store_true', default=False, help='turn verbose mode on') # arch=False->arch:all only, arch=True->arch:any only, None->all of them parser.add_option('-i', '--indep', action='store_false', dest='arch', default=None, help='act on architecture independent packages') parser.add_option('-a', '-s', '--arch', action='store_true', dest='arch', help='act on architecture dependent packages') parser.add_option('-q', '--quiet', action='store_false', dest='verbose', help='be quiet') parser.add_option('-p', '--package', action='append', help='act on the package named PACKAGE') parser.add_option('-N', '--no-package', action='append', help='do not act on the specified package') parser.add_option('--compile-all', action='store_true', default=False, help='compile all files from given private directory in postinst, ' 'not just the ones provided by the package') parser.add_option('-V', type='version_range', dest='vrange', help='specify list of supported Python versions. ' +\ 'See pycompile(1) for examples') parser.add_option('-X', '--exclude', action='append', dest='regexpr', help='exclude items that match given REGEXPR. You may use this option ' 'multiple times to build up a list of things to exclude.') parser.add_option('--depends', action='append', help='translate given requirements into Debian dependencies ' 'and add them to ${python:Depends}. ' 'Use it for missing items in requires.txt.') parser.add_option('--recommends', action='append', help='translate given requirements into Debian ' 'dependencies and add them to ${python:Recommends}') parser.add_option('--suggests', action='append', help='translate given requirements into Debian ' 'dependencies and add them to ${python:Suggests}') parser.add_option('--namespace', action='append', dest='namespaces', help='recreate __init__.py files for given namespaces at install time') parser.add_option('--clean-pycentral', action='store_true', default=False, help='generate maintainer script that will remove pycentral files') parser.add_option('--shebang', help='use given command as shebang in scripts') parser.add_option('--ignore-shebangs', action='store_true', default=False, help='do not translate shebangs into Debian dependencies') parser.add_option('--ignore-namespace', action='store_true', default=False, help="ignore Egg's namespace_packages.txt file and --namespace option") parser.add_option('--no-dbg-cleaning', action='store_false', dest='clean_dbg_pkg', default=True, help='do not remove files from debug packages') parser.add_option('--no-shebang-rewrite', action='store_true', default=False, help='do not rewrite shebangs') # ignore some debhelper options: parser.add_option('-O', help=SUPPRESS_HELP) options, args = parser.parse_args(sys.argv[1:] + \ os.environ.get('DH_OPTIONS', '').split()) # regexpr option type is not used so lets check patterns here for pattern in options.regexpr or []: # fail now rather than at runtime try: pattern = re.compile(pattern) except Exception: log.error('regular expression is not valid: %s', pattern) exit(1) if not options.vrange and exists('debian/pyversions'): log.debug('parsing version range from debian/pyversions') with open('debian/pyversions') as fp: for line in fp: line = line.strip() if line and not line.startswith('#'): options.vrange = parse_vrange(line) break # disable PyDist if dh_pydeb is used if options.guess_deps: try: rules = open('debian/rules', 'r').read() except IOError: log.warning('cannot open debian/rules file') else: if re.search('\n\s*dh_pydeb', rules) or \ re.search('\n\s*dh\s+[^#]*--with[^#]+pydeb', rules): log.warning('dh_pydeb detected, PyDist feature disabled') options.guess_deps = False if not args: private_dir = None else: private_dir = args[0] if not private_dir.startswith('/'): # handle usr/share/foo dirs (without leading slash) private_dir = '/' + private_dir # TODO: support more than one private dir at the same time (see :meth:scan) if options.skip_private: private_dir = False if options.verbose or os.environ.get('DH_VERBOSE') == '1': log.setLevel(logging.DEBUG) log.debug('argv: %s', sys.argv) log.debug('options: %s', options) log.debug('args: %s', args) dh = DebHelper(options) if not options.vrange and dh.python_version: options.vrange = parse_pycentral_vrange(dh.python_version) for package, pdetails in dh.packages.iteritems(): if options.arch is False and pdetails['arch'] != 'all' or \ options.arch is True and pdetails['arch'] == 'all': continue log.debug('processing package %s...', package) if not private_dir: if not pyinstall(package, options.vrange): exit(4) if not pyremove(package, options.vrange): exit(5) fix_locations(package) stats = scan(package, private_dir, options) if not private_dir: share(package, stats, options) pyshared_dir = "debian/%s/usr/share/pyshared/" % package if not stats['public_vers'] and exists(pyshared_dir): create_public_links(pyshared_dir, options.vrange) stats['public_vers'] = get_requested_versions(options.vrange) stats['compile'] = True dependencies = Dependencies(package) dependencies.parse(stats, options) if stats['public_vers']: dh.addsubstvar(package, 'python:Versions', \ ', '.join(sorted(vrepr(stats['public_vers'])))) ps = package.split('-', 1) if len(ps) > 1 and ps[0] == 'python': dh.addsubstvar(package, 'python:Provides', \ ', '.join("python%s-%s" % (i, ps[1])\ for i in sorted(vrepr(stats['public_vers'])))) pyclean_added = False # invoke pyclean only once in maintainer script if stats['compile']: if options.clean_pycentral: dh.autoscript(package, 'preinst', 'preinst-pycentral-clean', '') dh.autoscript(package, 'postinst', 'postinst-pycompile', '') dh.autoscript(package, 'prerm', 'prerm-pyclean', '') pyclean_added = True for pdir, details in stats['private_dirs'].iteritems(): if not details.get('compile'): continue if not pyclean_added: dh.autoscript(package, 'prerm', 'prerm-pyclean', '') pyclean_added = True args = pdir ext_for = details.get('ext') if ext_for is None: # no extension shebangs = list(v for i, v in details.get('shebangs', []) if v) if not options.ignore_shebangs and len(shebangs) == 1: # only one version from shebang args += " -V %s" % vrepr(shebangs[0]) elif options.vrange and options.vrange != (None, None): args += " -V %s" % vrange_str(options.vrange) elif False in ext_for: # at least one extension's version not detected if options.vrange and '-' not in vrange_str(options.vrange): ver = vrange_str(options.vrange) else: # try shebang or default Python version ver = (list(v for i, v in details.get('shebangs', []) if v) or [None])[0] or DEFAULT ver = vrepr(ver) dependencies.depend("python%s" % ver) args += " -V %s" % vrepr(ver) else: version = ext_for.pop() args += " -V %s" % vrepr(version) dependencies.depend("python%d.%d" % version) for pattern in options.regexpr or []: args += " -X '%s'" % pattern.replace("'", r"'\''") dh.autoscript(package, 'postinst', 'postinst-pycompile', args) dependencies.export_to(dh) pydist_file = join('debian', "%s.pydist" % package) if exists(pydist_file): if not validate_pydist(pydist_file): log.warning("%s.pydist file is invalid", package) else: dstdir = join('debian', package, 'usr/share/python/dist/') if not exists(dstdir): os.makedirs(dstdir) fcopy(pydist_file, join(dstdir, package)) # namespace feature - recreate __init__.py files at install time if options.ignore_namespace: nsp = None else: nsp = ns.parse(stats['nsp.txt'], options.namespaces) # note that pycompile/pyclean is already added to maintainer scripts # and it should remain there even if __init__.py was the only .py file if nsp: try: nsp = ns.remove_from_package(package, nsp, stats['public_vers']) except (IOError, OSError), e: log.error('cannot remove __init__.py from package: %s', e) exit(6) if nsp: dstdir = join('debian', package, 'usr/share/python/ns/') if not exists(dstdir): os.makedirs(dstdir) with open(join(dstdir, package), 'a') as fp: fp.writelines("%s\n" % i for i in nsp) pyshared = join('debian', package, 'usr/share/pyshared/') if isdir(pyshared) and not os.listdir(pyshared): # remove empty pyshared directory os.rmdir(pyshared) dh.save() if __name__ == '__main__': main() python-defaults-2.7.12/pyclean.rst0000664000000000000000000000102412254623031014001 0ustar ========= pyclean ========= --------------------------- removes .pyc and .pyo files --------------------------- :Manual section: 1 :Author: Piotr Ożarowski, 2012-201 SYNOPSIS ======== pyclean [-p PACKAGE | DIR_OR_FILE] OPTIONS ======= --version show program's version number and exit -h, --help show this help message and exit -v, --verbose turn verbose more one -q, --quiet be quiet -p PACKAGE, --package=PACKAGE specify Debian package name to clean (combining with DIR_OR_FILE will additionally limit list of files) python-defaults-2.7.12/debpython/0000775000000000000000000000000012374331373013623 5ustar python-defaults-2.7.12/debpython/depends.py0000664000000000000000000001600212254623031015606 0ustar # -*- coding: UTF-8 -*- # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import logging from debpython.pydist import parse_pydep, guess_dependency from debpython.version import DEFAULT, SUPPORTED, debsorted, vrepr, vrange_str # minimum version required for pycompile/pyclean MINPYCDEP = 'python:any (>= 2.6.6-7~)' log = logging.getLogger(__name__) class Dependencies(object): """Store relations (dependencies, etc.) between packages.""" def __init__(self, package): self.package = package self.depends = [] self.recommends = [] self.suggests = [] self.enhances = [] self.breaks = [] self.rtscripts = [] def export_to(self, dh): """Fill in debhelper's substvars.""" for i in self.depends: dh.addsubstvar(self.package, 'python:Depends', i) for i in self.recommends: dh.addsubstvar(self.package, 'python:Recommends', i) for i in self.suggests: dh.addsubstvar(self.package, 'python:Suggests', i) for i in self.enhances: dh.addsubstvar(self.package, 'python:Enhances', i) for i in self.breaks: dh.addsubstvar(self.package, 'python:Breaks', i) for i in self.rtscripts: dh.add_rtupdate(self.package, i) def __str__(self): return "D=%s; R=%s; S=%s; E=%s, B=%s; RT=%s" % (self.depends, \ self.recommends, self.suggests, self.enhances, \ self.breaks, self.rtscripts) def depend(self, value): if value and value not in self.depends: self.depends.append(value) def recommend(self, value): if value and value not in self.recommends: self.recommends.append(value) def suggest(self, value): if value and value not in self.suggests: self.suggests.append(value) def enhance(self, value): if value and value not in self.enhances: self.enhances.append(value) def break_(self, value): if value and value not in self.breaks: self.breaks.append(value) def rtscript(self, value): if value not in self.rtscripts: self.rtscripts.append(value) def parse(self, stats, options): log.debug('generating dependencies for package %s', self.package) pub_vers = sorted(stats['public_vers'].union(stats['ext'])) if pub_vers: dbgpkg = self.package.endswith('-dbg') tpl = 'python-dbg' if dbgpkg else 'python' minv = pub_vers[0] maxv = pub_vers[-1] # generating "python2.X | python2.Y | python2.Z" dependencies # disabled (see #625740): #if dbgpkg: # tpl2 = 'python%d.%d-dbg' #else: # tpl2 = 'python%d.%d' #self.depend(' | '.join(tpl2 % i for i in debsorted(pub_vers))) # additional Depends to block python package transitions if minv <= DEFAULT: self.depend("%s (>= %d.%d)" % \ (tpl, minv[0], minv[1])) if maxv >= DEFAULT: self.depend("%s (<< %d.%d)" % \ (tpl, maxv[0], maxv[1] + 1)) # make sure pycompile binary is available if stats['compile']: self.depend(MINPYCDEP) for interpreter, version in stats['shebangs']: self.depend("%s:any" % interpreter) for private_dir, details in stats['private_dirs'].iteritems(): versions = list(v for i, v in details.get('shebangs', []) if v) for v in versions: if v in SUPPORTED: self.depend("python%d.%d:any" % v) else: log.info('dependency on python%s (from shebang) ignored' ' - it\'s not supported anymore', vrepr(v)) # /usr/bin/python shebang → add python to Depends if any(True for i, v in details.get('shebangs', []) if v is None): self.depend('python:any') if details.get('compile', False): self.depend(MINPYCDEP) args = '' vr = options.vrange if len(versions) == 1: # only one version from shebang args += "-V %s" % vrepr(versions[0]) elif vr: # if there are no hardcoded versions in shebang or there # are scripts for different Python versions: compile with # default Python version (or the one requested via X-P-V) args += "-V %s" % vrange_str(vr) if vr == (None, None): pass elif vr[0] == vr[1]: self.depend("python%s:any" % vrepr(vr[0])) else: if vr[0]: # minimum version specified self.depend("python:any (>= %s)" % vrepr(vr[0])) if vr[1]: # maximum version specified self.depend("python:any (<< %d.%d)" % \ (vr[1][0], vr[1][1] + 1)) for pattern in options.regexpr or []: args += " -X '%s'" % pattern.replace("'", r"'\''") self.rtscript((private_dir, args)) if options.guess_deps: for fn in stats['requires.txt']: # TODO: should options.recommends and options.suggests be # removed from requires.txt? for i in parse_pydep(fn): self.depend(i) # add dependencies from --depends for item in options.depends or []: self.depend(guess_dependency(item)) # add dependencies from --recommends for item in options.recommends or []: self.recommend(guess_dependency(item)) # add dependencies from --suggests for item in options.suggests or []: self.suggest(guess_dependency(item)) log.debug(self) python-defaults-2.7.12/debpython/option.py0000664000000000000000000000353612057417145015514 0ustar # -*- coding: UTF-8 -*- # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import re import optparse from copy import copy from debpython.version import parse_vrange def parse_version_range(option, opt, value): try: return parse_vrange(value) except ValueError: raise optparse.OptionValueError("version range is invalid: %s" % value) def compile_regexpr(option, opt, value): try: pattern = re.compile(value) except Exception: raise optparse.OptionValueError('regular expression is not valid') return pattern class Option(optparse.Option): TYPES = optparse.Option.TYPES + ('version_range', 'regexpr') TYPE_CHECKER = copy(optparse.Option.TYPE_CHECKER) TYPE_CHECKER['version_range'] = parse_version_range TYPE_CHECKER['regexpr'] = compile_regexpr python-defaults-2.7.12/debpython/debhelper.py0000664000000000000000000002117612057417145016136 0ustar # -*- coding: UTF-8 -*- # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import logging from os import makedirs, chmod from os.path import exists, join, dirname log = logging.getLogger(__name__) class DebHelper(object): """Reinvents the wheel / some dh functionality (Perl is ugly ;-P)""" def __init__(self, options): self.options = options self.packages = {} self.python_version = None source_section = True binary_package = None pkgs = options.package skip_pkgs = options.no_package try: fp = open('debian/control', 'r') except IOError: raise Exception('cannot find debian/control file') xspv = xpv = False for line in fp: if not line.strip(): source_section = False binary_package = None continue if binary_package: if binary_package.startswith('python3'): continue if pkgs and binary_package not in pkgs: continue if skip_pkgs and binary_package in skip_pkgs: continue if line.startswith('Architecture:'): arch = line[13:].strip() # TODO: if arch doesn't match current architecture: #del self.packages[binary_package] self.packages[binary_package]['arch'] = arch continue elif line.startswith('Package:'): binary_package = line[8:].strip() if binary_package.startswith('python3'): log.debug('skipping Python 3.X package: %s', binary_package) continue if pkgs and binary_package not in pkgs: continue if skip_pkgs and binary_package in skip_pkgs: continue self.packages[binary_package] = {'substvars': {}, 'autoscripts': {}, 'rtupdates': [], 'arch': 'any'} elif line.startswith('Source:'): self.source_name = line[7:].strip() elif source_section: if line.lower().startswith('xs-python-version:'): xspv = True if not self.python_version: self.python_version = line[18:].strip() if line.lower().startswith('x-python-version:'): xpv = True self.python_version = line[17:].strip() if xspv and xpv: log.error('Please remove XS-Python-Version from debian/control') log.debug('source=%s, binary packages=%s', self.source_name, \ self.packages.keys()) def addsubstvar(self, package, name, value): """debhelper's addsubstvar""" self.packages[package]['substvars'].setdefault(name, []).append(value) def autoscript(self, package, when, template, args): """debhelper's autoscript""" self.packages[package]['autoscripts'].setdefault(when, {})\ .setdefault(template, []).append(args) def add_rtupdate(self, package, value): self.packages[package]['rtupdates'].append(value) def save_autoscripts(self): for package, settings in self.packages.iteritems(): autoscripts = settings.get('autoscripts') if not autoscripts: continue for when, templates in autoscripts.iteritems(): fn = "debian/%s.%s.debhelper" % (package, when) if exists(fn): data = open(fn, 'r').read() else: data = '' new_data = '' for tpl_name, args in templates.iteritems(): for i in args: # try local one first (useful while testing dh_python2) fpath = join(dirname(__file__), '..', "autoscripts/%s" % tpl_name) if not exists(fpath): fpath = "/usr/share/debhelper/autoscripts/%s" % tpl_name tpl = open(fpath, 'r').read() if self.options.compile_all and args: # TODO: should args be checked to contain dir name? tpl = tpl.replace('#PACKAGE#', '') else: tpl = tpl.replace('#PACKAGE#', package) tpl = tpl.replace('#ARGS#', i) if tpl not in data and tpl not in new_data: new_data += "\n%s" % tpl if new_data: data += "\n# Automatically added by dh_python2:" +\ "%s\n# End automatically added section\n" % new_data fp = open(fn, 'w') fp.write(data) fp.close() def save_substvars(self): for package, settings in self.packages.iteritems(): substvars = settings.get('substvars') if not substvars: continue fn = "debian/%s.substvars" % package if exists(fn): data = open(fn, 'r').read() else: data = '' for name, values in substvars.iteritems(): p = data.find("%s=" % name) if p > -1: # parse the line and remove it from data e = data[p:].find('\n') line = data[p + len("%s=" % name):\ p + e if e > -1 else None] items = [i.strip() for i in line.split(',') if i] if e > -1 and data[p + e:].strip(): data = "%s\n%s" % (data[:p], data[p + e:]) else: data = data[:p] else: items = [] for j in values: if j not in items: items.append(j) if items: if data: data += '\n' data += "%s=%s\n" % (name, ', '.join(items)) data = data.replace('\n\n', '\n') if data: fp = open(fn, 'w') fp.write(data) fp.close() def save_rtupdate(self): for package, settings in self.packages.iteritems(): pkg_arg = '' if self.options.compile_all else "-p %s" % package values = settings.get('rtupdates') if not values: continue d = "debian/%s/usr/share/python/runtime.d" % package if not exists(d): makedirs(d) fn = "%s/%s.rtupdate" % (d, package) if exists(fn): data = open(fn, 'r').read() else: data = "#! /bin/sh\nset -e" for dname, args in values: cmd = 'if [ "$1" = rtupdate ]; then' +\ "\n\tpyclean %s %s" % (pkg_arg, dname) +\ "\n\tpycompile %s %s %s\nfi" % (pkg_arg, args, dname) if cmd not in data: data += "\n%s" % cmd if data: fp = open(fn, 'w') fp.write(data) fp.close() chmod(fn, 0755) def save(self): self.save_substvars() self.save_autoscripts() self.save_rtupdate() python-defaults-2.7.12/debpython/files.py0000664000000000000000000000575612057417145015314 0ustar # -*- coding: UTF-8 -*- # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import logging from os import walk from os.path import abspath, isfile, join from subprocess import Popen, PIPE log = logging.getLogger(__name__) def from_directory(dname, extensions=('.py',)): """Generate *.py file names available in given directory.""" extensions = tuple(extensions) # .endswith doesn't like list if isinstance(dname, (list, tuple)): for item in dname: for fn in from_directory(item): yield fn elif isfile(dname) and dname.endswith(extensions): yield dname else: for root, dirs, file_names in walk(abspath(dname)): for fn in file_names: if fn.endswith(extensions): yield join(root, fn) def from_package(package_name, extensions=('.py',)): """Generate *.py file names available in given package.""" extensions = tuple(extensions) # .endswith doesn't like list process = Popen("/usr/bin/dpkg -L %s" % package_name,\ shell=True, stdout=PIPE) stdout, stderr = process.communicate() if process.returncode != 0: raise Exception("cannot get content of %s" % package_name) for line in stdout.splitlines(): if line.endswith(extensions): yield line def filter_directory(files, dname): """Generate *.py file names that match given directory.""" for fn in files: if fn.startswith(dname): yield fn def filter_public(files, versions): """Generate *.py file names that match given versions.""" versions_str = set("%d.%d" % i for i in versions) for fn in files: if fn.startswith('/usr/lib/python') and \ fn[15:18] in versions_str: yield fn def filter_out_ext(files, extensions): """Removes files with matching extensions from given generator.""" for fn in files: if not fn.endswith(extensions): yield fn python-defaults-2.7.12/debpython/pydist.py0000664000000000000000000002425012374331373015514 0ustar # -*- coding: UTF-8 -*- # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from __future__ import with_statement import logging import os import re from os.path import exists, isdir, join from string import maketrans from subprocess import PIPE, Popen from debpython.version import vrepr, getver, get_requested_versions from debpython.tools import memoize log = logging.getLogger(__name__) PUBLIC_DIR_RE = re.compile(r'.*?/usr/lib/python(\d.\d+)/(site|dist)-packages') PYDIST_RE = re.compile(r""" (?P[A-Za-z][A-Za-z0-9_.\-]*) # Python distribution name \s* (?P(?:-?\d\.\d+(?:-(?:\d\.\d+)?)?)?) # version range \s* (?P(?:[a-z][^;]*)?) # Debian dependency (?: # optional upstream version -> Debian version translator ;\s* (?PPEP386)? # PEP-386 mode \s* (?P(?:s|tr|y).*)? # translator rules )? """, re.VERBOSE) REQUIRES_RE = re.compile(r''' (?P[A-Za-z][A-Za-z0-9_.]*) # Python distribution name \s* (?P(?:\[[^\]]*\])?) # ignored for now \s* (?: # optional minimum/maximum version (?P<=?|>=?|==|!=) \s* (?P(\w|[-.])+) )? ''', re.VERBOSE) def validate(fpath): """Check if pydist file looks good.""" with open(fpath) as fp: for line in fp: line = line.strip('\r\n') if line.startswith('#') or not line: continue if not PYDIST_RE.match(line): log.error('invalid pydist data in file %s: %s', \ fpath.rsplit('/', 1)[-1], line) return False return True @memoize def load(dname='/usr/share/python/dist/', fname='debian/pydist-overrides', fbname='/usr/share/python/dist_fallback'): """Load iformation about installed Python distributions.""" if exists(fname): to_check = [fname] # first one! else: to_check = [] if isdir(dname): to_check.extend(join(dname, i) for i in os.listdir(dname)) if exists(fbname): # fall back generated at python-defaults build time to_check.append(fbname) # last one! result = {} for fpath in to_check: with open(fpath) as fp: for line in fp: line = line.strip('\r\n') if line.startswith('#') or not line: continue dist = PYDIST_RE.search(line) if not dist: raise Exception('invalid pydist line: %s (in %s)' % (line, fpath)) dist = dist.groupdict() name = safe_name(dist['name']) dist['versions'] = get_requested_versions(dist['vrange']) dist['dependency'] = dist['dependency'].strip() if dist['rules']: dist['rules'] = dist['rules'].split(';') else: dist['rules'] = [] result.setdefault(name, []).append(dist) return result def guess_dependency(req, version=None): log.debug('trying to guess dependency for %s (python=%s)', req, vrepr(version) if version else None) if isinstance(version, basestring): version = getver(version) # some upstreams have weird ideas for distribution name... name, rest = re.compile('([^!><= \[]+)(.*)').match(req).groups() req = safe_name(name) + rest data = load() req_d = REQUIRES_RE.match(req) if not req_d: log.info('please ask dh_python2 author to fix REQUIRES_RE ' 'or your upstream author to fix requires.txt') raise Exception('requirement is not valid: %s' % req) req_d = req_d.groupdict() name = req_d['name'] details = data.get(name.lower()) if details: for item in details: if version and version not in item.get('versions', version): # rule doesn't match version, try next one continue if not item['dependency']: return # this requirement should be ignored if item['dependency'].endswith(')'): # no need to translate versions if version is hardcoded in # Debian dependency return item['dependency'] if req_d['version'] and (item['standard'] or item['rules']) and\ req_d['operator'] not in (None, '=='): v = _translate(req_d['version'], item['rules'], item['standard']) return "%s (%s %s)" % (item['dependency'], req_d['operator'], v) else: return item['dependency'] # try dpkg -S query = "'*/%s-?*\.egg-info'" % ci_regexp(safe_name(name)) # TODO: .dist-info if version: query = "%s | grep '/python%s/\|/pyshared/'" % \ (query, vrepr(version)) else: query = "%s | grep '/python2\../\|/pyshared/'" % query log.debug("invoking dpkg -S %s", query) process = Popen("/usr/bin/dpkg -S %s" % query, \ shell=True, stdout=PIPE, stderr=PIPE) stdout, stderr = process.communicate() if process.returncode == 0: result = set() for line in stdout.split('\n'): if not line.strip(): continue result.add(line.split(':')[0]) if len(result) > 1: log.error('more than one package name found for %s dist', name) else: return result.pop() else: log.debug('dpkg -S did not find package for %s: %s', name, stderr) # fall back to python-distname pname = sensible_pname(name) log.info('Cannot find installed package that provides %s. ' 'Using %s as package name. Please add "%s correct_package_name" ' 'line to debian/pydist-overrides to override it if this is incorrect.', name, pname, safe_name(name)) return pname def parse_pydep(fname): public_dir = PUBLIC_DIR_RE.match(fname) if public_dir: ver = public_dir.group(1) else: ver = None result = [] modified = optional_section = False processed = [] with open(fname, 'r') as fp: lines = [i.strip() for i in fp.readlines()] for line in lines: if not line or line.startswith('#'): processed.append(line) continue if line.startswith('['): optional_section = True if optional_section: processed.append(line) continue dependency = guess_dependency(line, ver) if dependency: result.append(dependency) if 'setuptools' in line.lower(): # TODO: or dependency in recommends\ # or dependency in suggests modified = True else: processed.append(line) else: processed.append(line) if modified: with open(fname, 'w') as fp: fp.writelines(i + '\n' for i in processed) return result def safe_name(name): """Emulate distribute's safe_name.""" return re.compile('[^A-Za-z0-9.]+').sub('_', name).lower() def sensible_pname(egg_name): """Guess Debian package name from Egg name.""" egg_name = safe_name(egg_name).replace('_', '-') if egg_name.startswith('python-'): egg_name = egg_name[7:] return "python-%s" % egg_name.lower() def ci_regexp(name): """Return case insensitive dpkg -S regexp.""" return ''.join("[%s%s]" % (i.upper(), i) if i.isalpha() else i for i in name.lower()) PRE_VER_RE = re.compile(r'[-.]?(alpha|beta|rc|dev|a|b|c)') GROUP_RE = re.compile(r'\$(\d+)') def _pl2py(pattern): """Convert Perl RE patterns used in uscan to Python's >>> print _pl2py('foo$3') foo\g<3> """ return GROUP_RE.sub(r'\\g<\1>', pattern) def _translate(version, rules, standard): """Translate Python version into Debian one. >>> _translate('1.C2betac', ['s/c//gi'], None) '1.2beta' >>> _translate('5-fooa1.2beta3-fooD', ... ['s/^/1:/', 's/-foo//g', 's:([A-Z]):+$1:'], 'PEP386') '1:5~a1.2~beta3+D' >>> _translate('x.y.x.z', ['tr/xy/ab/', 'y,z,Z,'], None) 'a.b.a.Z' """ for rule in rules: # uscan supports s, tr and y operations if rule.startswith(('tr', 'y')): # Note: no support for escaped separator in the pattern pos = 1 if rule.startswith('y') else 2 tmp = rule[pos + 1:].split(rule[pos]) version = version.translate(maketrans(tmp[0], tmp[1])) elif rule.startswith('s'): # uscan supports: g, u and x flags tmp = rule[2:].split(rule[1]) pattern = re.compile(tmp[0]) count = 1 if tmp[2:]: flags = tmp[2] if 'g' in flags: count = 0 if 'i' in flags: pattern = re.compile(tmp[0], re.I) version = pattern.sub(_pl2py(tmp[1]), version, count) else: log.warn('unknown rule ignored: %s', rule) if standard == 'PEP386': version = PRE_VER_RE.sub('~\g<1>', version) return version python-defaults-2.7.12/debpython/tools.py0000664000000000000000000002362512057417145015345 0ustar # -*- coding: UTF-8 -*- # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from __future__ import with_statement import codecs import logging import os import re from cPickle import dumps from glob import glob from os.path import exists, isdir, join, split from shutil import rmtree from subprocess import PIPE, Popen from debpython.version import RANGE_PATTERN, getver, get_requested_versions log = logging.getLogger(__name__) EGGnPTH_RE = re.compile(r'(.*?)(-py\d\.\d(?:-[^.]*)?)?(\.egg-info|\.pth)$') SHEBANG_RE = re.compile(r'^#!\s*(.*?/bin/.*?)(python(2\.\d+)?(?:-dbg)?)(?:\s(.*))?[$\r\n].*') SHAREDLIB_RE = re.compile(r'NEEDED.*libpython(\d\.\d)') INSTALL_RE = re.compile(r""" (?P.+?) # file pattern (?:\s+ # optional Python module name: (?P[A-Za-z][A-Za-z0-9_.]*)? )? \s* # optional version range: (?P%s)?$ """ % RANGE_PATTERN, re.VERBOSE) REMOVE_RE = re.compile(r""" (?P.+?) # file pattern \s* # optional version range: (?P%s)?$ """ % RANGE_PATTERN, re.VERBOSE) def sitedir(version, package=None, gdb=False): """Return path to site-packages directory. >>> sitedir((2, 5)) '/usr/lib/python2.5/site-packages/' >>> sitedir((2, 7), 'python-foo', True) 'debian/python-foo/usr/lib/debug/usr/lib/python2.7/dist-packages/' """ if isinstance(version, basestring): version = tuple(int(i) for i in version.split('.')) if version >= (2, 6): path = "/usr/lib/python%d.%d/dist-packages/" % version else: path = "/usr/lib/python%d.%d/site-packages/" % version if gdb: path = "/usr/lib/debug%s" % path if package: path = "debian/%s%s" % (package, path) return path def relpath(target, link): """Return relative path. >>> relpath('/usr/share/python-foo/foo.py', '/usr/bin/foo', ) '../share/python-foo/foo.py' """ t = target.split('/') l = link.split('/') while l[0] == t[0]: del l[0], t[0] return '/'.join(['..'] * (len(l) - 1) + t) def relative_symlink(target, link): """Create relative symlink.""" return os.symlink(relpath(target, link), link) def fix_shebang(fpath, replacement=None): """Normalize file's shebang. :param replacement: new shebang command (path to interpreter and options) """ try: with open(fpath) as fp: fcontent = fp.readlines() if not fcontent: log.debug('fix_shebang: ignoring empty file: %s', fpath) return None except IOError: log.error('cannot open %s', fpath) return False match = SHEBANG_RE.match(fcontent[0]) if not match: return None if not replacement: path, interpreter, version, argv = match.groups() if path != '/usr/bin': # f.e. /usr/local/* or */bin/env replacement = "/usr/bin/%s" % interpreter if interpreter == 'python2': replacement = '/usr/bin/python' if replacement and argv: replacement += " %s" % argv if replacement: log.info('replacing shebang in %s (%s)', fpath, fcontent[0]) # do not catch IOError here, the file is zeroed at this stage so it's # better to fail dh_python2 with open(fpath, 'w') as fp: fp.write("#! %s\n" % replacement) fp.writelines(fcontent[1:]) return True def shebang2pyver(fpath): """Check file's shebang. :rtype: tuple :returns: pair of Python interpreter string and Python version """ try: with open(fpath) as fp: data = fp.read(32) match = SHEBANG_RE.match(data) if not match: return None res = match.groups() if res[1:3] != (None, None): if res[2]: return res[1], getver(res[2]) return res[1], None except IOError: log.error('cannot open %s', fpath) def so2pyver(fpath): """Return libpython version file is linked to or None. :rtype: tuple :returns: Python version """ cmd = "readelf -Wd '%s'" % fpath process = Popen(cmd, stdout=PIPE, shell=True) match = SHAREDLIB_RE.search(process.stdout.read()) if match: return getver(match.groups()[0]) def clean_egg_name(name): """Remove Python version and platform name from Egg files/dirs. >>> clean_egg_name('python_pipeline-0.1.3_py3k-py3.1.egg-info') 'python_pipeline-0.1.3_py3k.egg-info' >>> clean_egg_name('Foo-1.2-py2.7-linux-x86_64.egg-info') 'Foo-1.2.egg-info' """ match = EGGnPTH_RE.match(name) if match and match.group(2) is not None: return ''.join(match.group(1, 3)) return name class memoize(object): def __init__(self, func): self.func = func self.cache = {} def __call__(self, *args, **kwargs): key = dumps((args, kwargs)) if key not in self.cache: self.cache[key] = self.func(*args, **kwargs) return self.cache[key] def pyinstall(package, vrange): """Install local files listed in pkg.pyinstall files as public modules.""" status = True srcfpath = "./debian/%s.pyinstall" % package if not exists(srcfpath): return status versions = get_requested_versions(vrange) for line in codecs.open(srcfpath, encoding='utf-8'): if not line or line.startswith('#'): continue details = INSTALL_RE.match(line) if not details: status = False log.warn('%s.pyinstall: unrecognized line: %s', package, line) continue details = details.groupdict() if details['module']: details['module'] = details['module'].replace('.', '/') myvers = versions & get_requested_versions(details['vrange']) if not myvers: log.debug('%s.pyinstall: no matching versions for line %s', package, line) continue files = glob(details['pattern']) if not files: status = False log.error('%s.pyinstall: file not found: %s', package, details['pattern']) continue for fpath in files: fpath = fpath.lstrip('/.') if details['module']: dstname = join(details['module'], split(fpath)[1]) elif fpath.startswith('debian/'): dstname = fpath[7:] else: dstname = fpath for version in myvers: dstfpath = join(sitedir(version, package), dstname) dstdir = split(dstfpath)[0] if not exists(dstdir): try: os.makedirs(dstdir) except Exception: log.error('cannot create %s directory', dstdir) return False if exists(dstfpath): try: os.remove(dstfpath) except Exception: status = False log.error('cannot replace %s file', dstfpath) continue try: os.link(fpath, dstfpath) except Exception: status = False log.error('cannot copy %s file to %s', fpath, dstdir) return status def pyremove(package, vrange): """Remove public modules listed in pkg.pyremove file.""" status = True srcfpath = "./debian/%s.pyremove" % package if not exists(srcfpath): return status versions = get_requested_versions(vrange) for line in codecs.open(srcfpath, encoding='utf-8'): if not line or line.startswith('#'): continue details = REMOVE_RE.match(line) if not details: status = False log.warn('%s.pyremove: unrecognized line: %s', package, line) continue details = details.groupdict() myvers = versions & get_requested_versions(details['vrange']) if not myvers: log.debug('%s.pyremove: no matching versions for line %s', package, line) continue for version in myvers: files = glob(sitedir(version, package) + details['pattern']) if not files: log.debug('%s.pyremove: nothing to remove: python%d.%d, %s', package, version, details['pattern']) continue for fpath in files: if isdir(fpath): try: rmtree(fpath) except Exception, e: status = False log.error(e) else: try: os.remove(fpath) except (IOError, OSError), e: status = False log.error(e) return status python-defaults-2.7.12/debpython/__init__.py0000664000000000000000000000000012057417145015722 0ustar python-defaults-2.7.12/debpython/version.py0000664000000000000000000002302512254623031015654 0ustar # -*- coding: UTF-8 -*- # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import logging import re from ConfigParser import SafeConfigParser from os import environ from os.path import exists, dirname, join from types import GeneratorType # will be overriden via debian_defaults file few lines later SUPPORTED = [(2, 7),] DEFAULT = (2, 7) RANGE_PATTERN = r'(-)?(\d\.\d+)(?:(-)(\d\.\d+)?)?' RANGE_RE = re.compile(RANGE_PATTERN) log = logging.getLogger(__name__) # try to read debian_defaults and get a list of supported Python versions and # the default one from there _supported = environ.get('DEBPYTHON_SUPPORTED') _default = environ.get('DEBPYTHON_DEFAULT') if not _supported or not _default: _config = SafeConfigParser() _config.read('/usr/share/python/debian_defaults') if not _default: _default = _config.get('DEFAULT', 'default-version')[6:] if not _supported: _supported = _config.get('DEFAULT', 'supported-versions')\ .replace('python', '') try: DEFAULT = tuple(int(i) for i in _default.split('.')) except Exception: log.exception('cannot read debian_defaults') try: SUPPORTED = tuple(tuple(int(j) for j in i.strip().split('.')) for i in _supported.split(',')) except Exception: log.exception('cannot read debian_defaults') def get_requested_versions(vrange=None, available=None): """Return a set of requested and supported Python versions. :param available: if set to `True`, return installed versions only, if set to `False`, return requested versions that are not installed. By default returns all requested versions. :type available: bool >>> sorted(get_requested_versions([(2, 5), (3, 0)])) [(2, 7)] >>> sorted(get_requested_versions('')) == sorted(SUPPORTED) True >>> sorted(get_requested_versions([None, None])) == sorted(SUPPORTED) True >>> get_requested_versions([(5, 0), None]) set([]) """ if isinstance(vrange, basestring): vrange = parse_vrange(vrange) if not vrange or list(vrange) == [None, None]: versions = set(SUPPORTED) else: minv = (0, 0) if vrange[0] is None else vrange[0] maxv = (99, 99) if vrange[1] is None else vrange[1] if minv == maxv: versions = set((minv,) if minv in SUPPORTED else tuple()) else: versions = set(v for v in SUPPORTED if minv <= v < maxv) if available: versions = set(v for v in versions if exists("/usr/bin/python%d.%d" % v)) elif available is False: versions = set(v for v in versions if not exists("/usr/bin/python%d.%d" % v)) return versions def parse_vrange(value): """Return minimum and maximum Python version from given range. >>> parse_vrange('2.4-') ((2, 4), None) >>> parse_vrange('2.4-2.6') ((2, 4), (2, 6)) >>> parse_vrange('2.4-3.0') ((2, 4), (3, 0)) >>> parse_vrange('-2.7') (None, (2, 7)) >>> parse_vrange('2.5') ((2, 5), (2, 5)) >>> parse_vrange('') == parse_vrange('-') == (None, None) True """ if value in ('', '-'): return None, None match = RANGE_RE.match(value) if not match: raise ValueError("version range is invalid: %s" % value) groups = match.groups() if list(groups).count(None) == 3: # only one version is allowed minv = tuple(int(i) for i in groups[1].split('.')) return minv, minv minv = maxv = None if groups[0]: # maximum version only maxv = groups[1] else: minv = groups[1] maxv = groups[3] minv = tuple(int(i) for i in minv.split('.')) if minv else None maxv = tuple(int(i) for i in maxv.split('.')) if maxv else None if maxv and minv and minv > maxv: raise ValueError("version range is invalid: %s" % value) return minv, maxv def parse_pycentral_vrange(value): """Parse XS-Python-Version. >>> parse_pycentral_vrange('current') == (DEFAULT, DEFAULT) True >>> parse_pycentral_vrange('all') (None, None) >>> parse_pycentral_vrange('all, >= 2.4') ((2, 4), None) >>> parse_pycentral_vrange('all, << 3.0') (None, (3, 0)) >>> parse_pycentral_vrange('2.6') ((2, 6), (2, 6)) >>> parse_pycentral_vrange('2.5, 2.6') ((2, 5), None) >>> parse_pycentral_vrange('>= 2.6.3') ((2, 6), None) """ get = lambda x: get_requested_versions(parse_vrange(x)) current = False minv = maxv = None hardcoded = set() for item in value.split(','): item = item.strip() if item == 'all': continue elif item == 'current': current = True continue match = re.match('>=\s*([\d\.]+)', item) if match: minv = "%.3s" % match.group(1) continue match = re.match('<<\s*([\d\.]+)', item) if match: maxv = "%.3s" % match.group(1) continue match = re.match('^[\d\.]+$', item) if match: hardcoded.add("%.3s" % match.group(0)) if len(hardcoded) == 1: ver = hardcoded.pop() return getver(ver), getver(ver) if not minv and hardcoded: # yeah, no maxv! minv = sorted(hardcoded)[0] if current: versions = sorted(get("%s-%s" % (minv if minv else '', maxv if maxv else ''))) if not versions: raise ValueError("version range doesn't match installed Python versions: %s" % value) # not really what "current" means... if DEFAULT in versions: return DEFAULT, DEFAULT else: return versions[0], versions[0] return getver(minv) if minv else None, \ getver(maxv) if maxv else None def vrange_str(vrange): """Return version range string from given range. >>> vrange_str(((2, 4), None)) '2.4-' >>> vrange_str(((2, 4), (2, 6))) '2.4-2.6' >>> vrange_str(((2, 4), (3, 0))) '2.4-3.0' >>> vrange_str((None, (2, 7))) '-2.7' >>> vrange_str(((2, 5), (2, 5))) '2.5' >>> vrange_str((None, None)) '-' """ if vrange[0] is vrange[1] is None: return '-' if vrange[0] == vrange[1]: return '.'.join(str(i) for i in vrange[0]) elif vrange[0] is None: return '-' + '.'.join(str(i) for i in vrange[1]) elif vrange[1] is None: return '.'.join(str(i) for i in vrange[0]) + '-' else: return "%s-%s" % ('.'.join(str(i) for i in vrange[0]), '.'.join(str(i) for i in vrange[1])) def vrepr(value): """ >>> vrepr(([2, 7], [3, 2])) ['2.7', '3.2'] >>> vrepr(('2.6', '3.1')) ['2.6', '3.1'] >>> vrepr('2.7') '2.7' >>> vrepr((2, 7)) '2.7' """ if isinstance(value, basestring): return value elif not isinstance(value, (GeneratorType, set))\ and isinstance(value[0], int): return '.'.join(str(i) for i in value) result = [] for version in value: if isinstance(version, basestring): result.append(version) else: result.append('.'.join(str(i) for i in version)) return result def getver(value): """Return pair of integers that represent version. >>> getver('2.5') (2, 5) >>> getver('2.6.4') (2, 6) >>> getver(None) '' """ if not value: return '' return tuple(int(i) for i in value.split('.', 2))[:2] def debsorted(versions, return_str=None): """Return sorted list of versions starting with default Python version (if available) then list of suppored versions greater than default one followed by reversed list of older versions. List of versions sorted this way can be used in Depends field. :param vrepr: return string represenatations of versions, by default the same format is used as in :param:`versions` >>> debsorted([(2, 6), (3, 1), (2, 5), (2, 4), (2, 7)])[0] == DEFAULT True >>> debsorted(('2.4', '3.2', '2.6', '2.7'))[-1] (2, 4) >>> debsorted(set([(2, 1), (2, 2)])) [(2, 2), (2, 1)] >>> debsorted([(2, 1), (2, 2)], return_str=True) ['2.2', '2.1'] """ result = [] old_versions = [] for version in sorted(versions): if isinstance(version, basestring): version = getver(version) if version < DEFAULT: old_versions.append(version) else: result.append(version) result.extend(reversed(old_versions)) if return_str and result: return vrepr(result) return result python-defaults-2.7.12/debpython/namespace.py0000664000000000000000000001372512057417145016141 0ustar # -*- coding: UTF-8 -*- # Copyright © 2011-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from __future__ import with_statement import logging from os import environ, listdir, remove, rmdir from os.path import dirname, exists, join, getsize, split from subprocess import Popen, PIPE from debpython.pydist import PUBLIC_DIR_RE from debpython.tools import memoize, sitedir log = logging.getLogger(__name__) def parse(fpaths, other=None): """Parse namespace_packages.txt files.""" result = set(other or []) for fpath in fpaths: with open(fpath, 'r') as fp: for line in fp: if line: result.add(line.strip()) return result @memoize def load(package=None): """Return a set of namespaces to regenerate/clean. :param package: limit namespaces to the ones needed by given package """ fpaths = None # DESTDIR is used in tests nsdir = "%s/usr/share/python/ns/" % environ.get('DESTDIR', '') if package: # only one package is processed, no need to load all files fpath = join(nsdir, package) if exists(fpath): fpaths = [fpath] else: # load all files if exists(nsdir): fpaths = [join(nsdir, i) for i in listdir(nsdir)] if fpaths: result = set(i.replace('.', '/') for i in parse(fpaths)) else: result = set() return result def add_namespace_files(files, package=None, action=None): """Add __init__.py files to given generator.""" if action is not None: namespaces = load(package) already_processed = set() removal_candidates = set() for fn in files: yield fn if action is None: continue dpath = dirname(fn) if dpath not in already_processed: already_processed.add(dpath) m = PUBLIC_DIR_RE.match(dpath) if m: public_dir = m.group() while dpath != public_dir: ns_dir = dpath[len(public_dir) + 1:] if ns_dir in namespaces: fpath = join(dpath, '__init__.py') if action is True: try: open(fpath, 'a').close() except Exception: log.error('cannot create %s', fpath) else: yield fpath else: # action is False # postpone it due to dpkg -S call removal_candidates.add(fpath) already_processed.add(dpath) dpath = split(dpath)[0] # now deal with to-be-removed namespace candidates (dpkg -S is expensive) # dpgk -S is used just to be safe (in case some other package is providing # __init__.py file although it's in /usr/share/python/ns dir) if action is False and removal_candidates: process = Popen("/usr/bin/dpkg -S %s 2>/dev/null" % \ ' '.join(removal_candidates), shell=True, stdout=PIPE) # FIXME: len(search_string) > 131072 stdout, stderr = process.communicate() for line in stdout.splitlines(): ns = line.split(': ', 1)[1] if ns in removal_candidates: removal_candidates.remove(ns) for fpath in removal_candidates: try: remove(fpath) except (IOError, OSError), e: log.error('cannot remove %s', fpath) log.debug(e) else: yield fpath def remove_from_package(package, namespaces, versions): """Remove empty __init__.py files for requested namespaces.""" if not isinstance(namespaces, set): namespaces = set(namespaces) keep = set() for ns in namespaces: for version in versions: fpath = join(sitedir(version, package), *ns.split('.')) fpath = join(fpath, '__init__.py') if not exists(fpath): continue if getsize(fpath) != 0: log.warning('file not empty, cannot share %s namespace', ns) keep.add(ns) break # return a set of namespaces that should be handled by pycompile/pyclean result = namespaces - keep # remove empty __init__.py files, if available for ns in result: for version in versions: dpath = join(sitedir(version, package), *ns.split('.')) fpath = join(dpath, '__init__.py') if exists(fpath): remove(fpath) if not listdir(dpath): rmdir(dpath) # clean pyshared dir as well dpath = join('debian', package, 'usr/share/pyshared', *ns.split('.')) fpath = join(dpath, '__init__.py') if exists(fpath): remove(fpath) if not listdir(dpath): rmdir(dpath) return result python-defaults-2.7.12/runtime.d/0000775000000000000000000000000012057417145013534 5ustar python-defaults-2.7.12/runtime.d/public_modules.rtinstall0000775000000000000000000000056712057417145020513 0ustar #! /bin/sh set -e VERSION=${2#python} case "$VERSION" in 2.[45]) sitedir=/usr/lib/python$VERSION/site-packages;; *) sitedir=/usr/lib/python$VERSION/dist-packages esac if which python >/dev/null 2>&1 && which pycompile >/dev/null 2>&1; then pycompile -V $VERSION $sitedir else echo >&2 "python or pycompile not found in $(basename $0) hook." exit 1 fi python-defaults-2.7.12/runtime.d/public_modules.rtremove0000775000000000000000000000047412057417145020337 0ustar #! /bin/sh set -e VERSION=${2#python} case "$VERSION" in 2.[45]) sitedir=/usr/lib/python$VERSION/site-packages;; *) sitedir=/usr/lib/python$VERSION/dist-packages esac if which python >/dev/null 2>&1 && which pyclean >/dev/null 2>&1; then pyclean $sitedir else find $sitedir -name '*.py[co]' -delete fi python-defaults-2.7.12/tests/0000775000000000000000000000000012254623031012761 5ustar python-defaults-2.7.12/tests/t7/0000775000000000000000000000000012057417145013323 5ustar python-defaults-2.7.12/tests/t7/foo.py0000775000000000000000000000011312057417145014456 0ustar #!/usr/local/bin/python2.6 "/usr/local/bin/python2.6 hardcoded in shebang" python-defaults-2.7.12/tests/t7/spam.py0000664000000000000000000000001612057417145014632 0ustar print('spam') python-defaults-2.7.12/tests/t7/baz.py0000775000000000000000000000006012057417145014450 0ustar #!/usr/local/bin/python "/usr/local in shebang" python-defaults-2.7.12/tests/t7/Makefile0000664000000000000000000000142012057417145014760 0ustar #!/usr/bin/make -f include ../common.mk clean: clean-common check: # python2.4 hardcoded via `dh_python2 -shebang ...python2.4` grep -q '\-V 2.4 /usr/share/baz24' debian/foo/usr/share/python/runtime.d/foo.rtupdate grep -q '/usr/share/baz24 \-V 2.4' debian/foo/DEBIAN/postinst grep -q '#! /usr/bin/python2.4 -OO' debian/foo/usr/share/baz24/baz.py # python2.6 hardcoded via shebang grep -q '\-V 2.6 /usr/share/foo' debian/foo/usr/share/python/runtime.d/foo.rtupdate grep -q '/usr/share/foo \-V 2.6' debian/foo/DEBIAN/postinst # /env removed from shebang grep -q '#! /usr/bin/python' debian/foo/usr/share/bar/bar.py # /local removed from shebang grep -q '#! /usr/bin/python' debian/foo/usr/share/foo/baz.py grep -q '#! /usr/bin/python2.6' debian/foo/usr/share/foo/foo.py python-defaults-2.7.12/tests/t7/bar.py0000775000000000000000000000004712057417145014445 0ustar #!/usr/bin/env python "env in shebang" python-defaults-2.7.12/tests/t7/debian/0000775000000000000000000000000012057417145014545 5ustar python-defaults-2.7.12/tests/t7/debian/copyright0000664000000000000000000000015412057417145016500 0ustar The Debian packaging is © 2012, Piotr Ożarowski and is licensed under the MIT License. python-defaults-2.7.12/tests/t7/debian/compat0000664000000000000000000000000212057417145015743 0ustar 8 python-defaults-2.7.12/tests/t7/debian/control0000664000000000000000000000052212057417145016147 0ustar Source: foo Section: misc Priority: optional Maintainer: Piotr Ożarowski Build-Depends: debhelper (>= 7.0.50~) Build-Depends-Indep: python Standards-Version: 3.9.3 Package: foo Architecture: all Depends: ${python:Depends}, ${misc:Depends} Description: example 7 - shebangs exemple package #7 - shebang related tests python-defaults-2.7.12/tests/t7/debian/source/0000775000000000000000000000000012057417145016045 5ustar python-defaults-2.7.12/tests/t7/debian/source/format0000664000000000000000000000001512057417145017254 0ustar 3.0 (native) python-defaults-2.7.12/tests/t7/debian/install0000664000000000000000000000025012057417145016133 0ustar foo.py /usr/share/foo/ baz.py /usr/share/foo/ spam.py /usr/share/foo/ bar.py /usr/share/bar/ spam.py /usr/share/bar/ baz.py /usr/share/baz24/ spam.py /usr/share/baz24/ python-defaults-2.7.12/tests/t7/debian/rules0000775000000000000000000000040612057417145015625 0ustar #!/usr/bin/make -f %: dh $@ --buildsystem=python_distutils override_dh_pysupport: DH_VERBOSE=1 ../../dh_python2 DH_VERBOSE=1 ../../dh_python2 /usr/share/bar DH_VERBOSE=1 ../../dh_python2 /usr/share/baz24 --shebang '/usr/bin/python2.4 -OO' clean: dh_clean python-defaults-2.7.12/tests/t7/debian/changelog0000664000000000000000000000017712057417145016424 0ustar foo (1.0) unstable; urgency=low * Initial release -- Piotr Ożarowski Sun, 10 Jun 2012 14:09:45 +0200 python-defaults-2.7.12/tests/t7/setup.py0000664000000000000000000000000012057417145015023 0ustar python-defaults-2.7.12/tests/t5/0000775000000000000000000000000012057417145013321 5ustar python-defaults-2.7.12/tests/t5/Makefile0000664000000000000000000000261612057417145014766 0ustar #!/usr/bin/make -f include ../common.mk clean: clean-common check: # test dh_python2 test -f debian/python-foo/usr/share/pyshared/keep_this_one/__init__.py test ! -f debian/python-foo/usr/share/pyshared/remove_this_one/__init__.py test ! -f debian/python-foo/usr/share/pyshared/foo/__init__.py grep -q remove_this_one debian/python-foo/usr/share/python/ns/python-foo grep -q foo debian/python-foo/usr/share/python/ns/python-foo grep -q bar.baz debian/python-foo/usr/share/python/ns/python-foo grep -q keep_this_one debian/python-foo/usr/share/python/ns/python-foo && false || true grep -q "pycompile -p python-foo" debian/python-foo/DEBIAN/postinst grep -q "pyclean -p python-foo" debian/python-foo/DEBIAN/prerm # test pycompile DESTDIR=debian/python-foo/ ../../pycompile -v debian/python-foo/usr/lib/ set -e; for i in remove_this_one bar bar/baz;\ do [ "`ls debian/python-foo/usr/lib/python2.*/*-packages/$$i/__init__.py | wc -l`" != '0' ];\ [ "`ls debian/python-foo/usr/lib/python2.*/*-packages/$$i/__init__.pyc | wc -l`" != '0' ];\ done # test pyclean DESTDIR=debian/python-foo/ ../../pyclean -v debian/python-foo/usr/lib/ set -e; for i in remove_this_one bar bar/baz;\ do [ "`ls debian/python-foo/usr/lib/python2.*/*-packages/$$i/__init__.py 2>/dev/null || true | wc -l`" = 0 ];\ [ "`ls debian/python-foo/usr/lib/python2.*/*-packages/$$i/__init__.pyc 2>/dev/null || true | wc -l`" = 0 ];\ done python-defaults-2.7.12/tests/t5/debian/0000775000000000000000000000000012057417145014543 5ustar python-defaults-2.7.12/tests/t5/debian/copyright0000664000000000000000000000015412057417145016476 0ustar The Debian packaging is © 2011, Piotr Ożarowski and is licensed under the MIT License. python-defaults-2.7.12/tests/t5/debian/compat0000664000000000000000000000000212057417145015741 0ustar 7 python-defaults-2.7.12/tests/t5/debian/control0000664000000000000000000000070012057417145016143 0ustar Source: foo Section: python Priority: optional Maintainer: Piotr Ożarowski Build-Depends: debhelper (>= 7.0.50~) Build-Depends-Indep: python Standards-Version: 3.9.1 Package: python-foo Architecture: all Depends: ${python:Depends}, ${misc:Depends} Description: example 5 - namespace feature exemple package #5 - dropping __init__.py file from binary package and recreating it at install time (and removing at in remove time) python-defaults-2.7.12/tests/t5/debian/source/0000775000000000000000000000000012057417145016043 5ustar python-defaults-2.7.12/tests/t5/debian/source/format0000664000000000000000000000001512057417145017252 0ustar 3.0 (native) python-defaults-2.7.12/tests/t5/debian/rules0000775000000000000000000000075012057417145015625 0ustar #!/usr/bin/make -f %: dh $@ --buildsystem=python_distutils override_dh_auto_build: override_dh_auto_install: set -e;\ cd debian/python-foo/usr/share/pyshared/;\ echo "keep_this_one\nremove_this_one" > foo.egg-info/namespace_packages.txt;\ echo "True" > keep_this_one/__init__.py;\ touch remove_this_one/__init__.py remove_this_one/foo.py bar/baz/spam.py override_dh_pysupport: DH_VERBOSE=1 ../../dh_python2 --namespace foo --namespace bar.baz --namespace bar clean: dh_clean python-defaults-2.7.12/tests/t5/debian/dirs0000664000000000000000000000020312057417145015422 0ustar /usr/share/pyshared/bar/baz /usr/share/pyshared/foo.egg-info /usr/share/pyshared/keep_this_one /usr/share/pyshared/remove_this_one python-defaults-2.7.12/tests/t5/debian/changelog0000664000000000000000000000020112057417145016406 0ustar foo (0.1.1) unstable; urgency=low * Initial release -- Piotr Ożarowski Sun, 27 Mar 2011 21:09:27 +0200 python-defaults-2.7.12/tests/Makefile0000664000000000000000000000054212057417145014432 0ustar #!/usr/bin/make -f # enable or disable tests here: TESTS := test1 test2 test3 test4 test5 test6 test7 all: $(TESTS) test%: make -C t$* run make -C t$* check clean-test%: make -C t$* clean clean: $(TESTS:%=clean-%) rm -f *\.dsc *\.tar\.gz *\.build *\.changes *\.deb @find . -prune -name '*.egg-info' -exec rm -rf '{}' ';' || true .PHONY: clean python-defaults-2.7.12/tests/t3/0000775000000000000000000000000012057417145013317 5ustar python-defaults-2.7.12/tests/t3/lib/0000775000000000000000000000000012057417145014065 5ustar python-defaults-2.7.12/tests/t3/lib/foo.py0000664000000000000000000000011012057417145015212 0ustar import foo.bar class Foo(object): def __init__(self): pass python-defaults-2.7.12/tests/t3/lib/__init__.py0000664000000000000000000000000012057417145016164 0ustar python-defaults-2.7.12/tests/t3/lib/bar.c0000664000000000000000000000000012057417145014763 0ustar python-defaults-2.7.12/tests/t3/Makefile0000664000000000000000000000204312057417145014756 0ustar #!/usr/bin/make -f include ../common.mk DPY=$(DEBPYTHON_DEFAULT) check: grep -q "pycompile -p python-foo /usr/lib/python-foo -V $(DPY)"\ debian/python-foo/DEBIAN/postinst test -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/bar.so test ! -f debian/python-foo/usr/share/pyshared/foo/bar.so test -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/spam.so test ! -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/spam.so.0.1 test -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/baz.so test ! -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/baz.so.0.1 test ! -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/baz.so.0.1.2 test -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/quux.so test ! -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/quux.so.0 test ! -L debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/quux.so.0 test ! -f debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/quux.so.0.0.0 clean: clean-common rm -rf lib/Foo.egg-info build python-defaults-2.7.12/tests/t3/debian/0000775000000000000000000000000012057417145014541 5ustar python-defaults-2.7.12/tests/t3/debian/copyright0000664000000000000000000000015412057417145016474 0ustar The Debian packaging is © 2010, Piotr Ożarowski and is licensed under the MIT License. python-defaults-2.7.12/tests/t3/debian/compat0000664000000000000000000000000212057417145015737 0ustar 7 python-defaults-2.7.12/tests/t3/debian/control0000664000000000000000000000105512057417145016145 0ustar Source: foo Section: python Priority: optional Maintainer: Piotr Ożarowski Build-Depends: debhelper (>= 7.0.50~), python-all-dev Standards-Version: 3.9.1 X-Python-Version: >= 2.6 Package: python-foo Architecture: any Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends} Recommends: ${python:Recommends} Suggests: ${python:Suggests} Enhances: ${python:Enhances} Breaks: ${python:Breaks} Provides: ${python:Provides} XB-Python-Version: ${python:Versions} Description: foo to rule them all exemple package #3 - Python extension python-defaults-2.7.12/tests/t3/debian/source/0000775000000000000000000000000012057417145016041 5ustar python-defaults-2.7.12/tests/t3/debian/source/format0000664000000000000000000000001512057417145017250 0ustar 3.0 (native) python-defaults-2.7.12/tests/t3/debian/install0000664000000000000000000000011712057417145016131 0ustar # private module in architecture dependent dir lib/foo.py /usr/lib/python-foo/ python-defaults-2.7.12/tests/t3/debian/rules0000775000000000000000000000275112057417145015626 0ustar #!/usr/bin/make -f DPY=$(shell PYTHONPATH=../../ python -c 'import debpython.version as v; print(v.vrepr(v.DEFAULT))') %: dh $@ --buildsystem=python_distutils override_dh_pysupport: # install also as private extension dh_install debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/bar.so \ /usr/lib/python-foo/ # ... and under versioned name with a symlink cp debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/bar.so \ debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/spam.so.0 dh_link /usr/lib/python${DPY}/dist-packages/foo/spam.so.0 \ /usr/lib/python${DPY}/dist-packages/foo/spam.so # ... and with multiple symlinks cp debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/bar.so \ debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/baz.so.0.1.2 dh_link /usr/lib/python${DPY}/dist-packages/foo/baz.so.0.1.2 \ /usr/lib/python${DPY}/dist-packages/foo/baz.so.0.1 dh_link /usr/lib/python${DPY}/dist-packages/foo/baz.so.0.1 \ /usr/lib/python${DPY}/dist-packages/foo/baz.so # ... second style of multiple symlinks cp debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/bar.so \ debian/python-foo/usr/lib/python${DPY}/dist-packages/foo/quux.so.0.0.0 dh_link /usr/lib/python${DPY}/dist-packages/foo/quux.so.0.0.0 \ /usr/lib/python${DPY}/dist-packages/foo/quux.so.0 dh_link /usr/lib/python${DPY}/dist-packages/foo/quux.so.0.0.0 \ /usr/lib/python${DPY}/dist-packages/foo/quux.so # ... and complex multiple symlinks DH_VERBOSE=1 ../../dh_python2 python-defaults-2.7.12/tests/t3/debian/changelog0000664000000000000000000000020112057417145016404 0ustar foo (0.1.1) unstable; urgency=low * Initial release -- Piotr Ożarowski Sun, 19 Dec 2010 19:40:33 +0100 python-defaults-2.7.12/tests/t3/setup.py0000775000000000000000000000061312057417145015034 0ustar #!/usr/bin/env python from distutils.core import setup, Extension setup(name="distutils-test", version = "0.1", author="jbailey", author_email="jbailey@debian.org", url="http://www.python.org/sigs/distutils-sig/", ext_modules=[Extension('foo/bar', ['lib/bar.c'])], #py_modules=['package'], packages = ["foo"], package_dir = {'foo': 'lib'} ) python-defaults-2.7.12/tests/common.mk0000664000000000000000000000057212254623031014606 0ustar #!/usr/bin/make -f export DEBPYTHON_DEFAULT ?= $(shell sed -rne 's,^default-version = python(.*),\1,p' ../../debian/debian_defaults) export DEBPYTHON_SUPPORTED ?= $(shell sed -rne '/^supported-versions/{s/^supported-versions = (.*)/\1/g;s/python//gp}' ../../debian/debian_defaults) all: run check run: clean dpkg-buildpackage -b -us -uc clean-common: ./debian/rules clean python-defaults-2.7.12/tests/t2/0000775000000000000000000000000012254623031013306 5ustar python-defaults-2.7.12/tests/t2/foo.py0000664000000000000000000000002112057417145014444 0ustar print("I'm foo") python-defaults-2.7.12/tests/t2/Makefile0000664000000000000000000000052112254623031014744 0ustar #!/usr/bin/make -f include ../common.mk DPY=$(DEBPYTHON_DEFAULT) clean: clean-common check: test -f debian/python-foo/usr/lib/python$(DPY)/dist-packages/foo.py test -f debian/python-foo/usr/lib/python$(DPY)/dist-packages/bar/bar.py grep -q pycompile debian/python-foo/DEBIAN/postinst grep -q pyclean debian/python-foo/DEBIAN/prerm python-defaults-2.7.12/tests/t2/__init__.py0000664000000000000000000000003112057417145015421 0ustar print("I'm __init__.py") python-defaults-2.7.12/tests/t2/bar.py0000664000000000000000000000002112057417145014425 0ustar print("I'm bar") python-defaults-2.7.12/tests/t2/debian/0000775000000000000000000000000012057417145014540 5ustar python-defaults-2.7.12/tests/t2/debian/copyright0000664000000000000000000000015412057417145016473 0ustar The Debian packaging is © 2010, Piotr Ożarowski and is licensed under the MIT License. python-defaults-2.7.12/tests/t2/debian/compat0000664000000000000000000000000212057417145015736 0ustar 7 python-defaults-2.7.12/tests/t2/debian/control0000664000000000000000000000072512057417145016147 0ustar Source: foo Section: python Priority: optional Maintainer: Piotr Ożarowski Build-Depends: debhelper (>= 7.0.50~) Build-Depends-Indep: python-all Standards-Version: 3.9.1 XS-Python-Version: >= 2.1 Package: python-foo Architecture: all Depends: ${python:Depends}, ${misc:Depends} Recommends: ${python:Recommends} Suggests: ${python:Suggests} Enhances: ${python:Enhances} Breaks: ${python:Breaks} Description: foo to rule them all exemple package #2 python-defaults-2.7.12/tests/t2/debian/source/0000775000000000000000000000000012057417145016040 5ustar python-defaults-2.7.12/tests/t2/debian/source/format0000664000000000000000000000001512057417145017247 0ustar 3.0 (native) python-defaults-2.7.12/tests/t2/debian/install0000664000000000000000000000014112057417145016125 0ustar foo.py /usr/share/pyshared/ __init__.py /usr/share/pyshared/bar/ bar.py /usr/share/pyshared/bar/ python-defaults-2.7.12/tests/t2/debian/rules0000775000000000000000000000020512057417145015615 0ustar #!/usr/bin/make -f %: dh $@ --buildsystem=python_distutils override_dh_pysupport: DH_VERBOSE=1 ../../dh_python2 clean: dh_clean python-defaults-2.7.12/tests/t2/debian/changelog0000664000000000000000000000020112057417145016403 0ustar foo (0.1.1) unstable; urgency=low * Initial release -- Piotr Ożarowski Sat, 27 Feb 2010 20:42:17 +0100 python-defaults-2.7.12/tests/t2/setup.py0000664000000000000000000000000012057417145015016 0ustar python-defaults-2.7.12/tests/t1/0000775000000000000000000000000012254623031013305 5ustar python-defaults-2.7.12/tests/t1/lib/0000775000000000000000000000000012057417145014063 5ustar python-defaults-2.7.12/tests/t1/lib/foo/0000775000000000000000000000000012057417145014646 5ustar python-defaults-2.7.12/tests/t1/lib/foo/bar/0000775000000000000000000000000012057417145015412 5ustar python-defaults-2.7.12/tests/t1/lib/foo/bar/__init__.py0000664000000000000000000000006612057417145017525 0ustar print("you just imported foo.bar from %s" % __file__) python-defaults-2.7.12/tests/t1/lib/foo/baz.py0000664000000000000000000000006612057417145015776 0ustar print("you just imported foo.baz from %s" % __file__) python-defaults-2.7.12/tests/t1/lib/foo/jquery.js0000777000000000000000000000000012057417145026052 2/usr/share/javascript/jquery/jquery.jsustar python-defaults-2.7.12/tests/t1/lib/foo/__init__.py0000664000000000000000000000006212057417145016755 0ustar print("you just imported foo from %s" % __file__) python-defaults-2.7.12/tests/t1/Makefile0000664000000000000000000000133512254623031014747 0ustar #!/usr/bin/make -f include ../common.mk DPY=$(DEBPYTHON_DEFAULT) check: grep -q "Depends: .*python-mako" debian/python-foo/DEBIAN/control grep -q 'python-foo (>= 2:0.1~rc2)' debian/python-foo/DEBIAN/control ifneq (,$(findstring 2.6,$(DEBPYTHON_SUPPORTED))) test -f debian/python-foo/usr/lib/python2.6/dist-packages/foo/__init__.py endif test ! -f debian/python-foo/usr/lib/python2.6/dist-packages/foo/spam.py grep -q "Depends: .*python (<<" debian/python-foo/DEBIAN/control [ "`readlink debian/python-foo/usr/lib/python$(DPY)/dist-packages/foo/absolute_link_to_tmp`" = "/tmp" ] [ "`readlink debian/python-foo/usr/lib/python$(DPY)/dist-packages/foo/link_to_parent_dir`" = ".." ] clean: clean-common rm -rf lib/Foo.egg-info python-defaults-2.7.12/tests/t1/debian/0000775000000000000000000000000012057417145014537 5ustar python-defaults-2.7.12/tests/t1/debian/copyright0000664000000000000000000000015412057417145016472 0ustar The Debian packaging is © 2010, Piotr Ożarowski and is licensed under the MIT License. python-defaults-2.7.12/tests/t1/debian/spam.py0000664000000000000000000000001512057417145016045 0ustar print 'SPAM' python-defaults-2.7.12/tests/t1/debian/compat0000664000000000000000000000000212057417145015735 0ustar 7 python-defaults-2.7.12/tests/t1/debian/control0000664000000000000000000000103612057417145016142 0ustar Source: foo Section: python Priority: optional Maintainer: Piotr Ożarowski Build-Depends: debhelper (>= 7.0.50~) Build-Depends-Indep: python-all Standards-Version: 3.9.0 XS-Python-Version: >= 2.4 Package: python-foo Architecture: all Depends: ${python:Depends}, ${misc:Depends} Recommends: ${python:Recommends} Suggests: ${python:Suggests} Enhances: ${python:Enhances} Breaks: foo, ${python:Breaks} Provides: ${python:Provides} XB-Python-Version: ${python:Versions} Description: foo to rule them all exemple package #1 python-defaults-2.7.12/tests/t1/debian/python-foo.pyremove0000664000000000000000000000003512057417145020427 0ustar foo/spam.py 2.6 foo/bar 2.7- python-defaults-2.7.12/tests/t1/debian/source/0000775000000000000000000000000012057417145016037 5ustar python-defaults-2.7.12/tests/t1/debian/source/format0000664000000000000000000000001512057417145017246 0ustar 3.0 (native) python-defaults-2.7.12/tests/t1/debian/pydist-overrides0000664000000000000000000000016212057417145017775 0ustar Mako python-mako (>= 0.2) SQLAlchemy python-sqlalchemy (>= 0.6) Foo python-foo; PEP386 s/^/2:/ Bar python-bar Baz python-defaults-2.7.12/tests/t1/debian/python-foo.pyinstall0000664000000000000000000000003012057417145020573 0ustar debian/spam.py foo 2.5- python-defaults-2.7.12/tests/t1/debian/rules0000775000000000000000000000074012057417145015620 0ustar #!/usr/bin/make -f %: dh $@ --buildsystem=python_distutils override_dh_pysupport: find debian/ -name jquery.js -exec \ ln -fs /usr/share/javascript/jquery/jquery.js '{}' \; find debian/ -name foo -type d -exec \ ln -s /tmp/ '{}/absolute_link_to_tmp' \; find debian/ -name foo -type d -exec \ ln -s .. '{}/link_to_parent_dir' \; DH_VERBOSE=1 ../../dh_python2\ --depends 'SQLAlchemy >= 0.6.1'\ --recommends Mako\ --suggests 'Foo >= 0.1rc2'\ --suggests 'bar >= 1.0' python-defaults-2.7.12/tests/t1/debian/changelog0000664000000000000000000000020112057417145016402 0ustar foo (0.1.1) unstable; urgency=low * Initial release -- Piotr Ożarowski Sat, 27 Feb 2010 20:42:17 +0100 python-defaults-2.7.12/tests/t1/setup.py0000664000000000000000000000113612057417145015030 0ustar #! /usr/bin/python # -*- coding: UTF-8 -*- try: from setuptools import setup, find_packages except ImportError: exit() setup(name='Foo', version=0.1, description="Foo to rule them all", long_description="TODO", keywords='foo bar baz', author='Piotr Ożarowski', author_email='piotr@debian.org', url='http://www.debian.org/', license='MIT', package_dir={'': 'lib'}, packages=find_packages('lib/'), package_data = {'foo': ['jquery.js']}, zip_safe=False, install_requires = ['Mako', 'SQLAlchemy >=0.5', 'Baz [extras]'], ) python-defaults-2.7.12/tests/t4/0000775000000000000000000000000012254623031013310 5ustar python-defaults-2.7.12/tests/t4/foo.py0000775000000000000000000000004612057417145014460 0ustar #!/usr/bin/python2.6 print("I'm foo") python-defaults-2.7.12/tests/t4/baz.py0000664000000000000000000000006712057417145014451 0ustar #!/usr/bin/python2.4 print("I'm baz - not executable") python-defaults-2.7.12/tests/t4/Makefile0000664000000000000000000000077112254623031014755 0ustar #!/usr/bin/make -f include ../common.mk clean: clean-common check: grep -q python2.6 debian/foo/usr/share/foo/foo.py ifneq (,$(findstring 2.6,$(DEBPYTHON_SUPPORTED))) grep -q Depends:.*python2.6 debian/foo/DEBIAN/control endif #grep -q python2.5 debian/foo/usr/share/bar/bar.py #grep -q Depends:.*python2.5 debian/foo/DEBIAN/control grep -q python2.4 debian/foo/usr/share/foo/baz.py test ! -x debian/foo/usr/share/foo/baz.py grep -q Depends:.*python2.4 debian/foo/DEBIAN/control && false || true python-defaults-2.7.12/tests/t4/bar.py0000775000000000000000000000004612057417145014441 0ustar #!/usr/bin/python2.5 print("I'm bar") python-defaults-2.7.12/tests/t4/debian/0000775000000000000000000000000012057417145014542 5ustar python-defaults-2.7.12/tests/t4/debian/copyright0000664000000000000000000000015412057417145016475 0ustar The Debian packaging is © 2011, Piotr Ożarowski and is licensed under the MIT License. python-defaults-2.7.12/tests/t4/debian/compat0000664000000000000000000000000212057417145015740 0ustar 7 python-defaults-2.7.12/tests/t4/debian/control0000664000000000000000000000066212057417145016151 0ustar Source: foo Section: misc Priority: optional Maintainer: Piotr Ożarowski Build-Depends: debhelper (>= 7.0.50~) Build-Depends-Indep: python Standards-Version: 3.9.1 Package: foo Architecture: all Depends: ${python:Depends}, ${misc:Depends} Recommends: ${python:Recommends} Suggests: ${python:Suggests} Enhances: ${python:Enhances} Description: example 4 - private directory exemple package #4 - private directory python-defaults-2.7.12/tests/t4/debian/source/0000775000000000000000000000000012057417145016042 5ustar python-defaults-2.7.12/tests/t4/debian/source/format0000664000000000000000000000001512057417145017251 0ustar 3.0 (native) python-defaults-2.7.12/tests/t4/debian/install0000664000000000000000000000010512057417145016127 0ustar foo.py /usr/share/foo/ bar.py /usr/share/bar/ baz.py /usr/share/foo/ python-defaults-2.7.12/tests/t4/debian/rules0000775000000000000000000000026312057417145015623 0ustar #!/usr/bin/make -f %: dh $@ --buildsystem=python_distutils override_dh_pysupport: DH_VERBOSE=1 ../../dh_python2 DH_VERBOSE=1 ../../dh_python2 /usr/share/bar clean: dh_clean python-defaults-2.7.12/tests/t4/debian/changelog0000664000000000000000000000020112057417145016405 0ustar foo (0.1.1) unstable; urgency=low * Initial release -- Piotr Ożarowski Sat, 27 Feb 2010 20:42:17 +0100 python-defaults-2.7.12/tests/t4/setup.py0000664000000000000000000000000012057417145015020 0ustar python-defaults-2.7.12/tests/t6/0000775000000000000000000000000012254623031013312 5ustar python-defaults-2.7.12/tests/t6/foo.py0000775000000000000000000000004612057417145014462 0ustar #!/usr/bin/python2.6 print("I'm foo") python-defaults-2.7.12/tests/t6/spam.py0000664000000000000000000000001612057417145014631 0ustar print('spam') python-defaults-2.7.12/tests/t6/baz.py0000664000000000000000000000004312057417145014445 0ustar #!/usr/bin/python print("I'm baz") python-defaults-2.7.12/tests/t6/Makefile0000664000000000000000000000153412254623031014755 0ustar #!/usr/bin/make -f include ../common.mk clean: clean-common check: # python2.4 hardcoded via `dh_python2 -V 2.4` grep -q Depends:.*python2.4 debian/foo/DEBIAN/control grep -q '\-V 2.4 /usr/share/baz24' debian/foo/usr/share/python/runtime.d/foo.rtupdate grep -q '/usr/share/baz24 \-V 2.4' debian/foo/DEBIAN/postinst # python2.5 due to X-Python-Version: 2.5 grep -q Depends:.*python2.5 debian/foo/DEBIAN/control grep -q '\-V 2.5 /usr/share/bar25' debian/foo/usr/share/python/runtime.d/foo.rtupdate grep -q '/usr/share/bar25 \-V 2.5' debian/foo/DEBIAN/postinst # python2.6 hardcoded via shebang ifneq (,$(findstring 2.6,$(DEBPYTHON_SUPPORTED))) grep -q Depends:.*python2.6 debian/foo/DEBIAN/control grep -q '\-V 2.6 /usr/share/foo' debian/foo/usr/share/python/runtime.d/foo.rtupdate grep -q '/usr/share/foo \-V 2.6' debian/foo/DEBIAN/postinst endif python-defaults-2.7.12/tests/t6/bar.py0000775000000000000000000000004312057417145014440 0ustar #!/usr/bin/python print("I'm bar") python-defaults-2.7.12/tests/t6/debian/0000775000000000000000000000000012057417145014544 5ustar python-defaults-2.7.12/tests/t6/debian/copyright0000664000000000000000000000015412057417145016477 0ustar The Debian packaging is © 2011, Piotr Ożarowski and is licensed under the MIT License. python-defaults-2.7.12/tests/t6/debian/compat0000664000000000000000000000000212057417145015742 0ustar 8 python-defaults-2.7.12/tests/t6/debian/control0000664000000000000000000000116512057417145016152 0ustar Source: foo Section: misc Priority: optional Maintainer: Piotr Ożarowski Build-Depends: debhelper (>= 7.0.50~) Build-Depends-Indep: python Standards-Version: 3.9.1 X-Python-Version: 2.5 Package: foo Architecture: all Depends: ${python:Depends}, ${misc:Depends} Recommends: ${python:Recommends} Suggests: ${python:Suggests} Enhances: ${python:Enhances} Description: example 6 - private directory with hardcoded Python version exemple package #6 - private directories that support: * python2.4 hardcoded via `dh_python2 -V 2.4` * python2.5 due to X-Python-Version: 2.5 * python2.6 hardcoded via shebang python-defaults-2.7.12/tests/t6/debian/source/0000775000000000000000000000000012057417145016044 5ustar python-defaults-2.7.12/tests/t6/debian/source/format0000664000000000000000000000001512057417145017253 0ustar 3.0 (native) python-defaults-2.7.12/tests/t6/debian/install0000664000000000000000000000022512057417145016134 0ustar foo.py /usr/share/foo/ spam.py /usr/share/foo/ bar.py /usr/share/bar25/ spam.py /usr/share/bar25/ baz.py /usr/share/baz24/ spam.py /usr/share/baz24/ python-defaults-2.7.12/tests/t6/debian/rules0000775000000000000000000000035412057417145015626 0ustar #!/usr/bin/make -f %: dh $@ --buildsystem=python_distutils override_dh_pysupport: DH_VERBOSE=1 ../../dh_python2 DH_VERBOSE=1 ../../dh_python2 /usr/share/bar25 DH_VERBOSE=1 ../../dh_python2 /usr/share/baz24 -V 2.4 clean: dh_clean python-defaults-2.7.12/tests/t6/debian/changelog0000664000000000000000000000020112057417145016407 0ustar foo (0.1.1) unstable; urgency=low * Initial release -- Piotr Ożarowski Sat, 08 Oct 2011 17:13:03 +0200 python-defaults-2.7.12/tests/t6/setup.py0000664000000000000000000000000012057417145015022 0ustar python-defaults-2.7.12/Makefile0000664000000000000000000000410712374331373013271 0ustar #!/usr/bin/make -f INSTALL ?= install PREFIX ?= /usr/local MANPAGES ?= dh_python2.1 pycompile.1 pyclean.1 clean: make -C tests clean make -C pydist clean find . -name '*.py[co]' -delete rm -f .coverage install-dev: $(INSTALL) -m 755 -d $(DESTDIR)$(PREFIX)/bin \ $(DESTDIR)$(PREFIX)/share/python/runtime.d \ $(DESTDIR)$(PREFIX)/share/debhelper/autoscripts/ \ $(DESTDIR)$(PREFIX)/share/perl5/Debian/Debhelper/Sequence/ $(INSTALL) -m 755 runtime.d/* $(DESTDIR)$(PREFIX)/share/python/runtime.d/ $(INSTALL) -m 644 autoscripts/* $(DESTDIR)$(PREFIX)/share/debhelper/autoscripts/ $(INSTALL) -m 755 dh_python2 $(DESTDIR)$(PREFIX)/share/python/ $(INSTALL) -m 755 dh_python2.py $(DESTDIR)$(PREFIX)/bin/dh_python2 $(INSTALL) -m 644 python2.pm $(DESTDIR)$(PREFIX)/share/perl5/Debian/Debhelper/Sequence/ install-runtime: $(INSTALL) -m 755 -d $(DESTDIR)$(PREFIX)/share/python/debpython $(DESTDIR)$(PREFIX)/bin $(INSTALL) -m 644 debpython/*.py $(DESTDIR)$(PREFIX)/share/python/debpython/ $(INSTALL) -m 755 pycompile $(DESTDIR)$(PREFIX)/bin/ $(INSTALL) -m 755 pyclean $(DESTDIR)$(PREFIX)/bin/ install: install-dev install-runtime dist_fallback: make -C pydist $@ check_versions: @set -e;\ DEFAULT=`sed -rn 's,^DEFAULT = \(([0-9]+)\, ([0-9]+)\),\1.\2,p' debpython/version.py`;\ SUPPORTED=`sed -rn 's,^SUPPORTED = \[\(([0-9]+)\, ([0-9]+)\)\, \(([0-9]+)\, ([0-9]+)\)\],\1.\2 \3.\4,p' debpython/version.py`;\ DEB_DEFAULT=`sed -rn 's,^default-version = python([0-9.]*),\1,p' debian/debian_defaults`;\ DEB_SUPPORTED=`sed -rn 's|^supported-versions = (.*)|\1|p' debian/debian_defaults | sed 's/python//g;s/,//g'`;\ [ "$$DEFAULT" = "$$DEB_DEFAULT" ] || \ (echo "Please update DEFAULT in debpython/version.py ($$DEFAULT vs. $$DEB_DEFAULT)" >/dev/stderr; false);\ [ "$$SUPPORTED" = "$$DEB_SUPPORTED" ] || \ (echo "Please update SUPPORTED in debpython/version.py ($$SUPPORTED vs. $$DEB_SUPPORTED)" >/dev/stderr; false) pdebuild: pdebuild --debbuildopts -I # TESTS nose: nosetests --with-doctest --with-coverage tests: nose make -C tests test%: make -C tests $@ .PHONY: clean tests test% check_versions python-defaults-2.7.12/faq/0000775000000000000000000000000012632016514012370 5ustar python-defaults-2.7.12/faq/general.html0000664000000000000000000026445012632016513014705 0ustar General Python FAQ

General Python FAQ

Date: 2006-02-26
Version: 8958
Web site:http://www.python.org/

Contents

1   General Information

1.1   What is Python?

Python is an interpreted, interactive, object-oriented programming language. It incorporates modules, exceptions, dynamic typing, very high level dynamic data types, and classes. Python combines remarkable power with very clear syntax. It has interfaces to many system calls and libraries, as well as to various window systems, and is extensible in C or C++. It is also usable as an extension language for applications that need a programmable interface. Finally, Python is portable: it runs on many Unix variants, on the Mac, and on PCs under MS-DOS, Windows, Windows NT, and OS/2.

To find out more, start with the Beginner's Guide to Python.

1.2   Why was Python created in the first place?

Here's a very brief summary of what started it all, written by Guido van Rossum:

I had extensive experience with implementing an interpreted language in the ABC group at CWI, and from working with this group I had learned a lot about language design. This is the origin of many Python features, including the use of indentation for statement grouping and the inclusion of very-high-level data types (although the details are all different in Python).

I had a number of gripes about the ABC language, but also liked many of its features. It was impossible to extend the ABC language (or its implementation) to remedy my complaints -- in fact its lack of extensibility was one of its biggest problems. I had some experience with using Modula-2+ and talked with the designers of Modula-3 and read the Modula-3 report. Modula-3 is the origin of the syntax and semantics used for exceptions, and some other Python features.

I was working in the Amoeba distributed operating system group at CWI. We needed a better way to do system administration than by writing either C programs or Bourne shell scripts, since Amoeba had its own system call interface which wasn't easily accessible from the Bourne shell. My experience with error handling in Amoeba made me acutely aware of the importance of exceptions as a programming language feature.

It occurred to me that a scripting language with a syntax like ABC but with access to the Amoeba system calls would fill the need. I realized that it would be foolish to write an Amoeba-specific language, so I decided that I needed a language that was generally extensible.

During the 1989 Christmas holidays, I had a lot of time on my hand, so I decided to give it a try. During the next year, while still mostly working on it in my own time, Python was used in the Amoeba project with increasing success, and the feedback from colleagues made me add many early improvements.

In February 1991, after just over a year of development, I decided to post to USENET. The rest is in the Misc/HISTORY file.

1.3   What is Python good for?

Python is a high-level general-purpose programming language that can be applied to many different classes of problems.

The language comes with a large standard library that covers areas such as string processing (regular expressions, Unicode, calculating differences between files), Internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP, CGI programming), software engineering (unit testing, logging, profiling, parsing Python code), and operating system interfaces (system calls, filesystems, TCP/IP sockets). Look at the table of contents for the Library Reference to get an idea of what's available. A wide variety of third-party extensions are also available. Consult the Python Package Index to find packages of interest to you.

1.4   How does the Python version numbering scheme work?

Python versions are numbered A.B.C or A.B. A is the major version number -- it is only incremented for really major changes in the language. B is the minor version number, incremented for less earth-shattering changes. C is the micro-level -- it is incremented for each bugfix release. See PEP 6 for more information about bugfix releases.

Not all releases are bugfix releases. In the run-up to a new major release, a series of development releases are made, denoted as alpha, beta, or release candidate. Alphas are early releases in which interfaces aren't yet finalized; it's not unexpected to see an interface change between two alpha releases. Betas are more stable, preserving existing interfaces but possibly adding new modules, and release candidates are frozen, making no changes except as needed to fix critical bugs.

Alpha, beta and release candidate versions have an additional suffix. The suffix for an alpha version is "aN" for some small number N, the suffix for a beta version is "bN" for some small number N, and the suffix for a release candidate version is "cN" for some small number N. In other words, all versions labeled 2.0aN precede the versions labeled 2.0bN, which precede versions labeled 2.0cN, and those precede 2.0.

You may also find version numbers with a "+" suffix, e.g. "2.2+". These are unreleased versions, built directly from the subversion trunk. In practice, after a final minor release is made, the subversion trunk is incremented to the next minor version, which becomes the "a0" version, e.g. "2.4a0".

See also the documentation for sys.version, sys.hexversion, and sys.version_info.

1.6   How do I obtain a copy of the Python source?

The latest Python source distribution is always available from python.org, at http://www.python.org/download/. The latest development sources can be obtained via anonymous subversion from SourceForge, at http://svn.python.org/projects/python/trunk.

The source distribution is a gzipped tar file containing the complete C source, LaTeX documentation, Python library modules, example programs, and several useful pieces of freely distributable software. This will compile and run out of the box on most UNIX platforms.

Older versions of Python are also available from python.org.

1.7   How do I get documentation on Python?

All documentation is available on-line, starting at http://www.python.org/doc/.

The standard documentation for the current stable version of Python is also available at http://docs.python.org/.

The LaTeX source for the documentation is part of the source distribution. If you don't have LaTeX, the latest Python documentation set is available by anonymous FTP in various formats such as PostScript and HTML. Visit the above URL for links to the current versions.

1.8   I've never programmed before. Is there a Python tutorial?

There are numerous tutorials and books available. Consult the Beginner's Guide to find information for beginning Python programmers, including lists of tutorials.

1.10   Is there a newsgroup or mailing list devoted to Python?

There is a newsgroup, comp.lang.python, and a mailing list, python-list. The newsgroup and mailing list are gatewayed into each other -- if you can read news it's unnecessary to subscribe to the mailing list. comp.lang.python is high-traffic, receiving hundreds of postings every day, and Usenet readers are often more able to cope with this volume.

Announcements of new software releases and events can be found in comp.lang.python.announce, a low-traffic moderated list that receives about five postings per day. It's available as the python-announce mailing list.

More info about other mailing lists and newsgroups can be found at http://www.python.org/community/lists.html.

1.11   How do I get a beta test version of Python?

All releases, including alphas, betas and release candidates, are announced on the comp.lang.python and comp.lang.python.announce newsgroups. All announcements also appear on the Python home page, at http://www.python.org/; an RSS feed of news is available.

You can also access the development version of Python through subversion. See http://www.python.org/dev/devfaq.html#subversion-svn for details.

1.12   How do I submit bug reports and patches for Python?

To report a bug or submit a patch, please use the relevant service from the Python project at SourceForge.

Bugs: http://sourceforge.net/tracker/?group_id=5470&atid=105470

Patches: http://sourceforge.net/tracker/?group_id=5470&atid=305470

You must have a SourceForge account to report bugs; this makes it possible for us to contact you if we have follow-up questions. It will also enable SourceForge to send you updates as we act on your bug.

For more information on how Python is developed, consult the Python Developer's Guide.

1.13   Are there any published articles about Python that I can reference?

It's probably best to reference your favorite book about Python.

The very first article about Python is this very old article that's now quite outdated.

Guido van Rossum and Jelke de Boer, "Interactively Testing Remote Servers Using the Python Programming Language", CWI Quarterly, Volume 4, Issue 4 (December 1991), Amsterdam, pp 283-303.

1.14   Are there any books on Python?

Yes, there are many, and more are being published. See the python.org Wiki at http://www.python.org/moin/PythonBooks for a list.

You can also search online bookstores for "Python" and filter out the Monty Python references; or perhaps search for "Python" and "language".

1.15   Where in the world is www.python.org located?

It's currently in Amsterdam, graciously hosted by XS4ALL. Thanks to Thomas Wouters for his work in arranging python.org's hosting.

1.16   Why is it called Python?

At the same time he began implementing Python, Guido van Rossum was also reading the published scripts from "Monty Python's Flying Circus" (a BBC comedy series from the seventies, in the unlikely case you didn't know). It occurred to him that he needed a name that was short, unique, and slightly mysterious, so he decided to call the language Python.

2   Python in the real world

2.1   How stable is Python?

Very stable. New, stable releases have been coming out roughly every 6 to 18 months since 1991, and this seems likely to continue. Currently there are usually around 18 months between major releases.

With the introduction of retrospective "bugfix" releases the stability of existing releases is being improved. Bugfix releases, indicated by a third component of the version number (e.g. 2.1.3, 2.2.2), are managed for stability; only fixes for known problems are included in a bugfix release, and it's guaranteed that interfaces will remain the same throughout a series of bugfix releases.

The 2.4.2 release is the most stable version at this point in time.

2.2   How many people are using Python?

Probably tens of thousands of users, though it's difficult to obtain an exact count. Python is available for free download, so there are no sales figures, and it's available from many different sites and packaged with many Linux distributions, so download statistics don't tell the whole story either. The comp.lang.python newsgroup is very active, but not all Python users post to the group or even read it. Overall there is no accurate estimate of the number of subscribers or Python users.

2.3   Have any significant projects been done in Python?

See http://www.pythonology.org/success for a list of projects that use Python. Consulting the proceedings for past Python conferences will reveal contributions from many different companies and organizations.

High-profile Python projects include the Mailman mailing list manager and the Zope application server. Several Linux distributions, most notably Red Hat, have written part or all of their installer and system administration software in Python. Companies that use Python internally include Google, Yahoo, and Industrial Light & Magic.

2.4   What new developments are expected for Python in the future?

See http://www.python.org/peps for the Python Enhancement Proposals (PEPs). PEPs are design documents describing a suggested new feature for Python, providing a concise technical specification and a rationale. PEP 1 explains the PEP process and PEP format; read it first if you want to submit a PEP.

New developments are discussed on the python-dev mailing list.

2.5   Is it reasonable to propose incompatible changes to Python?

In general, no. There are already millions of lines of Python code around the world, so any change in the language that invalidates more than a very small fraction of existing programs has to be frowned upon. Even if you can provide a conversion program, there still is the problem of updating all documentation; many books have been written about Python, and we don't want to invalidate them all at a single stroke.

Providing a gradual upgrade path is necessary if a feature has to be changed. PEP 5 describes the procedure followed for introducing backward-incompatible changes while minimizing disruption for users.

2.6   What is the Python Software Foundation?

The Python Software Foundation is an independent non-profit organization that holds the copyright on Python versions 2.1 and newer. The PSF's mission is to advance open source technology related to the Python programming language and to publicize the use of Python. The PSF's home page is at http://www.python.org/psf/.

Donations to the PSF are tax-exempt in the US. If you use Python and find it helpful, please contribute via the PSF donation page.

2.7   Is Python Y2K (Year 2000) Compliant?

As of August, 2003 no major problems have been reported and Y2K compliance seems to be a non-issue.

Python does very few date calculations and for those it does perform relies on the C library functions. Python generally represents times either as seconds since 1970 or as a (year, month, day, ...) tuple where the year is expressed with four digits, which makes Y2K bugs unlikely. So as long as your C library is okay, Python should be okay. Of course, it's possible that a particular application written in Python makes assumptions about 2-digit years.

Because Python is available free of charge, there are no absolute guarantees. If there are unforseen problems, liability is the user's problem rather than the developers', and there is nobody you can sue for damages. The Python copyright notice contains the following disclaimer:

4. PSF is making Python 2.3 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 2.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS.

5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.

The good news is that if you encounter a problem, you have full source available to track it down and fix it. This is one advantage of an open source programming environment.

2.8   Is Python a good language for beginning programmers?

Yes. If you want to discuss Python's use in education, then you may be interested in joining the edu-sig mailing list.

It is still common to start students with a procedural (subset of a) statically typed language such as Pascal, C, or a subset of C++ or Java. Students may be better served by learning Python as their first language. Python has a very simple and consistent syntax and a large standard library and, most importantly, using Python in a beginning programming course permits students to concentrate on important programming skills such as problem decomposition and data type design. With Python, students can be quickly introduced to basic concepts such as loops and procedures. They can even probably work with user-defined objects in their very first course.

For a student who has never programmed before, using a statically typed language seems unnatural. It presents additional complexity that the student must master and slows the pace of the course. The students are trying to learn to think like a computer, decompose problems, design consistent interfaces, and encapsulate data. While learning to use a statically typed language is important in the long term, it is not necessarily the best topic to address in the students' first programming course.

Many other aspects of Python make it a good first language. Like Java, Python has a large standard library so that students can be assigned programming projects very early in the course that do something. Assignments aren't restricted to the standard four-function calculator and check balancing programs. By using the standard library, students can gain the satisfaction of working on realistic applications as they learn the fundamentals of programming. Using the standard library also teaches students about code reuse. Third-party modules such as PyGame are also helpful in extending the students' reach.

Python's interactive interpreter enables students to test language features while they're programming. They can keep a window with the interpreter running while they enter their program's source in another window. If they can't remember the methods for a list, they can do something like this:

>>> L = []
>>> dir(L)
['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove',
'reverse', 'sort']
>>> help(L.append)
Help on built-in function append:

append(...)
    L.append(object) -- append object to end
>>> L.append(1)
>>> L
[1]

With the interpreter, documentation is never far from the student as he's programming.

There are also good IDEs for Python. IDLE is a cross-platform IDE for Python that is written in Python using Tkinter. PythonWin is a Windows-specific IDE. Emacs users will be happy to know that there is a very good Python mode for Emacs. All of these programming environments provide syntax highlighting, auto-indenting, and access to the interactive interpreter while coding. Consult http://www.python.org/editors/ for a full list of Python editing environments.

3   Upgrading Python

3.1   What is this bsddb185 module my application keeps complaining about?

Starting with Python2.3, the distribution includes the PyBSDDB package <http://pybsddb.sf.net/> as a replacement for the old bsddb module. It includes functions which provide backward compatibility at the API level, but requires a newer version of the underlying Berkeley DB library. Files created with the older bsddb module can't be opened directly using the new module.

Using your old version of Python and a pair of scripts which are part of Python 2.3 (db2pickle.py and pickle2db.py, in the Tools/scripts directory) you can convert your old database files to the new format. Using your old Python version, run the db2pickle.py script to convert it to a pickle, e.g.:

python2.2 <pathto>/db2pickley.py database.db database.pck

Rename your database file:

mv database.db olddatabase.db

Now convert the pickle file to a new format database:

python2.3 <pathto>/pickle2db.py database.db database.pck

The precise commands you use will vary depending on the particulars of your installation. For full details about operation of these two scripts check the doc string at the start of each one.

4   Python's Design

4.1   Why does Python use indentation for grouping of statements?

Guido van Rossum believes that using indentation for grouping is extremely elegant and contributes a lot to the clarity of the average Python program. Most people learn to love this feature after awhile.

Since there are no begin/end brackets there cannot be a disagreement between grouping perceived by the parser and the human reader. Occasionally C programmers will encounter a fragment of code like this:

if (x <= y)
        x++;
        y--;
z++;

Only the x++ statement is executed if the condition is true, but the indentation leads you to believe otherwise. Even experienced C programmers will sometimes stare a long time at it wondering why y is being decremented even for x > y.

Because there are no begin/end brackets, Python is much less prone to coding-style conflicts. In C there are many different ways to place the braces. If you're used to reading and writing code that uses one style, you will feel at least slightly uneasy when reading (or being required to write) another style.

Many coding styles place begin/end brackets on a line by themself. This makes programs considerably longer and wastes valuable screen space, making it harder to get a good overview of a program. Ideally, a function should fit on onescreen (say, 20-30 lines). 20 lines of Python can do a lot more work than 20 lines of C. This is not solely due to the lack of begin/end brackets -- the lack of declarations and the high-level data types are also responsible -- but the indentation-based syntax certainly helps.

4.3   Why are floating point calculations so inaccurate?

People are often very surprised by results like this:

>>> 1.2-1.0
0.199999999999999996

and think it is a bug in Python. It's not. It's a problem caused by the internal representation of floating point numbers, which uses a fixed number of binary digits to represent a decimal number. Some decimal numbers can't be represented exactly in binary, resulting in small roundoff errors.

In decimal math, there are many numbers that can't be represented with a fixed number of decimal digits, e.g. 1/3 = 0.3333333333.......

In base 2, 1/2 = 0.1, 1/4 = 0.01, 1/8 = 0.001, etc. .2 equals 2/10 equals 1/5, resulting in the binary fractional number 0.001100110011001...

Floating point numbers only have 32 or 64 bits of precision, so the digits are cut off at some point, and the resulting number is 0.199999999999999996 in decimal, not 0.2.

A floating point's repr() function prints as many digits are necessary to make eval(repr(f)) == f true for any float f. The str() function prints fewer digits and this often results in the more sensible number that was probably intended:

>>> 0.2
0.20000000000000001
>>> print 0.2
0.2

Again, this has nothing to do with Python, but with the way the underlying C platform handles floating point numbers, and ultimately with the inaccuracy you'll always have when writing down numbers as a string of a fixed number of digits.

One of the consequences of this is that it is dangerous to compare the result of some computation to a float with == ! Tiny inaccuracies may mean that == fails. Instead, you have to check that the difference between the two numbers is less than a certain threshold:

epsilon = 0.0000000000001 # Tiny allowed error
expected_result = 0.4

if expected_result-epsilon <= computation() <= expected_result+epsilon:
   ...

Please see the chapter on floating point arithmetic in the Python tutorial for more information.

4.4   Why are Python strings immutable?

There are several advantages.

One is performance: knowing that a string is immutable makes it easy to lay it out at construction time -- fixed and unchanging storage requirements. This is also one of the reasons for the distinction between tuples and lists.

The other is that strings in Python are considered as "elemental" as numbers. No amount of activity will change the value 8 to anything else, and in Python, no amount of activity will change the string "eight" to anything else.

4.5   Why must 'self' be used explicitly in method definitions and calls?

The idea was borrowed from Modula-3. It turns out to be very useful, for a variety of reasons.

First, it's more obvious that you are using a method or instance attribute instead of a local variable. Reading self.x or self.meth() makes it absolutely clear that an instance variable or method is used even if you don't know the class definition by heart. In C++, you can sort of tell by the lack of a local variable declaration (assuming globals are rare or easily recognizable) -- but in Python, there are no local variable declarations, so you'd have to look up the class definition to be sure. Some C++ and Java coding standards call for instance attributes to have an m_ prefix, so this explicitness is still useful in those languages, too.

Second, it means that no special syntax is necessary if you want to explicitly reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have to use the :: operator -- in Python you can write baseclass.methodname(self, <argument list>). This is particularly useful for __init__() methods, and in general in cases where a derived class method wants to extend the base class method of the same name and thus has to call the base class method somehow.

Finally, for instance variables it solves a syntactic problem with assignment: since local variables in Python are (by definition!) those variables to which a value assigned in a function body (and that aren't explicitly declared global), there has to be some way to tell the interpreter that an assignment was meant to assign to an instance variable instead of to a local variable, and it should preferably be syntactic (for efficiency reasons). C++ does this through declarations, but Python doesn't have declarations and it would be a pity having to introduce them just for this purpose. Using the explicit "self.var" solves this nicely. Similarly, for using instance variables, having to write "self.var" means that references to unqualified names inside a method don't have to search the instance's directories. To put it another way, local variables and instance variables live in two different namespaces, and you need to tell Python which namespace to use.

4.6   Why can't I use an assignment in an expression?

Many people used to C or Perl complain that they want to use this C idiom:

while (line = readline(f)) {
    ...do something with line...
}

where in Python you're forced to write this:

while True:
    line = f.readline()
    if not line:
        break
    ...do something with line...

The reason for not allowing assignment in Python expressions is a common, hard-to-find bug in those other languages, caused by this construct:

if (x = 0) {
    ...error handling...
}
else {
    ...code that only works for nonzero x...
}

The error is a simple typo: x = 0, which assigns 0 to the variable x, was written while the comparison x == 0 is certainly what was intended.

Many alternatives have been proposed. Most are hacks that save some typing but use arbitrary or cryptic syntax or keywords, and fail the simple criterion for language change proposals: it should intuitively suggest the proper meaning to a human reader who has not yet been introduced to the construct.

An interesting phenomenon is that most experienced Python programmers recognize the "while True" idiom and don't seem to be missing the assignment in expression construct much; it's only newcomers who express a strong desire to add this to the language.

There's an alternative way of spelling this that seems attractive but is generally less robust than the "while True" solution:

line = f.readline()
while line:
    ...do something with line...
    line = f.readline()

The problem with this is that if you change your mind about exactly how you get the next line (e.g. you want to change it into sys.stdin.readline()) you have to remember to change two places in your program -- the second occurrence is hidden at the bottom of the loop.

The best approach is to use iterators, making it possible to loop through objects using the for statement. For example, in the current version of Python file objects support the iterator protocol, so you can now write simply:

for line in f:
    ... do something with line...

4.7   Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))?

The major reason is history. Functions were used for those operations that were generic for a group of types and which were intended to work even for objects that didn't have methods at all (e.g. tuples). It is also convenient to have a function that can readily be applied to an amorphous collection of objects when you use the functional features of Python (map(), apply() et al).

In fact, implementing len(), max(), min() as a built-in function is actually less code than implementing them as methods for each type. One can quibble about individual cases but it's a part of Python, and it's too late to make such fundamental changes now. The functions have to remain to avoid massive code breakage.

Note that for string operations Python has moved from external functions (the string module) to methods. However, len() is still a function.

4.8   Why is join() a string method instead of a list or tuple method?

Strings became much more like other standard types starting in Python 1.6, when methods were added which give the same functionality that has always been available using the functions of the string module. Most of these new methods have been widely accepted, but the one which appears to make some programmers feel uncomfortable is:

", ".join(['1', '2', '4', '8', '16'])

which gives the result:

"1, 2, 4, 8, 16"

There are two usual arguments against this usage.

The first runs along the lines of: "It looks really ugly using a method of a string literal (string constant)", to which the answer is that it might, but a string literal is just a fixed value. If the methods are to be allowed on names bound to strings there is no logical reason to make them unavailable on literals.

The second objection is typically cast as: "I am really telling a sequence to join its members together with a string constant". Sadly, you aren't. For some reason there seems to be much less difficulty with having split() as a string method, since in that case it is easy to see that

"1, 2, 4, 8, 16".split(", ")

is an instruction to a string literal to return the substrings delimited by the given separator (or, by default, arbitrary runs of white space). In this case a Unicode string returns a list of Unicode strings, an ASCII string returns a list of ASCII strings, and everyone is happy.

join() is a string method because in using it you are telling the separator string to iterate over an arbitrary sequence, forming string representations of each of the elements, and inserting itself between the elements' representations. This method can be used with any argument which obeys the rules for sequence objects, inluding any new classes you might define yourself.

Because this is a string method it can work for Unicode strings as well as plain ASCII strings. If join() were a method of the sequence types then the sequence types would have to decide which type of string to return depending on the type of the separator.

If none of these arguments persuade you, then for the moment you can continue to use the join() function from the string module, which allows you to write

string.join(['1', '2', '4', '8', '16'], ", ")

4.9   How fast are exceptions?

A try/except block is extremely efficient. Actually executing an exception is expensive. In versions of Python prior to 2.0 it was common to use this idiom:

try:
    value = dict[key]
except KeyError:
    dict[key] = getvalue(key)
    value = dict[key]

This only made sense when you expected the dict to have the key almost all the time. If that wasn't the case, you coded it like this:

if dict.has_key(key):
    value = dict[key]
else:
    dict[key] = getvalue(key)
    value = dict[key]

(In Python 2.0 and higher, you can code this as value = dict.setdefault(key, getvalue(key)).)

4.10   Why isn't there a switch or case statement in Python?

You can do this easily enough with a sequence of if... elif... elif... else. There have been some proposals for switch statement syntax, but there is no consensus (yet) on whether and how to do range tests. See PEP 275 for complete details and the current status.

For cases where you need to choose from a very large number of possibilities, you can create a dictionary mapping case values to functions to call. For example:

def function_1 (...):
    ...

functions = {'a': function_1,
             'b': function_2,
             'c': self.method_1, ...}

func = functions[value]
func()

For calling methods on objects, you can simplify yet further by using the getattr() built-in to retrieve methods with a particular name:

def visit_a (self, ...):
    ...
...

def dispatch (self, value):
    method_name = 'visit_' + str(value)
    method = getattr(self, method_name)
    method()

It's suggested that you use a prefix for the method names, such as visit_ in this example. Without such a prefix, if values are coming from an untrusted source, an attacker would be able to call any method on your object.

4.11   Can't you emulate threads in the interpreter instead of relying on an OS-specific thread implementation?

Answer 1: Unfortunately, the interpreter pushes at least one C stack frame for each Python stack frame. Also, extensions can call back into Python at almost random moments. Therefore, a complete threads implementation requires thread support for C.

Answer 2: Fortunately, there is Stackless Python, which has a completely redesigned interpreter loop that avoids the C stack. It's still experimental but looks very promising. Although it is binary compatible with standard Python, it's still unclear whether Stackless will make it into the core -- maybe it's just too revolutionary.

4.12   Why can't lambda forms contain statements?

Python lambda forms cannot contain statements because Python's syntactic framework can't handle statements nested inside expressions. However, in Python, this is not a serious problem. Unlike lambda forms in other languages, where they add functionality, Python lambdas are only a shorthand notation if you're too lazy to define a function.

Functions are already first class objects in Python, and can be declared in a local scope. Therefore the only advantage of using a lambda form instead of a locally-defined function is that you don't need to invent a name for the function -- but that's just a local variable to which the function object (which is exactly the same type of object that a lambda form yields) is assigned!

4.13   Can Python be compiled to machine code, C or some other language?

Not easily. Python's high level data types, dynamic typing of objects and run-time invocation of the interpreter (using eval() or exec) together mean that a "compiled" Python program would probably consist mostly of calls into the Python run-time system, even for seemingly simple operations like x+1.

Several projects described in the Python newsgroup or at past Python conferences have shown that this approach is feasible, although the speedups reached so far are only modest (e.g. 2x). Jython uses the same strategy for compiling to Java bytecode. (Jim Hugunin has demonstrated that in combination with whole-program analysis, speedups of 1000x are feasible for small demo programs. See the proceedings from the 1997 Python conference for more information.)

Internally, Python source code is always translated into a bytecode representation, and this bytecode is then executed by the Python virtual machine. In order to avoid the overhead of repeatedly parsing and translating modules that rarely change, this byte code is written into a file whose name ends in ".pyc" whenever a module is parsed. When the corresponding .py file is changed, it is parsed and translated again and the .pyc file is rewritten.

There is no performance difference once the .pyc file has been loaded, as the bytecode read from the .pyc file is exactly the same as the bytecode created by direct translation. The only difference is that loading code from a .pyc file is faster than parsing and translating a .py file, so the presence of precompiled .pyc files improves the start-up time of Python scripts. If desired, the Lib/compileall.py module can be used to create valid .pyc files for a given set of modules.

Note that the main script executed by Python, even if its filename ends in .py, is not compiled to a .pyc file. It is compiled to bytecode, but the bytecode is not saved to a file. Usually main scripts are quite short, so this doesn't cost much speed.

There are also several programs which make it easier to intermingle Python and C code in various ways to increase performance. See, for example, Psyco, Pyrex, PyInline, Py2Cmod, and Weave.

4.14   How does Python manage memory?

The details of Python memory management depend on the implementation. The standard C implementation of Python uses reference counting to detect inaccessible objects, and another mechanism to collect reference cycles, periodically executing a cycle detection algorithm which looks for inaccessible cycles and deletes the objects involved. The gc module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector's parameters.

Jython relies on the Java runtime so the JVM's garbage collector is used. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation.

Sometimes objects get stuck in tracebacks temporarily and hence are not deallocated when you might expect. Clear the tracebacks with:

import sys
sys.exc_clear()
sys.exc_traceback = sys.last_traceback = None

Tracebacks are used for reporting errors, implementing debuggers and related things. They contain a portion of the program state extracted during the handling of an exception (usually the most recent exception).

In the absence of circularities and tracebacks, Python programs need not explicitly manage memory.

Why doesn't Python use a more traditional garbage collection scheme? For one thing, this is not a C standard feature and hence it's not portable. (Yes, we know about the Boehm GC library. It has bits of assembler code for most common platforms, not for all of them, and although it is mostly transparent, it isn't completely transparent; patches are required to get Python to work with it.)

Traditional GC also becomes a problem when Python is embedded into other applications. While in a standalone Python it's fine to replace the standard malloc() and free() with versions provided by the GC library, an application embedding Python may want to have its own substitute for malloc() and free(), and may not want Python's. Right now, Python works with anything that implements malloc() and free() properly.

In Jython, the following code (which is fine in CPython) will probably run out of file descriptors long before it runs out of memory:

for file in <very long list of files>:
    f = open(file)
    c = f.read(1)

Using the current reference counting and destructor scheme, each new assignment to f closes the previous file. Using GC, this is not guaranteed. If you want to write code that will work with any Python implementation, you should explicitly close the file; this will work regardless of GC:

for file in <very long list of files>:
    f = open(file)
    c = f.read(1)
    f.close()

4.15   Why isn't all memory freed when Python exits?

Objects referenced from the global namespaces of Python modules are not always deallocated when Python exits. This may happen if there are circular references. There are also certain bits of memory that are allocated by the C library that are impossible to free (e.g. a tool like Purify will complain about these). Python is, however, aggressive about cleaning up memory on exit and does try to destroy every single object.

If you want to force Python to delete certain things on deallocation use the sys.exitfunc() hook to run a function that will force those deletions.

4.16   Why are there separate tuple and list data types?

Lists and tuples, while similar in many respects, are generally used in fundamentally different ways. Tuples can be thought of as being similar to Pascal records or C structs; they're small collections of related data which may be of different types which are operated on as a group. For example, a Cartesian coordinate is appropriately represented as a tuple of two or three numbers.

Lists, on the other hand, are more like arrays in other languages. They tend to hold a varying number of objects all of which have the same type and which are operated on one-by-one. For example, os.listdir('.') returns a list of strings representing the files in the current directory. Functions which operate on this output would generally not break if you added another file or two to the directory.

Tuples are immutable, meaning that once a tuple has been created, you can't replace any of its elements with a new value. Lists are mutable, meaning that you can always change a list's elements. Only immutable elements can be used as dictionary keys, and hence only tuples and not lists can be used as keys.

4.17   How are lists implemented?

Python's lists are really variable-length arrays, not Lisp-style linked lists. The implementation uses a contiguous array of references to other objects, and keeps a pointer to this array and the array's length in a list head structure.

This makes indexing a list a[i] an operation whose cost is independent of the size of the list or the value of the index.

When items are appended or inserted, the array of references is resized. Some cleverness is applied to improve the performance of appending items repeatedly; when the array must be grown, some extra space is allocated so the next few times don't require an actual resize.

4.18   How are dictionaries implemented?

Python's dictionaries are implemented as resizable hash tables. Compared to B-trees, this gives better performance for lookup (the most common operation by far) under most circumstances, and the implementation is simpler.

Dictionaries work by computing a hash code for each key stored in the dictionary using the hash() built-in function. The hash code varies widely depending on the key; for example, "Python" hashes to -539294296 while "python", a string that differs by a single bit, hashes to 1142331976. The hash code is then used to calculate a location in an internal array where the value will be stored. Assuming that you're storing keys that all have different hash values, this means that dictionaries take constant time -- O(1), in computer science notation -- to retrieve a key. It also means that no sorted order of the keys is maintained, and traversing the array as the .keys() and .items() do will output the dictionary's content in some arbitrary jumbled order.

4.19   Why must dictionary keys be immutable?

The hash table implementation of dictionaries uses a hash value calculated from the key value to find the key. If the key were a mutable object, its value could change, and thus its hash could also change. But since whoever changes the key object can't tell that it was being used as a dictionary key, it can't move the entry around in the dictionary. Then, when you try to look up the same object in the dictionary it won't be found because its hash value is different. If you tried to look up the old value it wouldn't be found either, because the value of the object found in that hash bin would be different.

If you want a dictionary indexed with a list, simply convert the list to a tuple first; the function tuple(L) creates a tuple with the same entries as the list L. Tuples are immutable and can therefore be used as dictionary keys.

Some unacceptable solutions that have been proposed:

  • Hash lists by their address (object ID). This doesn't work because if you construct a new list with the same value it won't be found; e.g.:

    d = {[1,2]: '12'}
    print d[[1,2]]
    

    would raise a KeyError exception because the id of the [1,2] used in the second line differs from that in the first line. In other words, dictionary keys should be compared using ==, not using 'is'.

  • Make a copy when using a list as a key. This doesn't work because the list, being a mutable object, could contain a reference to itself, and then the copying code would run into an infinite loop.

  • Allow lists as keys but tell the user not to modify them. This would allow a class of hard-to-track bugs in programs when you forgot or modified a list by accident. It also invalidates an important invariant of dictionaries: every value in d.keys() is usable as a key of the dictionary.

  • Mark lists as read-only once they are used as a dictionary key. The problem is that it's not just the top-level object that could change its value; you could use a tuple containing a list as a key. Entering anything as a key into a dictionary would require marking all objects reachable from there as read-only -- and again, self-referential objects could cause an infinite loop.

There is a trick to get around this if you need to, but use it at your own risk: You can wrap a mutable structure inside a class instance which has both a __cmp__ and a __hash__ method. You must then make sure that the hash value for all such wrapper objects that reside in a dictionary (or other hash based structure), remain fixed while the object is in the dictionary (or other structure).:

class ListWrapper:
     def __init__(self, the_list):
           self.the_list = the_list
     def __cmp__(self, other):
           return self.the_list == other.the_list
     def __hash__(self):
           l = self.the_list
           result = 98767 - len(l)*555
           for i in range(len(l)):
                try:
                     result = result + (hash(l[i]) % 9999999) * 1001 + i
                except:
                     result = (result % 7777777) + i * 333
           return result

Note that the hash computation is complicated by the possibility that some members of the list may be unhashable and also by the possibility of arithmetic overflow.

Furthermore it must always be the case that if o1 == o2 (ie o1.__cmp__(o2)==0) then hash(o1)==hash(o2) (ie, o1.__hash__() == o2.__hash__()), regardless of whether the object is in a dictionary or not. If you fail to meet these restrictions dictionaries and other hash based structures will misbehave.

In the case of ListWrapper, whenever the wrapper object is in a dictionary the wrapped list must not change to avoid anomalies. Don't do this unless you are prepared to think hard about the requirements and the consequences of not meeting them correctly. Consider yourself warned.

4.20   Why doesn't list.sort() return the sorted list?

In situations where performance matters, making a copy of the list just to sort it would be wasteful. Therefore, list.sort() sorts the list in place. In order to remind you of that fact, it does not return the sorted list. This way, you won't be fooled into accidentally overwriting a list when you need a sorted copy but also need to keep the unsorted version around.

In Python 2.4 a new builtin - sorted() - has been added. This function creates a new list from a passed iterable, sorts it and returns it.

As a result, here's the idiom to iterate over the keys of a dictionary in sorted order:

for key in sorted(dict.iterkeys()):
    ...do whatever with dict[key]...

Versions of Python prior to 2.4 need to use the following idiom:

keys = dict.keys()
keys.sort()
for key in keys:
    ...do whatever with dict[key]...

4.21   How do you specify and enforce an interface spec in Python?

An interface specification for a module as provided by languages such as C++ and Java describes the prototypes for the methods and functions of the module. Many feel that compile-time enforcement of interface specifications help in the construction of large programs. Python does not support interface specifications directly, but many of their advantages can be obtained by an appropriate test discipline for components, which can often be very easily accomplished in Python. There is also a tool, PyChecker, which can be used to find problems due to subclassing.

A good test suite for a module can at once provide a regression test and serve as both a module interface specification and a set of examples. Many Python modules can be run as a script to provide a simple "self test." Even modules which use complex external interfaces can often be tested in isolation using trivial "stub" emulations of the external interface. The doctest and unittest modules or third-party test frameworks can be used to construct exhaustive test suites that exercise every line of code in a module.

An appropriate testing discipline can help build large complex applications in Python as well as having interface specifications would. In fact, it can be better because an interface specification cannot test certain properties of a program. For example, the append() method is expected to add new elements to the end of some internal list; an interface specification cannot test that your append() implementation will actually do this correctly, but it's trivial to check this property in a test suite.

Writing test suites is very helpful, and you might want to design your code with an eye to making it easily tested. One increasingly popular technique, test-directed development, calls for writing parts of the test suite first, before you write any of the actual code. Of course Python allows you to be sloppy and not write test cases at all.

4.22   Why are default values shared between objects?

This type of bug commonly bites neophyte programmers. Consider this function:

def foo(D={}):  # Danger: shared reference to one dict for all calls
    ... compute something ...
    D[key] = value
    return D

The first time you call this function, D contains a single item. The second time, D contains two items because when foo() begins executing, D starts out with an item already in it.

It is often expected that a function call creates new objects for default values. This is not what happens. Default values are created exactly once, when the function is defined. If that object is changed, like the dictionary in this example, subsequent calls to the function will refer to this changed object.

By definition, immutable objects such as numbers, strings, tuples, and None, are safe from change. Changes to mutable objects such as dictionaries, lists, and class instances can lead to confusion.

Because of this feature, it is good programming practice to not use mutable objects as default values. Instead, use None as the default value and inside the function, check if the parameter is None and create a new list/dictionary/whatever if it is. For example, don't write:

def foo(dict={}):
    ...

but:

def foo(dict=None):
    if dict is None:
        dict = {} # create a new dict for local namespace

This feature can be useful. When you have a function that's time-consuming to compute, a common technique is to cache the parameters and the resulting value of each call to the function, and return the cached value if the same value is requested again. This is called "memoizing", and can be implemented like this:

# Callers will never provide a third parameter for this function.
def expensive (arg1, arg2, _cache={}):
    if _cache.has_key((arg1, arg2)):
        return _cache[(arg1, arg2)]

    # Calculate the value
    result = ... expensive computation ...
    _cache[(arg1, arg2)] = result           # Store result in the cache
    return result

You could use a global variable containing a dictionary instead of the default value; it's a matter of taste.

4.23   Why is there no goto?

You can use exceptions to provide a "structured goto" that even works across function calls. Many feel that exceptions can conveniently emulate all reasonable uses of the "go" or "goto" constructs of C, Fortran, and other languages. For example:

class label: pass # declare a label

try:
     ...
     if (condition): raise label() # goto label
     ...
except label: # where to goto
     pass
...

This doesn't allow you to jump into the middle of a loop, but that's usually considered an abuse of goto anyway. Use sparingly.

4.24   Why do I get a SyntaxError for a 'continue' inside a 'try'?

This is an implementation limitation, caused by the extremely simple-minded way Python generates bytecode. The try block pushes something on the "block stack" which the continue would have to pop off again. The current code generator doesn't have the data structures around so that continue can generate the right code.

Note that Jython doesn't have this restriction!

4.25   Why can't raw strings (r-strings) end with a backslash?

More precisely, they can't end with an odd number of backslashes: the unpaired backslash at the end escapes the closing quote character, leaving an unterminated string.

Raw strings were designed to ease creating input for processors (chiefly regular expression engines) that want to do their own backslash escape processing. Such processors consider an unmatched trailing backslash to be an error anyway, so raw strings disallow that. In return, they allow you to pass on the string quote character by escaping it with a backslash. These rules work well when r-strings are used for their intended purpose.

If you're trying to build Windows pathnames, note that all Windows system calls accept forward slashes too:

f = open("/mydir/file.txt") # works fine!

If you're trying to build a pathname for a DOS command, try e.g. one of

dir = r"\this\is\my\dos\dir" "\\"
dir = r"\this\is\my\dos\dir\ "[:-1]
dir = "\\this\\is\\my\\dos\\dir\\"

4.26   Why doesn't Python have a "with" statement like some other languages?

Because such a construct would be ambiguous.

Some languages, such as Object Pascal, Delphi, and C++, use static types. So it is possible to know, in an unambiguous way, what member is being assigned in a "with" clause. This is the main point - the compiler always knows the scope of every variable at compile time.

Python uses dynamic types. It is impossible to know in advance which attribute will be referenced at runtime. Member attributes may be added or removed from objects on the fly. This would make it impossible to know, from a simple reading, what attribute is being referenced - a local one, a global one, or a member attribute.

For instance, take the following incomplete snippet:

def foo(a):
   with a:
      print x

The snippet assumes that "a" must have a member attribute called "x". However, there is nothing in Python that guarantees that. What should happen if "a" is, let us say, an integer? And if I have a global variable named "x", will it end up being used inside the with block? As you see, the dynamic nature of Python makes such choices much harder.

The primary benefit of "with" and similar language features (reduction of code volume) can, however, easily be achieved in Python by assignment. Instead of:

function(args).dict[index][index].a = 21
function(args).dict[index][index].b = 42
function(args).dict[index][index].c = 63

write this:

ref = function(args).dict[index][index]
ref.a = 21
ref.b = 42
ref.c = 63

This also has the side-effect of increasing execution speed because name bindings are resolved at run-time in Python, and the second version only needs to perform the resolution once. If the referenced object does not have a, b and c attributes, of course, the end result is still a run-time exception.

4.27   Why are colons required for the if/while/def/class statements?

The colon is required primarily to enhance readability (one of the results of the experimental ABC language). Consider this:

if a==b
    print a

versus

if a==b:
    print a

Notice how the second one is slightly easier to read. Notice further how a colon sets off the example in the second line of this FAQ answer; it's a standard usage in English.

Another minor reason is that the colon makes it easier for editors with syntax highlighting; they can look for colons to decide when indentation needs to be increased instead of having to do a more elaborate parsing of the program text.

python-defaults-2.7.12/faq/library.ht0000664000000000000000000010306012057417145014377 0ustar Title: Python Library and Extension FAQ Content-type: text/x-rst ==================================== Python Library and Extension FAQ ==================================== :Date: $Date: 2005-12-16 19:21:20 -0700 (Fri, 16 Dec 2005) $ :Version: $Revision: 8684 $ :Web site: http://www.python.org/ .. contents:: .. sectnum:: General Library Questions =============================== How do I find a module or application to perform task X? ------------------------------------------------------------- Check `the Library Reference `_ to see if there's a relevant standard library module. (Eventually you'll learn what's in the standard library and will able to skip this step.) Search the `Python Package Index `_. Next, check the `Vaults of Parnassus `_, an older index of packages. Finally, try `Google `_ or other Web search engine. Searching for "Python" plus a keyword or two for your topic of interest will usually find something helpful. Where is the math.py (socket.py, regex.py, etc.) source file? --------------------------------------------------------------------- If you can't find a source file for a module it may be a builtin or dynamically loaded module implemented in C, C++ or other compiled language. In this case you may not have the source file or it may be something like mathmodule.c, somewhere in a C source directory (not on the Python Path). There are (at least) three kinds of modules in Python: 1) modules written in Python (.py); 2) modules written in C and dynamically loaded (.dll, .pyd, .so, .sl, etc); 3) modules written in C and linked with the interpreter; to get a list of these, type:: import sys print sys.builtin_module_names How do I make a Python script executable on Unix? --------------------------------------------------------- You need to do two things: the script file's mode must be executable and the first line must begin with ``#!`` followed by the path of the Python interpreter. The first is done by executing ``chmod +x scriptfile`` or perhaps ``chmod 755 scriptfile``. The second can be done in a number of ways. The most straightforward way is to write :: #!/usr/local/bin/python as the very first line of your file, using the pathname for where the Python interpreter is installed on your platform. If you would like the script to be independent of where the Python interpreter lives, you can use the "env" program. Almost all Unix variants support the following, assuming the python interpreter is in a directory on the user's $PATH:: #! /usr/bin/env python *Don't* do this for CGI scripts. The $PATH variable for CGI scripts is often very minimal, so you need to use the actual absolute pathname of the interpreter. Occasionally, a user's environment is so full that the /usr/bin/env program fails; or there's no env program at all. In that case, you can try the following hack (due to Alex Rezinsky):: #! /bin/sh """:" exec python $0 ${1+"$@"} """ The minor disadvantage is that this defines the script's __doc__ string. However, you can fix that by adding :: __doc__ = """...Whatever...""" Is there a curses/termcap package for Python? ---------------------------------------------------- For Unix variants: The standard Python source distribution comes with a curses module in the Modules/ subdirectory, though it's not compiled by default (note that this is not available in the Windows distribution -- there is no curses module for Windows). The curses module supports basic curses features as well as many additional functions from ncurses and SYSV curses such as colour, alternative character set support, pads, and mouse support. This means the module isn't compatible with operating systems that only have BSD curses, but there don't seem to be any currently maintained OSes that fall into this category. For Windows: use `the consolelib module `_. Is there an equivalent to C's onexit() in Python? -------------------------------------------------------- `The atexit module `_ provides a register function that is similar to C's onexit. Why don't my signal handlers work? -------------------------------------------- The most common problem is that the signal handler is declared with the wrong argument list. It is called as :: handler(signum, frame) so it should be declared with two arguments:: def handler(signum, frame): ... Common tasks ================= How do I test a Python program or component? ---------------------------------------------------- Python comes with two testing frameworks. The `doctest module `_ finds examples in the docstrings for a module and runs them, comparing the output with the expected output given in the docstring. The `unittest module `_ is a fancier testing framework modelled on Java and Smalltalk testing frameworks. For testing, it helps to write the program so that it may be easily tested by using good modular design. Your program should have almost all functionality encapsulated in either functions or class methods -- and this sometimes has the surprising and delightful effect of making the program run faster (because local variable accesses are faster than global accesses). Furthermore the program should avoid depending on mutating global variables, since this makes testing much more difficult to do. The "global main logic" of your program may be as simple as :: if __name__=="__main__": main_logic() at the bottom of the main module of your program. Once your program is organized as a tractable collection of functions and class behaviours you should write test functions that exercise the behaviours. A test suite can be associated with each module which automates a sequence of tests. This sounds like a lot of work, but since Python is so terse and flexible it's surprisingly easy. You can make coding much more pleasant and fun by writing your test functions in parallel with the "production code", since this makes it easy to find bugs and even design flaws earlier. "Support modules" that are not intended to be the main module of a program may include a self-test of the module. :: if __name__ == "__main__": self_test() Even programs that interact with complex external interfaces may be tested when the external interfaces are unavailable by using "fake" interfaces implemented in Python. How do I create documentation from doc strings? ------------------------------------------------------- The `pydoc module `_ can create HTML from the doc strings in your Python source code. An alternative is `pythondoc `_. How do I get a single keypress at a time? ----------------------------------------------- For Unix variants:There are several solutions. It's straightforward to do this using curses, but curses is a fairly large module to learn. Here's a solution without curses:: import termios, fcntl, sys, os fd = sys.stdin.fileno() oldterm = termios.tcgetattr(fd) newattr = termios.tcgetattr(fd) newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO termios.tcsetattr(fd, termios.TCSANOW, newattr) oldflags = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK) try: while 1: try: c = sys.stdin.read(1) print "Got character", `c` except IOError: pass finally: termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm) fcntl.fcntl(fd, fcntl.F_SETFL, oldflags) You need the ``termios`` and the ``fcntl`` module for any of this to work, and I've only tried it on Linux, though it should work elsewhere. In this code, characters are read and printed one at a time. ``termios.tcsetattr()`` turns off stdin's echoing and disables canonical mode. ``fcntl.fnctl()`` is used to obtain stdin's file descriptor flags and modify them for non-blocking mode. Since reading stdin when it is empty results in an ``IOError``, this error is caught and ignored. Threads ============= How do I program using threads? --------------------------------- Be sure to use `the threading module `_ and not the ``thread`` module. The ``threading`` module builds convenient abstractions on top of the low-level primitives provided by the ``thread`` module. Aahz has a set of slides from his threading tutorial that are helpful; see http://starship.python.net/crew/aahz/OSCON2001/. None of my threads seem to run: why? ------------------------------------------- As soon as the main thread exits, all threads are killed. Your main thread is running too quickly, giving the threads no time to do any work. A simple fix is to add a sleep to the end of the program that's long enough for all the threads to finish:: import threading, time def thread_task(name, n): for i in range(n): print name, i for i in range(10): T = threading.Thread(target=thread_task, args=(str(i), i)) T.start() time.sleep(10) # <----------------------------! But now (on many platforms) the threads don't run in parallel, but appear to run sequentially, one at a time! The reason is that the OS thread scheduler doesn't start a new thread until the previous thread is blocked. A simple fix is to add a tiny sleep to the start of the run function:: def thread_task(name, n): time.sleep(0.001) # <---------------------! for i in range(n): print name, i for i in range(10): T = threading.Thread(target=thread_task, args=(str(i), i)) T.start() time.sleep(10) Instead of trying to guess how long a ``time.sleep()`` delay will be enough, it's better to use some kind of semaphore mechanism. One idea is to use the `Queue module `_ to create a queue object, let each thread append a token to the queue when it finishes, and let the main thread read as many tokens from the queue as there are threads. How do I parcel out work among a bunch of worker threads? ---------------------------------------------------------------- Use the `Queue module `_ to create a queue containing a list of jobs. The ``Queue`` class maintains a list of objects with ``.put(obj)`` to add an item to the queue and ``.get()`` to return an item. The class will take care of the locking necessary to ensure that each job is handed out exactly once. Here's a trivial example:: import threading, Queue, time # The worker thread gets jobs off the queue. When the queue is empty, it # assumes there will be no more work and exits. # (Realistically workers will run until terminated.) def worker (): print 'Running worker' time.sleep(0.1) while True: try: arg = q.get(block=False) except Queue.Empty: print 'Worker', threading.currentThread(), print 'queue empty' break else: print 'Worker', threading.currentThread(), print 'running with argument', arg time.sleep(0.5) # Create queue q = Queue.Queue() # Start a pool of 5 workers for i in range(5): t = threading.Thread(target=worker, name='worker %i' % (i+1)) t.start() # Begin adding work to the queue for i in range(50): q.put(i) # Give threads time to run print 'Main thread sleeping' time.sleep(5) When run, this will produce the following output: Running worker Running worker Running worker Running worker Running worker Main thread sleeping Worker running with argument 0 Worker running with argument 1 Worker running with argument 2 Worker running with argument 3 Worker running with argument 4 Worker running with argument 5 ... Consult the module's documentation for more details; the ``Queue`` class provides a featureful interface. What kinds of global value mutation are thread-safe? ------------------------------------------------------------ A global interpreter lock (GIL) is used internally to ensure that only one thread runs in the Python VM at a time. In general, Python offers to switch among threads only between bytecode instructions; how frequently it switches can be set via ``sys.setcheckinterval()``. Each bytecode instruction and therefore all the C implementation code reached from each instruction is therefore atomic from the point of view of a Python program. In theory, this means an exact accounting requires an exact understanding of the PVM bytecode implementation. In practice, it means that operations on shared variables of builtin data types (ints, lists, dicts, etc) that "look atomic" really are. For example, the following operations are all atomic (L, L1, L2 are lists, D, D1, D2 are dicts, x, y are objects, i, j are ints):: L.append(x) L1.extend(L2) x = L[i] x = L.pop() L1[i:j] = L2 L.sort() x = y x.field = y D[x] = y D1.update(D2) D.keys() These aren't:: i = i+1 L.append(L[-1]) L[i] = L[j] D[x] = D[x] + 1 Operations that replace other objects may invoke those other objects' ``__del__`` method when their reference count reaches zero, and that can affect things. This is especially true for the mass updates to dictionaries and lists. When in doubt, use a mutex! Can't we get rid of the Global Interpreter Lock? -------------------------------------------------------- The Global Interpreter Lock (GIL) is often seen as a hindrance to Python's deployment on high-end multiprocessor server machines, because a multi-threaded Python program effectively only uses one CPU, due to the insistence that (almost) all Python code can only run while the GIL is held. Back in the days of Python 1.5, Greg Stein actually implemented a comprehensive patch set (the "free threading" patches) that removed the GIL and replaced it with fine-grained locking. Unfortunately, even on Windows (where locks are very efficient) this ran ordinary Python code about twice as slow as the interpreter using the GIL. On Linux the performance loss was even worse because pthread locks aren't as efficient. Since then, the idea of getting rid of the GIL has occasionally come up but nobody has found a way to deal with the expected slowdown, and users who don't use threads would not be happy if their code ran at half at the speed. Greg's free threading patch set has not been kept up-to-date for later Python versions. This doesn't mean that you can't make good use of Python on multi-CPU machines! You just have to be creative with dividing the work up between multiple *processes* rather than multiple *threads*. Judicious use of C extensions will also help; if you use a C extension to perform a time-consuming task, the extension can release the GIL while the thread of execution is in the C code and allow other threads to get some work done. It has been suggested that the GIL should be a per-interpreter-state lock rather than truly global; interpreters then wouldn't be able to share objects. Unfortunately, this isn't likely to happen either. It would be a tremendous amount of work, because many object implementations currently have global state. For example, small integers and short strings are cached; these caches would have to be moved to the interpreter state. Other object types have their own free list; these free lists would have to be moved to the interpreter state. And so on. And I doubt that it can even be done in finite time, because the same problem exists for 3rd party extensions. It is likely that 3rd party extensions are being written at a faster rate than you can convert them to store all their global state in the interpreter state. And finally, once you have multiple interpreters not sharing any state, what have you gained over running each interpreter in a separate process? Input and Output ========================= How do I delete a file? (And other file questions...) --------------------------------------------------------- Use ``os.remove(filename)`` or ``os.unlink(filename)``; for documentation, see `the POSIX module `_. The two functions are identical; ``unlink()`` is simply the name of the Unix system call for this function. To remove a directory, use ``os.rmdir()``; use ``os.mkdir()`` to create one. ``os.makedirs(path)`` will create any intermediate directories in ``path`` that don't exist. ``os.removedirs(path)`` will remove intermediate directories as long as they're empty; if you want to delete an entire directory tree and its contents, use ``shutil.rmtree()``. To rename a file, use ``os.rename(old_path, new_path)``. To truncate a file, open it using ``f = open(filename, "r+")``, and use ``f.truncate(offset)``; offset defaults to the current seek position. There's also ```os.ftruncate(fd, offset)`` for files opened with ``os.open()``, where ``fd`` is the file descriptor (a small integer). The ``shutil`` module also contains a number of functions to work on files including ``copyfile``, ``copytree``, and ``rmtree``. How do I copy a file? ----------------------------- The ``shutil`` module contains a ``copyfile()`` function. Note that on MacOS 9 it doesn't copy the resource fork and Finder info. How do I read (or write) binary data? --------------------------------------------- or complex data formats, it's best to use `the struct module `_. It allows you to take a string containing binary data (usually numbers) and convert it to Python objects; and vice versa. For example, the following code reads two 2-byte integers and one 4-byte integer in big-endian format from a file:: import struct f = open(filename, "rb") # Open in binary mode for portability s = f.read(8) x, y, z = struct.unpack(">hhl", s) The '>' in the format string forces big-endian data; the letter 'h' reads one "short integer" (2 bytes), and 'l' reads one "long integer" (4 bytes) from the string. For data that is more regular (e.g. a homogeneous list of ints or thefloats), you can also use `the array module `_. I can't seem to use os.read() on a pipe created with os.popen(); why? ------------------------------------------------------------------------ ``os.read()`` is a low-level function which takes a file descriptor, a small integer representing the opened file. ``os.popen()`` creates a high-level file object, the same type returned by the builtin ``open()`` function. Thus, to read n bytes from a pipe p created with ``os.popen()``, you need to use ``p.read(n)``. How do I run a subprocess with pipes connected to both input and output? -------------------------------------------------------------------------------- Use `the popen2 module `_. For example:: import popen2 fromchild, tochild = popen2.popen2("command") tochild.write("input\n") tochild.flush() output = fromchild.readline() Warning: in general it is unwise to do this because you can easily cause a deadlock where your process is blocked waiting for output from the child while the child is blocked waiting for input from you. This can be caused because the parent expects the child to output more text than it does, or it can be caused by data being stuck in stdio buffers due to lack of flushing. The Python parent can of course explicitly flush the data it sends to the child before it reads any output, but if the child is a naive C program it may have been written to never explicitly flush its output, even if it is interactive, since flushing is normally automatic. Note that a deadlock is also possible if you use ``popen3`` to read stdout and stderr. If one of the two is too large for the internal buffer (increasing the buffer size does not help) and you ``read()`` the other one first, there is a deadlock, too. Note on a bug in popen2: unless your program calls ``wait()`` or ``waitpid()``, finished child processes are never removed, and eventually calls to popen2 will fail because of a limit on the number of child processes. Calling ``os.waitpid`` with the ``os.WNOHANG`` option can prevent this; a good place to insert such a call would be before calling ``popen2`` again. In many cases, all you really need is to run some data through a command and get the result back. Unless the amount of data is very large, the easiest way to do this is to write it to a temporary file and run the command with that temporary file as input. The `standard module tempfile `_ exports a ``mktemp()`` function to generate unique temporary file names. :: import tempfile import os class Popen3: """ This is a deadlock-safe version of popen that returns an object with errorlevel, out (a string) and err (a string). (capturestderr may not work under windows.) Example: print Popen3('grep spam','\n\nhere spam\n\n').out """ def __init__(self,command,input=None,capturestderr=None): outfile=tempfile.mktemp() command="( %s ) > %s" % (command,outfile) if input: infile=tempfile.mktemp() open(infile,"w").write(input) command=command+" <"+infile if capturestderr: errfile=tempfile.mktemp() command=command+" 2>"+errfile self.errorlevel=os.system(command) >> 8 self.out=open(outfile,"r").read() os.remove(outfile) if input: os.remove(infile) if capturestderr: self.err=open(errfile,"r").read() os.remove(errfile) Note that many interactive programs (e.g. vi) don't work well with pipes substituted for standard input and output. You will have to use pseudo ttys ("ptys") instead of pipes. Or you can use a Python interface to Don Libes' "expect" library. A Python extension that interfaces to expect is called "expy" and available from http://expectpy.sourceforge.net. A pure Python solution that works like expect is ` pexpect `_. How do I access the serial (RS232) port? ------------------------------------------------ For Win32, POSIX (Linux, BSD, etc.), Jython: http://pyserial.sourceforge.net For Unix, see a Usenet post by Mitch Chapman: http://groups.google.com/groups?selm=34A04430.CF9@ohioee.com Why doesn't closing sys.stdout (stdin, stderr) really close it? ----------------------------------------------------------------------- Python file objects are a high-level layer of abstraction on top of C streams, which in turn are a medium-level layer of abstraction on top of (among other things) low-level C file descriptors. For most file objects you create in Python via the builtin ``file`` constructor, ``f.close()`` marks the Python file object as being closed from Python's point of view, and also arranges to close the underlying C stream. This also happens automatically in f's destructor, when f becomes garbage. But stdin, stdout and stderr are treated specially by Python, because of the special status also given to them by C. Running ``sys.stdout.close()`` marks the Python-level file object as being closed, but does *not* close the associated C stream. To close the underlying C stream for one of these three, you should first be sure that's what you really want to do (e.g., you may confuse extension modules trying to do I/O). If it is, use os.close:: os.close(0) # close C's stdin stream os.close(1) # close C's stdout stream os.close(2) # close C's stderr stream Network/Internet Programming ======================================= What WWW tools are there for Python? -------------------------------------------- See the chapters titled `"Internet Protocols and Support" `_ and `"Internet Data Handling" `_ in the Library Reference Manual. Python has many modules that will help you build server-side and client-side web systems. A summary of available frameworks is maintained by Paul Boddie at http://www.python.org/cgi-bin/moinmoin/WebProgramming . Cameron Laird maintains a useful set of pages about Python web technologies at http://phaseit.net/claird/comp.lang.python/web_python.html. The `Web Programming topic guide `_ also points to many useful resources. How can I mimic CGI form submission (METHOD=POST)? ---------------------------------------------------------- I would like to retrieve web pages that are the result of POSTing a form. Is there existing code that would let me do this easily? Yes. Here's a simple example that uses httplib:: #!/usr/local/bin/python import httplib, sys, time ### build the query string qs = "First=Josephine&MI=Q&Last=Public" ### connect and send the server a path httpobj = httplib.HTTP('www.some-server.out-there', 80) httpobj.putrequest('POST', '/cgi-bin/some-cgi-script') ### now generate the rest of the HTTP headers... httpobj.putheader('Accept', '*/*') httpobj.putheader('Connection', 'Keep-Alive') httpobj.putheader('Content-type', 'application/x-www-form-urlencoded') httpobj.putheader('Content-length', '%d' % len(qs)) httpobj.endheaders() httpobj.send(qs) ### find out what the server said in response... reply, msg, hdrs = httpobj.getreply() if reply != 200: sys.stdout.write(httpobj.getfile().read()) Note that in general for URL-encoded POST operations, query strings must be quoted by using ``urllib.quote()``. For example to send name="Guy Steele, Jr.":: >>> from urllib import quote >>> x = quote("Guy Steele, Jr.") >>> x 'Guy%20Steele,%20Jr.' >>> query_string = "name="+x >>> query_string 'name=Guy%20Steele,%20Jr.' What module should I use to help with generating HTML? -------------------------------------------------------------- There are many different modules available: * HTMLgen is a class library of objects corresponding to all the HTML 3.2 markup tags. It's used when you are writing in Python and wish to synthesize HTML pages for generating a web or for CGI forms, etc. * DocumentTemplate and Zope Page Templates are two different systems that are part of Zope. * Quixote's PTL uses Python syntax to assemble strings of text. Consult the `Web Programming topic guide `_ for more links. How do I send mail from a Python script? ------------------------------------------------ Use `the standard library module smtplib `_. Here's a very simple interactive mail sender that uses it. This method will work on any host that supports an SMTP listener. :: import sys, smtplib fromaddr = raw_input("From: ") toaddrs = raw_input("To: ").split(',') print "Enter message, end with ^D:" msg = '' while 1: line = sys.stdin.readline() if not line: break msg = msg + line # The actual mail send server = smtplib.SMTP('localhost') server.sendmail(fromaddr, toaddrs, msg) server.quit() A Unix-only alternative uses sendmail. The location of the sendmail program varies between systems; sometimes it is ``/usr/lib/sendmail``, sometime ``/usr/sbin/sendmail``. The sendmail manual page will help you out. Here's some sample code:: SENDMAIL = "/usr/sbin/sendmail" # sendmail location import os p = os.popen("%s -t -i" % SENDMAIL, "w") p.write("To: receiver@example.com\n") p.write("Subject: test\n") p.write("\n") # blank line separating headers from body p.write("Some text\n") p.write("some more text\n") sts = p.close() if sts != 0: print "Sendmail exit status", sts How do I avoid blocking in the connect() method of a socket? -------------------------------------------------------------------------- The select module is commonly used to help with asynchronous I/O on sockets. To prevent the TCP connect from blocking, you can set the socket to non-blocking mode. Then when you do the ``connect()``, you will either connect immediately (unlikely) or get an exception that contains the error number as ``.errno``. ``errno.EINPROGRESS`` indicates that the connection is in progress, but hasn't finished yet. Different OSes will return different values, so you're going to have to check what's returned on your system. You can use the ``connect_ex()`` method to avoid creating an exception. It will just return the errno value. To poll, you can call ``connect_ex()`` again later -- 0 or ``errno.EISCONN`` indicate that you're connected -- or you can pass this socket to select to check if it's writeable. Databases ===================== Are there any interfaces to database packages in Python? ---------------------------------------------------------------- Yes. Python 2.3 includes the ``bsddb`` package which provides an interface to the `BerkeleyDB `_ library. Interfaces to disk-based hashes such as `DBM `_ and `GDBM `_ are also included with standard Python. Support for most relational databases is available. See the `Database Topic Guide `_ for details. How do you implement persistent objects in Python? ------------------------------------------------------------ The `pickle library module `_ solves this in a very general way (though you still can't store things like open files, sockets or windows), and the `shelve library module `_ uses pickle and (g)dbm to create persistent mappings containing arbitrary Python objects. For better performance, you can use `the cPickle module `_. A more awkward way of doing things is to use pickle's little sister, marshal. `The marshal module `_ provides very fast ways to store noncircular basic Python types to files and strings, and back again. Although marshal does not do fancy things like store instances or handle shared references properly, it does run extremely fast. For example loading a half megabyte of data may take less than a third of a second. This often beats doing something more complex and general such as using gdbm with pickle/shelve. Why is cPickle so slow? -------------------------------- The default format used by the pickle module is a slow one that results in readable pickles. Making it the default, but it would break backward compatibility:: largeString = 'z' * (100 * 1024) myPickle = cPickle.dumps(largeString, protocol=1) If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come? -------------------------------------------------------------------------------------------------- Databases opened for write access with the bsddb module (and often by the anydbm module, since it will preferentially use bsddb) must explicitly be closed using the ``.close()`` method of the database. The underlying library caches database contents which need to be converted to on-disk form and written. If you have initialized a new bsddb database but not written anything to it before the program crashes, you will often wind up with a zero-length file and encounter an exception the next time the file is opened. I tried to open Berkeley DB file, but bsddb produces bsddb.error: (22, 'Invalid argument'). Help! How can I restore my data? ------------------------------------------------------------------------------------------------------------------------------------ Don't panic! Your data is probably intact. The most frequent cause for the error is that you tried to open an earlier Berkeley DB file with a later version of the Berkeley DB library. Many Linux systems now have all three versions of Berkeley DB available. If you are migrating from version 1 to a newer version use db_dump185 to dump a plain text version of the database. If you are migrating from version 2 to version 3 use db2_dump to create a plain text version of the database. In either case, use db_load to create a new native database for the latest version installed on your computer. If you have version 3 of Berkeley DB installed, you should be able to use db2_load to create a native version 2 database. You should move away from Berkeley DB version 1 files because the hash file code contains known bugs that can corrupt your data. Mathematics and Numerics ================================ How do I generate random numbers in Python? --------------------------------------------------- The `standard module random `_ implements a random number generator. Usage is simple:: import random random.random() This returns a random floating point number in the range [0, 1). There are also many other specialized generators in this module, such as: * ``randrange(a, b)`` chooses an integer in the range [a, b). * ``uniform(a, b)`` chooses a floating point number in the range [a, b). * ``normalvariate(mean, sdev)`` samples the normal (Gaussian) distribution. Some higher-level functions operate on sequences directly, such as: * ``choice(S)`` chooses random element from a given sequence * ``shuffle(L)`` shuffles a list in-place, i.e. permutes it randomly There's also a ``Random`` class you can instantiate to create independent multiple random number generators. python-defaults-2.7.12/faq/extending.ht0000664000000000000000000004367212057417145014734 0ustar Title: Python Extending/Embedding FAQ Content-type: text/x-rst ==================================== Extending/Embedding FAQ ==================================== :Date: $Date: 2004-04-08 09:05:47 -0600 (Thu, 08 Apr 2004) $ :Version: $Revision: 7294 $ :Web site: http://www.python.org/ .. contents:: .. sectnum:: Can I create my own functions in C? ------------------------------------------ Yes, you can create built-in modules containing functions, variables, exceptions and even new types in C. This is explained in the document "Extending and Embedding the Python Interpreter" (http://docs.python.org/ext/ext.html). Most intermediate or advanced Python books will also cover this topic. Can I create my own functions in C++? -------------------------------------------- Yes, using the C compatibility features found in C++. Place ``extern "C" { ... }`` around the Python include files and put ``extern "C"`` before each function that is going to be called by the Python interpreter. Global or static C++ objects with constructors are probably not a good idea. Writing C is hard; are there any alternatives? --------------------------------------------------- There are a number of alternatives to writing your own C extensions, depending on what you're trying to do. If you need more speed, `Psyco `_ generates x86 assembly code from Python bytecode. You can use Psyco to compile the most time-critical functions in your code, and gain a significant improvement with very little effort, as long as you're running on a machine with an x86-compatible processor. `Pyrex `_ is a compiler that accepts a slightly modified form of Python and generates the corresponding C code. Pyrex makes it possible to write an extension without having to learn Python's C API. If you need to interface to some C library for which no Python extension currently exists, you can try wrapping the library's data types and functions with a tool such as `SWIG `_. For C++ libraries, you can look at `SIP `_, `CXX `_, `Boost `_, or `Weave `_. How can I execute arbitrary Python statements from C? ------------------------------------------------------------ The highest-level function to do this is ``PyRun_SimpleString()`` which takes a single string argument to be executed in the context of the module ``__main__`` and returns 0 for success and -1 when an exception occurred (including ``SyntaxError``). If you want more control, use ``PyRun_String()``; see the source for ``PyRun_SimpleString()`` in Python/pythonrun.c. How can I evaluate an arbitrary Python expression from C? ---------------------------------------------------------------- Call the function ``PyRun_String()`` from the previous question with the start symbol ``Py_eval_input``; it parses an expression, evaluates it and returns its value. How do I extract C values from a Python object? ------------------------------------------------------ That depends on the object's type. If it's a tuple, ``PyTupleSize(o)`` returns its length and ``PyTuple_GetItem(o, i)`` returns its i'th item. Lists have similar functions, ``PyListSize(o)`` and ``PyList_GetItem(o, i)``. For strings, ``PyString_Size(o)`` returns its length and ``PyString_AsString(o)`` a pointer to its value. Note that Python strings may contain null bytes so C's ``strlen()`` should not be used. To test the type of an object, first make sure it isn't NULL, and then use ``PyString_Check(o)``, ``PyTuple_Check(o)``, ``PyList_Check(o)``, etc. There is also a high-level API to Python objects which is provided by the so-called 'abstract' interface -- read ``Include/abstract.h`` for further details. It allows interfacing with any kind of Python sequence using calls like ``PySequence_Length()``, ``PySequence_GetItem()``, etc.) as well as many other useful protocols. How do I use Py_BuildValue() to create a tuple of arbitrary length? -------------------------------------------------------------------------- You can't. Use ``t = PyTuple_New(n)`` instead, and fill it with objects using ``PyTuple_SetItem(t, i, o)`` -- note that this "eats" a reference count of ``o``, so you have to ``Py_INCREF`` it. Lists have similar functions ``PyList_New(n)`` and ``PyList_SetItem(l, i, o)``. Note that you *must* set all the tuple items to some value before you pass the tuple to Python code -- ``PyTuple_New(n)`` initializes them to NULL, which isn't a valid Python value. How do I call an object's method from C? ----------------------------------------------- The ``PyObject_CallMethod()`` function can be used to call an arbitrary method of an object. The parameters are the object, the name of the method to call, a format string like that used with ``Py_BuildValue()``, and the argument values:: PyObject * PyObject_CallMethod(PyObject *object, char *method_name, char *arg_format, ...); This works for any object that has methods -- whether built-in or user-defined. You are responsible for eventually ``Py_DECREF``'ing the return value. To call, e.g., a file object's "seek" method with arguments 10, 0 (assuming the file object pointer is "f"):: res = PyObject_CallMethod(f, "seek", "(ii)", 10, 0); if (res == NULL) { ... an exception occurred ... } else { Py_DECREF(res); } Note that since ``PyObject_CallObject()`` *always* wants a tuple for the argument list, to call a function without arguments, pass "()" for the format, and to call a function with one argument, surround the argument in parentheses, e.g. "(i)". How do I catch the output from PyErr_Print() (or anything that prints to stdout/stderr)? ----------------------------------------------------------------------------------------------- In Python code, define an object that supports the ``write()`` method. Assign this object to ``sys.stdout`` and ``sys.stderr``. Call print_error, or just allow the standard traceback mechanism to work. Then, the output will go wherever your ``write()`` method sends it. The easiest way to do this is to use the StringIO class in the standard library. Sample code and use for catching stdout:: >>> class StdoutCatcher: ... def __init__(self): ... self.data = '' ... def write(self, stuff): ... self.data = self.data + stuff ... >>> import sys >>> sys.stdout = StdoutCatcher() >>> print 'foo' >>> print 'hello world!' >>> sys.stderr.write(sys.stdout.data) foo hello world! How do I access a module written in Python from C? --------------------------------------------------------- You can get a pointer to the module object as follows:: module = PyImport_ImportModule(""); If the module hasn't been imported yet (i.e. it is not yet present in ``sys.modules``), this initializes the module; otherwise it simply returns the value of ``sys.modules[""]``. Note that it doesn't enter the module into any namespace -- it only ensures it has been initialized and is stored in ``sys.modules``. You can then access the module's attributes (i.e. any name defined in the module) as follows:: attr = PyObject_GetAttrString(module, ""); Calling ``PyObject_SetAttrString()`` to assign to variables in the module also works. How do I interface to C++ objects from Python? ------------------------------------------------------ Depending on your requirements, there are many approaches. To do this manually, begin by reading `the "Extending and Embedding" document `_. Realize that for the Python run-time system, there isn't a whole lot of difference between C and C++ -- so the strategy of building a new Python type around a C structure (pointer) type will also work for C++ objects. For C++ libraries, you can look at `SIP `_, `CXX `_, `Boost `_, or `Weave `_. `SWIG `_ is a similar automated tool that only supports C libraries. I added a module using the Setup file and the make fails; why? ---------------------------------------------------------------------- Setup must end in a newline, if there is no newline there, the build process fails. (Fixing this requires some ugly shell script hackery, and this bug is so minor that it doesn't seem worth the effort.) How do I debug an extension? ------------------------------------ When using GDB with dynamically loaded extensions, you can't set a breakpoint in your extension until your extension is loaded. In your ``.gdbinit`` file (or interactively), add the command:: br _PyImport_LoadDynamicModule Then, when you run GDB:: $ gdb /local/bin/python gdb) run myscript.py gdb) continue # repeat until your extension is loaded gdb) finish # so that your extension is loaded gdb) br myfunction.c:50 gdb) continue I want to compile a Python module on my Linux system, but some files are missing. Why? ------------------------------------------------------------------------------------------------- Most packaged versions of Python don't include the /usr/lib/python2.x/config/ directory, which contains various files required for compiling Python extensions. For Red Hat, install the python-devel RPM to get the necessary files. For Debian, run ``apt-get install python-dev``. What does "SystemError: _PyImport_FixupExtension: module yourmodule not loaded" mean? ------------------------------------------------------------------------------------------------------- This means that you have created an extension module named "yourmodule", but your module init function does not initialize with that name. Every module init function will have a line similar to:: module = Py_InitModule("yourmodule", yourmodule_functions); If the string passed to this function is not the same name as your extenion module, the ``SystemError`` exception will be raised. How do I tell "incomplete input" from "invalid input"? -------------------------------------------------------------------------------- Sometimes you want to emulate the Python interactive interpreter's behavior, where it gives you a continuation prompt when the input is incomplete (e.g. you typed the start of an "if" statement or you didn't close your parentheses or triple string quotes), but it gives you a syntax error message immediately when the input is invalid. In Python you can use the ``codeop`` module, which approximates the parser's behavior sufficiently. IDLE uses this, for example. The easiest way to do it in C is to call ``PyRun_InteractiveLoop()`` (perhaps in a separate thread) and let the Python interpreter handle the input for you. You can also set the ``PyOS_ReadlineFunctionPointer`` to point at your custom input function. See ``Modules/readline.c`` and ``Parser/myreadline.c`` for more hints. However sometimes you have to run the embedded Python interpreter in the same thread as your rest application and you can't allow the ``PyRun_InteractiveLoop()`` to stop while waiting for user input. The one solution then is to call ``PyParser_ParseString()`` and test for ``e.error`` equal to ``E_EOF``, which means the input is incomplete). Here's a sample code fragment, untested, inspired by code from Alex Farber:: #include #include #include #include #include #include int testcomplete(char *code) /* code should end in \n */ /* return -1 for error, 0 for incomplete, 1 for complete */ { node *n; perrdetail e; n = PyParser_ParseString(code, &_PyParser_Grammar, Py_file_input, &e); if (n == NULL) { if (e.error == E_EOF) return 0; return -1; } PyNode_Free(n); return 1; } Another solution is trying to compile the received string with ``Py_CompileString()``. If it compiles without errors, try to execute the returned code object by calling ``PyEval_EvalCode()``. Otherwise save the input for later. If the compilation fails, find out if it's an error or just more input is required - by extracting the message string from the exception tuple and comparing it to the string "unexpected EOF while parsing". Here is a complete example using the GNU readline library (you may want to ignore SIGINT while calling readline()):: #include #include #include #include #include #include int main (int argc, char* argv[]) { int i, j, done = 0; /* lengths of line, code */ char ps1[] = ">>> "; char ps2[] = "... "; char *prompt = ps1; char *msg, *line, *code = NULL; PyObject *src, *glb, *loc; PyObject *exc, *val, *trb, *obj, *dum; Py_Initialize (); loc = PyDict_New (); glb = PyDict_New (); PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ()); while (!done) { line = readline (prompt); if (NULL == line) /* CTRL-D pressed */ { done = 1; } else { i = strlen (line); if (i > 0) add_history (line); /* save non-empty lines */ if (NULL == code) /* nothing in code yet */ j = 0; else j = strlen (code); code = realloc (code, i + j + 2); if (NULL == code) /* out of memory */ exit (1); if (0 == j) /* code was empty, so */ code[0] = '\0'; /* keep strncat happy */ strncat (code, line, i); /* append line to code */ code[i + j] = '\n'; /* append '\n' to code */ code[i + j + 1] = '\0'; src = Py_CompileString (code, "", Py_single_input); if (NULL != src) /* compiled just fine - */ { if (ps1 == prompt || /* ">>> " or */ '\n' == code[i + j - 1]) /* "... " and double '\n' */ { /* so execute it */ dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc); Py_XDECREF (dum); Py_XDECREF (src); free (code); code = NULL; if (PyErr_Occurred ()) PyErr_Print (); prompt = ps1; } } /* syntax error or E_EOF? */ else if (PyErr_ExceptionMatches (PyExc_SyntaxError)) { PyErr_Fetch (&exc, &val, &trb); /* clears exception! */ if (PyArg_ParseTuple (val, "sO", &msg, &obj) && !strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */ { Py_XDECREF (exc); Py_XDECREF (val); Py_XDECREF (trb); prompt = ps2; } else /* some other syntax error */ { PyErr_Restore (exc, val, trb); PyErr_Print (); free (code); code = NULL; prompt = ps1; } } else /* some non-syntax error */ { PyErr_Print (); free (code); code = NULL; prompt = ps1; } free (line); } } Py_XDECREF(glb); Py_XDECREF(loc); Py_Finalize(); exit(0); } How do I find undefined g++ symbols __builtin_new or __pure_virtual? ----------------------------------------------------------------------------------- To dynamically load g++ extension modules, you must recompile Python, relink it using g++ (change LINKCC in the python Modules Makefile), and link your extension module using g++ (e.g., "g++ -shared -o mymodule.so mymodule.o"). Can I create an object class with some methods implemented in C and others in Python (e.g. through inheritance)? ----------------------------------------------------------------------------------------------------------------------------------------------------- In Python 2.2, you can inherit from builtin classes such as int, list, dict, etc. The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html) provides a way of doing this from C++ (i.e. you can inherit from an extension class written in C++ using the BPL). When importing module X, why do I get "undefined symbol: PyUnicodeUCS2*"? -------------------------------------------------------------------------------------------------- You are using a version of Python that uses a 4-byte representation for Unicode characters, but some C extension module you are importing was compiled using a Python that uses a 2-byte representation for Unicode characters (the default). If instead the name of the undefined symbol starts with ``PyUnicodeUCS4``, the problem is the reverse: Python was built using 2-byte Unicode characters, and the extension module was compiled using a Python with 4-byte Unicode characters. This can easily occur when using pre-built extension packages. RedHat Linux 7.x, in particular, provided a "python2" binary that is compiled with 4-byte Unicode. This only causes the link failure if the extension uses any of the ``PyUnicode_*()`` functions. It is also a problem if an extension uses any of the Unicode-related format specifiers for ``Py_BuildValue`` (or similar) or parameter specifications for ``PyArg_ParseTuple()``. You can check the size of the Unicode character a Python interpreter is using by checking the value of sys.maxunicode:: >>> import sys >>> if sys.maxunicode > 65535: ... print 'UCS4 build' ... else: ... print 'UCS2 build' The only way to solve this problem is to use extension modules compiled with a Python binary built using the same size for Unicode characters. python-defaults-2.7.12/faq/gui.html0000664000000000000000000004324412632016513014050 0ustar Graphic User Interface FAQ

Graphic User Interface FAQ

Date: 2003-09-04
Version: 6607
Web site:http://www.python.org/

1   General GUI Questions

1.1   What platform-independent GUI toolkits exist for Python?

Depending on what platform(s) you are aiming at, there are several.

1.1.1   Tkinter

Standard builds of Python include an object-oriented interface to the Tcl/Tk widget set, called Tkinter. This is probably the easiest to install and use. For more info about Tk, including pointers to the source, see the Tcl/Tk home page at http://www.tcl.tk. Tcl/Tk is fully portable to the MacOS, Windows, and Unix platforms.

1.1.2   wxWindows

wxWindows is a portable GUI class library written in C++ that's a portable interface to various platform-specific libraries; wxPython is a Python interface to wxWindows. wxWindows supports Windows and MacOS; on Unix variants, it supports both GTk+ and Motif toolkits. wxWindows preserves the look and feel of the underlying graphics toolkit, and there is quite a rich widget set and collection of GDI classes. See the wxWindows page for more details.

wxPython is an extension module that wraps many of the wxWindows C++ classes, and is quickly gaining popularity amongst Python developers. You can get wxPython as part of the source or CVS distribution of wxWindows, or directly from its home page.

1.1.3   Qt

There are bindings available for the Qt toolkit (PyQt) and for KDE (PyKDE). If you're writing open source software, you don't need to pay for PyQt, but if you want to write proprietary applications, you must buy a PyQt license from Riverbank Computing and a Qt license from Trolltech.

1.1.4   GTk+

PyGTk bindings for the GTk+ toolkit have been implemented by by James Henstridge; see ftp://ftp.gtk.org/pub/gtk/python/.

1.1.5   FLTK

Python bindings for the FLTK toolkit, a simple yet powerful and mature cross-platform windowing system, are available from the PyFLTK project.

1.1.6   FOX

A wrapper for the FOX toolkit called FXpy is available. FOX supports both Unix variants and Windows.

1.1.7   OpenGL

For OpenGL bindings, see PyOpenGL.

1.2   What platform-specific GUI toolkits exist for Python?

The Mac port by Jack Jansen has a rich and ever-growing set of modules that support the native Mac toolbox calls. The port includes support for MacOS9 and MacOS X's Carbon libraries. By installing the PyObjc Objective-C bridge, Python programs can use MacOS X's Cocoa libraries. See the documentation that comes with the Mac port.

Pythonwin by Mark Hammond includes an interface to the Microsoft Foundation Classes and a Python programming environment using it that's written mostly in Python.

2   Tkinter questions

2.1   How do I freeze Tkinter applications?

Freeze is a tool to create stand-alone applications. When freezing Tkinter applications, the applications will not be truly stand-alone, as the application will still need the Tcl and Tk libraries.

One solution is to ship the application with the tcl and tk libraries, and point to them at run-time using the TCL_LIBRARY and TK_LIBRARY environment variables.

To get truly stand-alone applications, the Tcl scripts that form the library have to be integrated into the application as well. One tool supporting that is SAM (stand-alone modules), which is part of the Tix distribution (http://tix.mne.com). Build Tix with SAM enabled, perform the appropriate call to Tclsam_init etc inside Python's Modules/tkappinit.c, and link with libtclsam and libtksam (you might include the Tix libraries as well).

2.2   Can I have Tk events handled while waiting for I/O?

Yes, and you don't even need threads! But you'll have to restructure your I/O code a bit. Tk has the equivalent of Xt's XtAddInput() call, which allows you to register a callback function which will be called from the Tk mainloop when I/O is possible on a file descriptor. Here's what you need:

from Tkinter import tkinter
tkinter.createfilehandler(file, mask, callback)

The file may be a Python file or socket object (actually, anything with a fileno() method), or an integer file descriptor. The mask is one of the constants tkinter.READABLE or tkinter.WRITABLE. The callback is called as follows:

callback(file, mask)

You must unregister the callback when you're done, using

tkinter.deletefilehandler(file)

Note: since you don't know how many bytes are available for reading, you can't use the Python file object's read or readline methods, since these will insist on reading a predefined number of bytes. For sockets, the recv() or recvfrom() methods will work fine; for other files, use os.read(file.fileno(), maxbytecount).

2.3   I can't get key bindings to work in Tkinter: why?

An often-heard complaint is that event handlers bound to events with the bind() method don't get handled even when the appropriate key is pressed.

The most common cause is that the widget to which the binding applies doesn't have "keyboard focus". Check out the Tk documentation for the focus command. Usually a widget is given the keyboard focus by clicking in it (but not for labels; see the takefocus option).

python-defaults-2.7.12/faq/general.ht0000664000000000000000000017123512057417145014361 0ustar Title: General Python FAQ Content-type: text/x-rst ==================================== General Python FAQ ==================================== :Date: $Date: 2006-02-26 06:15:13 +0100 (Sun, 26 Feb 2006) $ :Version: $Revision: 8958 $ :Web site: http://www.python.org/ .. contents:: .. sectnum:: General Information ===================== What is Python? ---------------------- Python is an interpreted, interactive, object-oriented programming language. It incorporates modules, exceptions, dynamic typing, very high level dynamic data types, and classes. Python combines remarkable power with very clear syntax. It has interfaces to many system calls and libraries, as well as to various window systems, and is extensible in C or C++. It is also usable as an extension language for applications that need a programmable interface. Finally, Python is portable: it runs on many Unix variants, on the Mac, and on PCs under MS-DOS, Windows, Windows NT, and OS/2. To find out more, start with the `Beginner's Guide to Python `_. Why was Python created in the first place? -------------------------------------------------- Here's a *very* brief summary of what started it all, written by Guido van Rossum: I had extensive experience with implementing an interpreted language in the ABC group at CWI, and from working with this group I had learned a lot about language design. This is the origin of many Python features, including the use of indentation for statement grouping and the inclusion of very-high-level data types (although the details are all different in Python). I had a number of gripes about the ABC language, but also liked many of its features. It was impossible to extend the ABC language (or its implementation) to remedy my complaints -- in fact its lack of extensibility was one of its biggest problems. I had some experience with using Modula-2+ and talked with the designers of Modula-3 and read the Modula-3 report. Modula-3 is the origin of the syntax and semantics used for exceptions, and some other Python features. I was working in the Amoeba distributed operating system group at CWI. We needed a better way to do system administration than by writing either C programs or Bourne shell scripts, since Amoeba had its own system call interface which wasn't easily accessible from the Bourne shell. My experience with error handling in Amoeba made me acutely aware of the importance of exceptions as a programming language feature. It occurred to me that a scripting language with a syntax like ABC but with access to the Amoeba system calls would fill the need. I realized that it would be foolish to write an Amoeba-specific language, so I decided that I needed a language that was generally extensible. During the 1989 Christmas holidays, I had a lot of time on my hand, so I decided to give it a try. During the next year, while still mostly working on it in my own time, Python was used in the Amoeba project with increasing success, and the feedback from colleagues made me add many early improvements. In February 1991, after just over a year of development, I decided to post to USENET. The rest is in the Misc/HISTORY file. What is Python good for? -------------------------------- Python is a high-level general-purpose programming language that can be applied to many different classes of problems. The language comes with a large standard library that covers areas such as string processing (regular expressions, Unicode, calculating differences between files), Internet protocols (HTTP, FTP, SMTP, XML-RPC, POP, IMAP, CGI programming), software engineering (unit testing, logging, profiling, parsing Python code), and operating system interfaces (system calls, filesystems, TCP/IP sockets). Look at the table of contents for `the Library Reference `_ to get an idea of what's available. A wide variety of third-party extensions are also available. Consult `the Python Package Index `_ to find packages of interest to you. How does the Python version numbering scheme work? ---------------------------------------------------------- Python versions are numbered A.B.C or A.B. A is the major version number -- it is only incremented for really major changes in the language. B is the minor version number, incremented for less earth-shattering changes. C is the micro-level -- it is incremented for each bugfix release. See `PEP 6 <../../peps/pep-0006.html>`_ for more information about bugfix releases. Not all releases are bugfix releases. In the run-up to a new major release, a series of development releases are made, denoted as alpha, beta, or release candidate. Alphas are early releases in which interfaces aren't yet finalized; it's not unexpected to see an interface change between two alpha releases. Betas are more stable, preserving existing interfaces but possibly adding new modules, and release candidates are frozen, making no changes except as needed to fix critical bugs. Alpha, beta and release candidate versions have an additional suffix. The suffix for an alpha version is "aN" for some small number N, the suffix for a beta version is "bN" for some small number N, and the suffix for a release candidate version is "cN" for some small number N. In other words, all versions labeled 2.0aN precede the versions labeled 2.0bN, which precede versions labeled 2.0cN, and *those* precede 2.0. You may also find version numbers with a "+" suffix, e.g. "2.2+". These are unreleased versions, built directly from the subversion trunk. In practice, after a final minor release is made, the subversion trunk is incremented to the next minor version, which becomes the "a0" version, e.g. "2.4a0". See also the documentation for ``sys.version``, ``sys.hexversion``, and ``sys.version_info``. Are there copyright restrictions on the use of Python? -------------------------------------------------------------- Not really. You can do anything you want with the source, as long as you leave the copyrights in and display those copyrights in any documentation about Python that you produce. If you honor the copyright rules, it's OK to use Python for commercial use, to sell copies of Python in source or binary form (modified or unmodified), or to sell products that incorporate Python in some form. We would still like to know about all commercial use of Python, of course. See `the PSF license page <../../psf/license.html>`_ to find further explanations and a link to the full text of the license. How do I obtain a copy of the Python source? --------------------------------------------------- The latest Python source distribution is always available from python.org, at http://www.python.org/download/. The latest development sources can be obtained via anonymous subversion from SourceForge, at http://svn.python.org/projects/python/trunk. The source distribution is a gzipped tar file containing the complete C source, LaTeX documentation, Python library modules, example programs, and several useful pieces of freely distributable software. This will compile and run out of the box on most UNIX platforms. Older versions of Python are also available from python.org. How do I get documentation on Python? -------------------------------------------- All documentation is available on-line, starting at http://www.python.org/doc/. The standard documentation for the current stable version of Python is also available at http://docs.python.org/. The LaTeX source for the documentation is part of the source distribution. If you don't have LaTeX, the latest Python documentation set is available by anonymous FTP in various formats such as PostScript and HTML. Visit the above URL for links to the current versions. I've never programmed before. Is there a Python tutorial? ----------------------------------------------------------------- There are numerous tutorials and books available. Consult `the Beginner's Guide `_ to find information for beginning Python programmers, including lists of tutorials. Are there other FTP sites that mirror the Python distribution? --------------------------------------------------------------------- Consult the list of python.org mirrors at http://www.python.org/Mirrors.html. Is there a newsgroup or mailing list devoted to Python? -------------------------------------------------------------- There is a newsgroup, comp.lang.python, and a mailing list, `python-list `_. The newsgroup and mailing list are gatewayed into each other -- if you can read news it's unnecessary to subscribe to the mailing list. comp.lang.python is high-traffic, receiving hundreds of postings every day, and Usenet readers are often more able to cope with this volume. Announcements of new software releases and events can be found in comp.lang.python.announce, a low-traffic moderated list that receives about five postings per day. It's available as `the python-announce mailing list `_. More info about other mailing lists and newsgroups can be found at http://www.python.org/community/lists.html. How do I get a beta test version of Python? --------------------------------------------------- All releases, including alphas, betas and release candidates, are announced on the comp.lang.python and comp.lang.python.announce newsgroups. All announcements also appear on the Python home page, at http://www.python.org/; an RSS feed of news is available. You can also access the development version of Python through subversion. See http://www.python.org/dev/devfaq.html#subversion-svn for details. How do I submit bug reports and patches for Python? ---------------------------------------------------------- To report a bug or submit a patch, please use the relevant service from the Python project at SourceForge. Bugs: http://sourceforge.net/tracker/?group_id=5470&atid=105470 Patches: http://sourceforge.net/tracker/?group_id=5470&atid=305470 You must have a SourceForge account to report bugs; this makes it possible for us to contact you if we have follow-up questions. It will also enable SourceForge to send you updates as we act on your bug. For more information on how Python is developed, consult `the Python Developer's Guide <../../dev/>`_. Are there any published articles about Python that I can reference? --------------------------------------------------------------------------- It's probably best to reference your favorite book about Python. The very first article about Python is this very old article that's now quite outdated. Guido van Rossum and Jelke de Boer, "Interactively Testing Remote Servers Using the Python Programming Language", CWI Quarterly, Volume 4, Issue 4 (December 1991), Amsterdam, pp 283-303. Are there any books on Python? ------------------------------------- Yes, there are many, and more are being published. See the python.org Wiki at http://www.python.org/moin/PythonBooks for a list. You can also search online bookstores for "Python" and filter out the Monty Python references; or perhaps search for "Python" and "language". Where in the world is www.python.org located? ----------------------------------------------------- It's currently in Amsterdam, graciously hosted by `XS4ALL `_. Thanks to Thomas Wouters for his work in arranging python.org's hosting. Why is it called Python? ------------------------------- At the same time he began implementing Python, Guido van Rossum was also reading the published scripts from "Monty Python's Flying Circus" (a BBC comedy series from the seventies, in the unlikely case you didn't know). It occurred to him that he needed a name that was short, unique, and slightly mysterious, so he decided to call the language Python. Do I have to like "Monty Python's Flying Circus"? ------------------------------------------------------------------- No, but it helps. :) Python in the real world ============================ How stable is Python? ---------------------------- Very stable. New, stable releases have been coming out roughly every 6 to 18 months since 1991, and this seems likely to continue. Currently there are usually around 18 months between major releases. With the introduction of retrospective "bugfix" releases the stability of existing releases is being improved. Bugfix releases, indicated by a third component of the version number (e.g. 2.1.3, 2.2.2), are managed for stability; only fixes for known problems are included in a bugfix release, and it's guaranteed that interfaces will remain the same throughout a series of bugfix releases. The `2.4.2 release <../../2.4.2/>`_ is the most stable version at this point in time. How many people are using Python? ---------------------------------------- Probably tens of thousands of users, though it's difficult to obtain an exact count. Python is available for free download, so there are no sales figures, and it's available from many different sites and packaged with many Linux distributions, so download statistics don't tell the whole story either. The comp.lang.python newsgroup is very active, but not all Python users post to the group or even read it. Overall there is no accurate estimate of the number of subscribers or Python users. Have any significant projects been done in Python? --------------------------------------------------------- See http://www.pythonology.org/success for a list of projects that use Python. Consulting the proceedings for `past Python conferences <../../workshops/>`_ will reveal contributions from many different companies and organizations. High-profile Python projects include `the Mailman mailing list manager `_ and `the Zope application server `_. Several Linux distributions, most notably `Red Hat `_, have written part or all of their installer and system administration software in Python. Companies that use Python internally include Google, Yahoo, and Industrial Light & Magic. What new developments are expected for Python in the future? ------------------------------------------------------------------- See http://www.python.org/peps for the Python Enhancement Proposals (PEPs). PEPs are design documents describing a suggested new feature for Python, providing a concise technical specification and a rationale. `PEP 1 <../../peps/pep-0001.html>`_ explains the PEP process and PEP format; read it first if you want to submit a PEP. New developments are discussed on `the python-dev mailing list `_. Is it reasonable to propose incompatible changes to Python? ------------------------------------------------------------------ In general, no. There are already millions of lines of Python code around the world, so any change in the language that invalidates more than a very small fraction of existing programs has to be frowned upon. Even if you can provide a conversion program, there still is the problem of updating all documentation; many books have been written about Python, and we don't want to invalidate them all at a single stroke. Providing a gradual upgrade path is necessary if a feature has to be changed. `PEP 5 <../../peps/pep-0005.html>`_ describes the procedure followed for introducing backward-incompatible changes while minimizing disruption for users. What is the Python Software Foundation? ----------------------------------------- The Python Software Foundation is an independent non-profit organization that holds the copyright on Python versions 2.1 and newer. The PSF's mission is to advance open source technology related to the Python programming language and to publicize the use of Python. The PSF's home page is at http://www.python.org/psf/. Donations to the PSF are tax-exempt in the US. If you use Python and find it helpful, please contribute via `the PSF donation page <../../psf/donations.html>`_. Is Python Y2K (Year 2000) Compliant? -------------------------------------------- As of August, 2003 no major problems have been reported and Y2K compliance seems to be a non-issue. Python does very few date calculations and for those it does perform relies on the C library functions. Python generally represents times either as seconds since 1970 or as a ``(year, month, day, ...)`` tuple where the year is expressed with four digits, which makes Y2K bugs unlikely. So as long as your C library is okay, Python should be okay. Of course, it's possible that a particular application written in Python makes assumptions about 2-digit years. Because Python is available free of charge, there are no absolute guarantees. If there *are* unforseen problems, liability is the user's problem rather than the developers', and there is nobody you can sue for damages. The Python copyright notice contains the following disclaimer: 4. PSF is making Python 2.3 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 2.3 WILL NOT INFRINGE ANY THIRD PARTY RIGHTS. 5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON 2.3 FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON 2.3, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. The good news is that *if* you encounter a problem, you have full source available to track it down and fix it. This is one advantage of an open source programming environment. Is Python a good language for beginning programmers? ----------------------------------------------------------------------- Yes. If you want to discuss Python's use in education, then you may be interested in joining `the edu-sig mailing list <../../sigs/edu-sig>`_. It is still common to start students with a procedural (subset of a) statically typed language such as Pascal, C, or a subset of C++ or Java. Students may be better served by learning Python as their first language. Python has a very simple and consistent syntax and a large standard library and, most importantly, using Python in a beginning programming course permits students to concentrate on important programming skills such as problem decomposition and data type design. With Python, students can be quickly introduced to basic concepts such as loops and procedures. They can even probably work with user-defined objects in their very first course. For a student who has never programmed before, using a statically typed language seems unnatural. It presents additional complexity that the student must master and slows the pace of the course. The students are trying to learn to think like a computer, decompose problems, design consistent interfaces, and encapsulate data. While learning to use a statically typed language is important in the long term, it is not necessarily the best topic to address in the students' first programming course. Many other aspects of Python make it a good first language. Like Java, Python has a large standard library so that students can be assigned programming projects very early in the course that *do* something. Assignments aren't restricted to the standard four-function calculator and check balancing programs. By using the standard library, students can gain the satisfaction of working on realistic applications as they learn the fundamentals of programming. Using the standard library also teaches students about code reuse. Third-party modules such as PyGame are also helpful in extending the students' reach. Python's interactive interpreter enables students to test language features while they're programming. They can keep a window with the interpreter running while they enter their program's source in another window. If they can't remember the methods for a list, they can do something like this:: >>> L = [] >>> dir(L) ['append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort'] >>> help(L.append) Help on built-in function append: append(...) L.append(object) -- append object to end >>> L.append(1) >>> L [1] With the interpreter, documentation is never far from the student as he's programming. There are also good IDEs for Python. IDLE is a cross-platform IDE for Python that is written in Python using Tkinter. PythonWin is a Windows-specific IDE. Emacs users will be happy to know that there is a very good Python mode for Emacs. All of these programming environments provide syntax highlighting, auto-indenting, and access to the interactive interpreter while coding. Consult http://www.python.org/editors/ for a full list of Python editing environments. Upgrading Python ===================== What is this bsddb185 module my application keeps complaining about? -------------------------------------------------------------------- Starting with Python2.3, the distribution includes the `PyBSDDB package ` as a replacement for the old bsddb module. It includes functions which provide backward compatibility at the API level, but requires a newer version of the underlying `Berkeley DB `_ library. Files created with the older bsddb module can't be opened directly using the new module. Using your old version of Python and a pair of scripts which are part of Python 2.3 (db2pickle.py and pickle2db.py, in the Tools/scripts directory) you can convert your old database files to the new format. Using your old Python version, run the db2pickle.py script to convert it to a pickle, e.g.:: python2.2 /db2pickley.py database.db database.pck Rename your database file:: mv database.db olddatabase.db Now convert the pickle file to a new format database:: python2.3 /pickle2db.py database.db database.pck The precise commands you use will vary depending on the particulars of your installation. For full details about operation of these two scripts check the doc string at the start of each one. Python's Design ===================== Why does Python use indentation for grouping of statements? ----------------------------------------------------------- Guido van Rossum believes that using indentation for grouping is extremely elegant and contributes a lot to the clarity of the average Python program. Most people learn to love this feature after awhile. Since there are no begin/end brackets there cannot be a disagreement between grouping perceived by the parser and the human reader. Occasionally C programmers will encounter a fragment of code like this:: if (x <= y) x++; y--; z++; Only the ``x++`` statement is executed if the condition is true, but the indentation leads you to believe otherwise. Even experienced C programmers will sometimes stare a long time at it wondering why y is being decremented even for ``x > y``. Because there are no begin/end brackets, Python is much less prone to coding-style conflicts. In C there are many different ways to place the braces. If you're used to reading and writing code that uses one style, you will feel at least slightly uneasy when reading (or being required to write) another style. Many coding styles place begin/end brackets on a line by themself. This makes programs considerably longer and wastes valuable screen space, making it harder to get a good overview of a program. Ideally, a function should fit on onescreen (say, 20-30 lines). 20 lines of Python can do a lot more work than 20 lines of C. This is not solely due to the lack of begin/end brackets -- the lack of declarations and the high-level data types are also responsible -- but the indentation-based syntax certainly helps. Why am I getting strange results with simple arithmetic operations? ------------------------------------------------------------------- See the next question. Why are floating point calculations so inaccurate? -------------------------------------------------- People are often very surprised by results like this:: >>> 1.2-1.0 0.199999999999999996 and think it is a bug in Python. It's not. It's a problem caused by the internal representation of floating point numbers, which uses a fixed number of binary digits to represent a decimal number. Some decimal numbers can't be represented exactly in binary, resulting in small roundoff errors. In decimal math, there are many numbers that can't be represented with a fixed number of decimal digits, e.g. 1/3 = 0.3333333333....... In base 2, 1/2 = 0.1, 1/4 = 0.01, 1/8 = 0.001, etc. .2 equals 2/10 equals 1/5, resulting in the binary fractional number 0.001100110011001... Floating point numbers only have 32 or 64 bits of precision, so the digits are cut off at some point, and the resulting number is 0.199999999999999996 in decimal, not 0.2. A floating point's ``repr()`` function prints as many digits are necessary to make ``eval(repr(f)) == f`` true for any float f. The ``str()`` function prints fewer digits and this often results in the more sensible number that was probably intended:: >>> 0.2 0.20000000000000001 >>> print 0.2 0.2 Again, this has nothing to do with Python, but with the way the underlying C platform handles floating point numbers, and ultimately with the inaccuracy you'll always have when writing down numbers as a string of a fixed number of digits. One of the consequences of this is that it is dangerous to compare the result of some computation to a float with == ! Tiny inaccuracies may mean that == fails. Instead, you have to check that the difference between the two numbers is less than a certain threshold:: epsilon = 0.0000000000001 # Tiny allowed error expected_result = 0.4 if expected_result-epsilon <= computation() <= expected_result+epsilon: ... Please see the chapter on `floating point arithmetic `_ in the Python tutorial for more information. Why are Python strings immutable? --------------------------------- There are several advantages. One is performance: knowing that a string is immutable makes it easy to lay it out at construction time -- fixed and unchanging storage requirements. This is also one of the reasons for the distinction between tuples and lists. The other is that strings in Python are considered as "elemental" as numbers. No amount of activity will change the value 8 to anything else, and in Python, no amount of activity will change the string "eight" to anything else. Why must 'self' be used explicitly in method definitions and calls? ------------------------------------------------------------------- The idea was borrowed from Modula-3. It turns out to be very useful, for a variety of reasons. First, it's more obvious that you are using a method or instance attribute instead of a local variable. Reading ``self.x`` or ``self.meth()`` makes it absolutely clear that an instance variable or method is used even if you don't know the class definition by heart. In C++, you can sort of tell by the lack of a local variable declaration (assuming globals are rare or easily recognizable) -- but in Python, there are no local variable declarations, so you'd have to look up the class definition to be sure. Some C++ and Java coding standards call for instance attributes to have an ``m_`` prefix, so this explicitness is still useful in those languages, too. Second, it means that no special syntax is necessary if you want to explicitly reference or call the method from a particular class. In C++, if you want to use a method from a base class which is overridden in a derived class, you have to use the :: operator -- in Python you can write baseclass.methodname(self, ). This is particularly useful for __init__() methods, and in general in cases where a derived class method wants to extend the base class method of the same name and thus has to call the base class method somehow. Finally, for instance variables it solves a syntactic problem with assignment: since local variables in Python are (by definition!) those variables to which a value assigned in a function body (and that aren't explicitly declared global), there has to be some way to tell the interpreter that an assignment was meant to assign to an instance variable instead of to a local variable, and it should preferably be syntactic (for efficiency reasons). C++ does this through declarations, but Python doesn't have declarations and it would be a pity having to introduce them just for this purpose. Using the explicit "self.var" solves this nicely. Similarly, for using instance variables, having to write "self.var" means that references to unqualified names inside a method don't have to search the instance's directories. To put it another way, local variables and instance variables live in two different namespaces, and you need to tell Python which namespace to use. Why can't I use an assignment in an expression? ------------------------------------------------------- Many people used to C or Perl complain that they want to use this C idiom:: while (line = readline(f)) { ...do something with line... } where in Python you're forced to write this:: while True: line = f.readline() if not line: break ...do something with line... The reason for not allowing assignment in Python expressions is a common, hard-to-find bug in those other languages, caused by this construct:: if (x = 0) { ...error handling... } else { ...code that only works for nonzero x... } The error is a simple typo: ``x = 0``, which assigns 0 to the variable ``x``, was written while the comparison ``x == 0`` is certainly what was intended. Many alternatives have been proposed. Most are hacks that save some typing but use arbitrary or cryptic syntax or keywords, and fail the simple criterion for language change proposals: it should intuitively suggest the proper meaning to a human reader who has not yet been introduced to the construct. An interesting phenomenon is that most experienced Python programmers recognize the "while True" idiom and don't seem to be missing the assignment in expression construct much; it's only newcomers who express a strong desire to add this to the language. There's an alternative way of spelling this that seems attractive but is generally less robust than the "while True" solution:: line = f.readline() while line: ...do something with line... line = f.readline() The problem with this is that if you change your mind about exactly how you get the next line (e.g. you want to change it into ``sys.stdin.readline()``) you have to remember to change two places in your program -- the second occurrence is hidden at the bottom of the loop. The best approach is to use iterators, making it possible to loop through objects using the ``for`` statement. For example, in the current version of Python file objects support the iterator protocol, so you can now write simply:: for line in f: ... do something with line... Why does Python use methods for some functionality (e.g. list.index()) but functions for other (e.g. len(list))? ---------------------------------------------------------------------------------------------------------------- The major reason is history. Functions were used for those operations that were generic for a group of types and which were intended to work even for objects that didn't have methods at all (e.g. tuples). It is also convenient to have a function that can readily be applied to an amorphous collection of objects when you use the functional features of Python (``map()``, ``apply()`` et al). In fact, implementing ``len()``, ``max()``, ``min()`` as a built-in function is actually less code than implementing them as methods for each type. One can quibble about individual cases but it's a part of Python, and it's too late to make such fundamental changes now. The functions have to remain to avoid massive code breakage. Note that for string operations Python has moved from external functions (the ``string`` module) to methods. However, ``len()`` is still a function. Why is join() a string method instead of a list or tuple method? ---------------------------------------------------------------- Strings became much more like other standard types starting in Python 1.6, when methods were added which give the same functionality that has always been available using the functions of the string module. Most of these new methods have been widely accepted, but the one which appears to make some programmers feel uncomfortable is:: ", ".join(['1', '2', '4', '8', '16']) which gives the result:: "1, 2, 4, 8, 16" There are two usual arguments against this usage. The first runs along the lines of: "It looks really ugly using a method of a string literal (string constant)", to which the answer is that it might, but a string literal is just a fixed value. If the methods are to be allowed on names bound to strings there is no logical reason to make them unavailable on literals. The second objection is typically cast as: "I am really telling a sequence to join its members together with a string constant". Sadly, you aren't. For some reason there seems to be much less difficulty with having split() as a string method, since in that case it is easy to see that :: "1, 2, 4, 8, 16".split(", ") is an instruction to a string literal to return the substrings delimited by the given separator (or, by default, arbitrary runs of white space). In this case a Unicode string returns a list of Unicode strings, an ASCII string returns a list of ASCII strings, and everyone is happy. join() is a string method because in using it you are telling the separator string to iterate over an arbitrary sequence, forming string representations of each of the elements, and inserting itself between the elements' representations. This method can be used with any argument which obeys the rules for sequence objects, inluding any new classes you might define yourself. Because this is a string method it can work for Unicode strings as well as plain ASCII strings. If join() were a method of the sequence types then the sequence types would have to decide which type of string to return depending on the type of the separator. If none of these arguments persuade you, then for the moment you can continue to use the join() function from the string module, which allows you to write :: string.join(['1', '2', '4', '8', '16'], ", ") How fast are exceptions? ------------------------ A try/except block is extremely efficient. Actually executing an exception is expensive. In versions of Python prior to 2.0 it was common to use this idiom:: try: value = dict[key] except KeyError: dict[key] = getvalue(key) value = dict[key] This only made sense when you expected the dict to have the key almost all the time. If that wasn't the case, you coded it like this:: if dict.has_key(key): value = dict[key] else: dict[key] = getvalue(key) value = dict[key] (In Python 2.0 and higher, you can code this as ``value = dict.setdefault(key, getvalue(key))``.) Why isn't there a switch or case statement in Python? ----------------------------------------------------- You can do this easily enough with a sequence of ``if... elif... elif... else``. There have been some proposals for switch statement syntax, but there is no consensus (yet) on whether and how to do range tests. See `PEP 275 <../../peps/pep-0275.html>`_ for complete details and the current status. For cases where you need to choose from a very large number of possibilities, you can create a dictionary mapping case values to functions to call. For example:: def function_1 (...): ... functions = {'a': function_1, 'b': function_2, 'c': self.method_1, ...} func = functions[value] func() For calling methods on objects, you can simplify yet further by using the ``getattr()`` built-in to retrieve methods with a particular name:: def visit_a (self, ...): ... ... def dispatch (self, value): method_name = 'visit_' + str(value) method = getattr(self, method_name) method() It's suggested that you use a prefix for the method names, such as ``visit_`` in this example. Without such a prefix, if values are coming from an untrusted source, an attacker would be able to call any method on your object. Can't you emulate threads in the interpreter instead of relying on an OS-specific thread implementation? -------------------------------------------------------------------------------------------------------- Answer 1: Unfortunately, the interpreter pushes at least one C stack frame for each Python stack frame. Also, extensions can call back into Python at almost random moments. Therefore, a complete threads implementation requires thread support for C. Answer 2: Fortunately, there is `Stackless Python `_, which has a completely redesigned interpreter loop that avoids the C stack. It's still experimental but looks very promising. Although it is binary compatible with standard Python, it's still unclear whether Stackless will make it into the core -- maybe it's just too revolutionary. Why can't lambda forms contain statements? ------------------------------------------ Python lambda forms cannot contain statements because Python's syntactic framework can't handle statements nested inside expressions. However, in Python, this is not a serious problem. Unlike lambda forms in other languages, where they add functionality, Python lambdas are only a shorthand notation if you're too lazy to define a function. Functions are already first class objects in Python, and can be declared in a local scope. Therefore the only advantage of using a lambda form instead of a locally-defined function is that you don't need to invent a name for the function -- but that's just a local variable to which the function object (which is exactly the same type of object that a lambda form yields) is assigned! Can Python be compiled to machine code, C or some other language? ----------------------------------------------------------------- Not easily. Python's high level data types, dynamic typing of objects and run-time invocation of the interpreter (using ``eval()`` or ``exec``) together mean that a "compiled" Python program would probably consist mostly of calls into the Python run-time system, even for seemingly simple operations like ``x+1``. Several projects described in the Python newsgroup or at past `Python conferences <../../workshops/>`_ have shown that this approach is feasible, although the speedups reached so far are only modest (e.g. 2x). Jython uses the same strategy for compiling to Java bytecode. (Jim Hugunin has demonstrated that in combination with whole-program analysis, speedups of 1000x are feasible for small demo programs. See the proceedings from the `1997 Python conference <../../workshops/1997-10/proceedings/>`_ for more information.) Internally, Python source code is always translated into a bytecode representation, and this bytecode is then executed by the Python virtual machine. In order to avoid the overhead of repeatedly parsing and translating modules that rarely change, this byte code is written into a file whose name ends in ".pyc" whenever a module is parsed. When the corresponding .py file is changed, it is parsed and translated again and the .pyc file is rewritten. There is no performance difference once the .pyc file has been loaded, as the bytecode read from the .pyc file is exactly the same as the bytecode created by direct translation. The only difference is that loading code from a .pyc file is faster than parsing and translating a .py file, so the presence of precompiled .pyc files improves the start-up time of Python scripts. If desired, the Lib/compileall.py module can be used to create valid .pyc files for a given set of modules. Note that the main script executed by Python, even if its filename ends in .py, is not compiled to a .pyc file. It is compiled to bytecode, but the bytecode is not saved to a file. Usually main scripts are quite short, so this doesn't cost much speed. There are also several programs which make it easier to intermingle Python and C code in various ways to increase performance. See, for example, `Psyco `_, `Pyrex `_, `PyInline `_, `Py2Cmod `_, and `Weave `_. How does Python manage memory? ------------------------------ The details of Python memory management depend on the implementation. The standard C implementation of Python uses reference counting to detect inaccessible objects, and another mechanism to collect reference cycles, periodically executing a cycle detection algorithm which looks for inaccessible cycles and deletes the objects involved. The ``gc`` module provides functions to perform a garbage collection, obtain debugging statistics, and tune the collector's parameters. Jython relies on the Java runtime so the JVM's garbage collector is used. This difference can cause some subtle porting problems if your Python code depends on the behavior of the reference counting implementation. Sometimes objects get stuck in tracebacks temporarily and hence are not deallocated when you might expect. Clear the tracebacks with:: import sys sys.exc_clear() sys.exc_traceback = sys.last_traceback = None Tracebacks are used for reporting errors, implementing debuggers and related things. They contain a portion of the program state extracted during the handling of an exception (usually the most recent exception). In the absence of circularities and tracebacks, Python programs need not explicitly manage memory. Why doesn't Python use a more traditional garbage collection scheme? For one thing, this is not a C standard feature and hence it's not portable. (Yes, we know about the Boehm GC library. It has bits of assembler code for *most* common platforms, not for all of them, and although it is mostly transparent, it isn't completely transparent; patches are required to get Python to work with it.) Traditional GC also becomes a problem when Python is embedded into other applications. While in a standalone Python it's fine to replace the standard malloc() and free() with versions provided by the GC library, an application embedding Python may want to have its *own* substitute for malloc() and free(), and may not want Python's. Right now, Python works with anything that implements malloc() and free() properly. In Jython, the following code (which is fine in CPython) will probably run out of file descriptors long before it runs out of memory:: for file in : f = open(file) c = f.read(1) Using the current reference counting and destructor scheme, each new assignment to f closes the previous file. Using GC, this is not guaranteed. If you want to write code that will work with any Python implementation, you should explicitly close the file; this will work regardless of GC:: for file in : f = open(file) c = f.read(1) f.close() Why isn't all memory freed when Python exits? ----------------------------------------------------- Objects referenced from the global namespaces of Python modules are not always deallocated when Python exits. This may happen if there are circular references. There are also certain bits of memory that are allocated by the C library that are impossible to free (e.g. a tool like Purify will complain about these). Python is, however, aggressive about cleaning up memory on exit and does try to destroy every single object. If you want to force Python to delete certain things on deallocation use the ``sys.exitfunc()`` hook to run a function that will force those deletions. Why are there separate tuple and list data types? ------------------------------------------------- Lists and tuples, while similar in many respects, are generally used in fundamentally different ways. Tuples can be thought of as being similar to Pascal records or C structs; they're small collections of related data which may be of different types which are operated on as a group. For example, a Cartesian coordinate is appropriately represented as a tuple of two or three numbers. Lists, on the other hand, are more like arrays in other languages. They tend to hold a varying number of objects all of which have the same type and which are operated on one-by-one. For example, ``os.listdir('.')`` returns a list of strings representing the files in the current directory. Functions which operate on this output would generally not break if you added another file or two to the directory. Tuples are immutable, meaning that once a tuple has been created, you can't replace any of its elements with a new value. Lists are mutable, meaning that you can always change a list's elements. Only immutable elements can be used as dictionary keys, and hence only tuples and not lists can be used as keys. How are lists implemented? -------------------------- Python's lists are really variable-length arrays, not Lisp-style linked lists. The implementation uses a contiguous array of references to other objects, and keeps a pointer to this array and the array's length in a list head structure. This makes indexing a list ``a[i]`` an operation whose cost is independent of the size of the list or the value of the index. When items are appended or inserted, the array of references is resized. Some cleverness is applied to improve the performance of appending items repeatedly; when the array must be grown, some extra space is allocated so the next few times don't require an actual resize. How are dictionaries implemented? ----------------------------------------- Python's dictionaries are implemented as resizable hash tables. Compared to B-trees, this gives better performance for lookup (the most common operation by far) under most circumstances, and the implementation is simpler. Dictionaries work by computing a hash code for each key stored in the dictionary using the ``hash()`` built-in function. The hash code varies widely depending on the key; for example, "Python" hashes to -539294296 while "python", a string that differs by a single bit, hashes to 1142331976. The hash code is then used to calculate a location in an internal array where the value will be stored. Assuming that you're storing keys that all have different hash values, this means that dictionaries take constant time -- O(1), in computer science notation -- to retrieve a key. It also means that no sorted order of the keys is maintained, and traversing the array as the ``.keys()`` and ``.items()`` do will output the dictionary's content in some arbitrary jumbled order. Why must dictionary keys be immutable? ---------------------------------------------- The hash table implementation of dictionaries uses a hash value calculated from the key value to find the key. If the key were a mutable object, its value could change, and thus its hash could also change. But since whoever changes the key object can't tell that it was being used as a dictionary key, it can't move the entry around in the dictionary. Then, when you try to look up the same object in the dictionary it won't be found because its hash value is different. If you tried to look up the old value it wouldn't be found either, because the value of the object found in that hash bin would be different. If you want a dictionary indexed with a list, simply convert the list to a tuple first; the function ``tuple(L)`` creates a tuple with the same entries as the list ``L``. Tuples are immutable and can therefore be used as dictionary keys. Some unacceptable solutions that have been proposed: - Hash lists by their address (object ID). This doesn't work because if you construct a new list with the same value it won't be found; e.g.:: d = {[1,2]: '12'} print d[[1,2]] would raise a KeyError exception because the id of the ``[1,2]`` used in the second line differs from that in the first line. In other words, dictionary keys should be compared using ``==``, not using 'is'. - Make a copy when using a list as a key. This doesn't work because the list, being a mutable object, could contain a reference to itself, and then the copying code would run into an infinite loop. - Allow lists as keys but tell the user not to modify them. This would allow a class of hard-to-track bugs in programs when you forgot or modified a list by accident. It also invalidates an important invariant of dictionaries: every value in ``d.keys()`` is usable as a key of the dictionary. - Mark lists as read-only once they are used as a dictionary key. The problem is that it's not just the top-level object that could change its value; you could use a tuple containing a list as a key. Entering anything as a key into a dictionary would require marking all objects reachable from there as read-only -- and again, self-referential objects could cause an infinite loop. There is a trick to get around this if you need to, but use it at your own risk: You can wrap a mutable structure inside a class instance which has both a __cmp__ and a __hash__ method. You must then make sure that the hash value for all such wrapper objects that reside in a dictionary (or other hash based structure), remain fixed while the object is in the dictionary (or other structure).:: class ListWrapper: def __init__(self, the_list): self.the_list = the_list def __cmp__(self, other): return self.the_list == other.the_list def __hash__(self): l = self.the_list result = 98767 - len(l)*555 for i in range(len(l)): try: result = result + (hash(l[i]) % 9999999) * 1001 + i except: result = (result % 7777777) + i * 333 return result Note that the hash computation is complicated by the possibility that some members of the list may be unhashable and also by the possibility of arithmetic overflow. Furthermore it must always be the case that if ``o1 == o2`` (ie ``o1.__cmp__(o2)==0``) then ``hash(o1)==hash(o2)`` (ie, ``o1.__hash__() == o2.__hash__()``), regardless of whether the object is in a dictionary or not. If you fail to meet these restrictions dictionaries and other hash based structures will misbehave. In the case of ListWrapper, whenever the wrapper object is in a dictionary the wrapped list must not change to avoid anomalies. Don't do this unless you are prepared to think hard about the requirements and the consequences of not meeting them correctly. Consider yourself warned. Why doesn't list.sort() return the sorted list? ------------------------------------------------------- In situations where performance matters, making a copy of the list just to sort it would be wasteful. Therefore, list.sort() sorts the list in place. In order to remind you of that fact, it does not return the sorted list. This way, you won't be fooled into accidentally overwriting a list when you need a sorted copy but also need to keep the unsorted version around. In Python 2.4 a new builtin - sorted() - has been added. This function creates a new list from a passed iterable, sorts it and returns it. As a result, here's the idiom to iterate over the keys of a dictionary in sorted order:: for key in sorted(dict.iterkeys()): ...do whatever with dict[key]... Versions of Python prior to 2.4 need to use the following idiom:: keys = dict.keys() keys.sort() for key in keys: ...do whatever with dict[key]... How do you specify and enforce an interface spec in Python? ------------------------------------------------------------------- An interface specification for a module as provided by languages such as C++ and Java describes the prototypes for the methods and functions of the module. Many feel that compile-time enforcement of interface specifications help in the construction of large programs. Python does not support interface specifications directly, but many of their advantages can be obtained by an appropriate test discipline for components, which can often be very easily accomplished in Python. There is also a tool, PyChecker, which can be used to find problems due to subclassing. A good test suite for a module can at once provide a regression test and serve as both a module interface specification and a set of examples. Many Python modules can be run as a script to provide a simple "self test." Even modules which use complex external interfaces can often be tested in isolation using trivial "stub" emulations of the external interface. The ``doctest`` and ``unittest`` modules or third-party test frameworks can be used to construct exhaustive test suites that exercise every line of code in a module. An appropriate testing discipline can help build large complex applications in Python as well as having interface specifications would. In fact, it can be better because an interface specification cannot test certain properties of a program. For example, the ``append()`` method is expected to add new elements to the end of some internal list; an interface specification cannot test that your ``append()`` implementation will actually do this correctly, but it's trivial to check this property in a test suite. Writing test suites is very helpful, and you might want to design your code with an eye to making it easily tested. One increasingly popular technique, test-directed development, calls for writing parts of the test suite first, before you write any of the actual code. Of course Python allows you to be sloppy and not write test cases at all. Why are default values shared between objects? ---------------------------------------------------------------- This type of bug commonly bites neophyte programmers. Consider this function:: def foo(D={}): # Danger: shared reference to one dict for all calls ... compute something ... D[key] = value return D The first time you call this function, ``D`` contains a single item. The second time, ``D`` contains two items because when ``foo()`` begins executing, ``D`` starts out with an item already in it. It is often expected that a function call creates new objects for default values. This is not what happens. Default values are created exactly once, when the function is defined. If that object is changed, like the dictionary in this example, subsequent calls to the function will refer to this changed object. By definition, immutable objects such as numbers, strings, tuples, and ``None``, are safe from change. Changes to mutable objects such as dictionaries, lists, and class instances can lead to confusion. Because of this feature, it is good programming practice to not use mutable objects as default values. Instead, use ``None`` as the default value and inside the function, check if the parameter is ``None`` and create a new list/dictionary/whatever if it is. For example, don't write:: def foo(dict={}): ... but:: def foo(dict=None): if dict is None: dict = {} # create a new dict for local namespace This feature can be useful. When you have a function that's time-consuming to compute, a common technique is to cache the parameters and the resulting value of each call to the function, and return the cached value if the same value is requested again. This is called "memoizing", and can be implemented like this:: # Callers will never provide a third parameter for this function. def expensive (arg1, arg2, _cache={}): if _cache.has_key((arg1, arg2)): return _cache[(arg1, arg2)] # Calculate the value result = ... expensive computation ... _cache[(arg1, arg2)] = result # Store result in the cache return result You could use a global variable containing a dictionary instead of the default value; it's a matter of taste. Why is there no goto? ------------------------ You can use exceptions to provide a "structured goto" that even works across function calls. Many feel that exceptions can conveniently emulate all reasonable uses of the "go" or "goto" constructs of C, Fortran, and other languages. For example:: class label: pass # declare a label try: ... if (condition): raise label() # goto label ... except label: # where to goto pass ... This doesn't allow you to jump into the middle of a loop, but that's usually considered an abuse of goto anyway. Use sparingly. Why do I get a SyntaxError for a 'continue' inside a 'try'? ------------------------------------------------------------------- This is an implementation limitation, caused by the extremely simple-minded way Python generates bytecode. The ``try`` block pushes something on the "block stack" which the ``continue`` would have to pop off again. The current code generator doesn't have the data structures around so that ``continue`` can generate the right code. Note that Jython doesn't have this restriction! Why can't raw strings (r-strings) end with a backslash? --------------------------------------------------------------- More precisely, they can't end with an odd number of backslashes: the unpaired backslash at the end escapes the closing quote character, leaving an unterminated string. Raw strings were designed to ease creating input for processors (chiefly regular expression engines) that want to do their own backslash escape processing. Such processors consider an unmatched trailing backslash to be an error anyway, so raw strings disallow that. In return, they allow you to pass on the string quote character by escaping it with a backslash. These rules work well when r-strings are used for their intended purpose. If you're trying to build Windows pathnames, note that all Windows system calls accept forward slashes too:: f = open("/mydir/file.txt") # works fine! If you're trying to build a pathname for a DOS command, try e.g. one of :: dir = r"\this\is\my\dos\dir" "\\" dir = r"\this\is\my\dos\dir\ "[:-1] dir = "\\this\\is\\my\\dos\\dir\\" Why doesn't Python have a "with" statement like some other languages? --------------------------------------------------------------------------------------- Because such a construct would be ambiguous. Some languages, such as Object Pascal, Delphi, and C++, use static types. So it is possible to know, in an unambiguous way, what member is being assigned in a "with" clause. This is the main point - the compiler *always* knows the scope of every variable at compile time. Python uses dynamic types. It is impossible to know in advance which attribute will be referenced at runtime. Member attributes may be added or removed from objects on the fly. This would make it impossible to know, from a simple reading, what attribute is being referenced - a local one, a global one, or a member attribute. For instance, take the following incomplete snippet:: def foo(a): with a: print x The snippet assumes that "a" must have a member attribute called "x". However, there is nothing in Python that guarantees that. What should happen if "a" is, let us say, an integer? And if I have a global variable named "x", will it end up being used inside the with block? As you see, the dynamic nature of Python makes such choices much harder. The primary benefit of "with" and similar language features (reduction of code volume) can, however, easily be achieved in Python by assignment. Instead of:: function(args).dict[index][index].a = 21 function(args).dict[index][index].b = 42 function(args).dict[index][index].c = 63 write this:: ref = function(args).dict[index][index] ref.a = 21 ref.b = 42 ref.c = 63 This also has the side-effect of increasing execution speed because name bindings are resolved at run-time in Python, and the second version only needs to perform the resolution once. If the referenced object does not have a, b and c attributes, of course, the end result is still a run-time exception. Why are colons required for the if/while/def/class statements? -------------------------------------------------------------------- The colon is required primarily to enhance readability (one of the results of the experimental ABC language). Consider this:: if a==b print a versus :: if a==b: print a Notice how the second one is slightly easier to read. Notice further how a colon sets off the example in the second line of this FAQ answer; it's a standard usage in English. Another minor reason is that the colon makes it easier for editors with syntax highlighting; they can look for colons to decide when indentation needs to be increased instead of having to do a more elaborate parsing of the program text. python-defaults-2.7.12/faq/programming.html0000664000000000000000000031000212632016514015574 0ustar Programming FAQ

Programming FAQ

Date: 2005-12-21
Version: 8721
Web site:http://www.python.org/

Contents

1   General Questions

1.1   Is there a source code level debugger with breakpoints, single-stepping, etc.?

Yes.

The pdb module is a simple but adequate console-mode debugger for Python. It is part of the standard Python library, and is documented in the Library Reference Manual. You can also write your own debugger by using the code for pdb as an example.

The IDLE interactive development environment, which is part of the standard Python distribution (normally available as Tools/scripts/idle), includes a graphical debugger. There is documentation for the IDLE debugger at http://www.python.org/idle/doc/idle2.html#Debugger

PythonWin is a Python IDE that includes a GUI debugger based on pdb. The Pythonwin debugger colors breakpoints and has quite a few cool features such as debugging non-Pythonwin programs. A reference can be found at http://www.python.org/windows/pythonwin/. Recent versions of PythonWin are available as a part of the ActivePython distribution (see http://www.activestate.com/Products/ActivePython/index.html).

Boa Constructor is an IDE and GUI builder that uses wxPython. It offers visual frame creation and manipulation, an object inspector, many views on the source like object browsers, inheritance hierarchies, doc string generated html documentation, an advanced debugger, integrated help, and Zope support.

Eric3 is an IDE built on PyQt and the Scintilla editing component.

Pydb is a version of the standard Python debugger pdb, modified for use with DDD (Data Display Debugger), a popular graphical debugger front end. Pydb can be found at http://packages.debian.org/unstable/devel/pydb.html> and DDD can be found at http://www.gnu.org/software/ddd.

There are a number of commmercial Python IDEs that include graphical debuggers. They include:

1.2   Is there a tool to help find bugs or perform static analysis?

Yes.

PyChecker is a static analysis tool that finds bugs in Python source code and warns about code complexity and style. You can get PyChecker from http://pychecker.sf.net.

Pylint is another tool that checks if a module satisfies a coding standard, and also makes it possible to write plug-ins to add a custom feature. In addition to the bug checking that PyChecker performs, Pylint offers some additional features such as checking line length, whether variable names are well-formed according to your coding standard, whether declared interfaces are fully implemented, and more. http://www.logilab.org/projects/pylint/documentation provides a full list of Pylint's features.

1.3   How can I create a stand-alone binary from a Python script?

You don't need the ability to compile Python to C code if all you want is a stand-alone program that users can download and run without having to install the Python distribution first. There are a number of tools that determine the set of modules required by a program and bind these modules together with a Python binary to produce a single executable.

One is to use the freeze tool, which is included in the Python source tree as Tools/freeze. It converts Python byte code to C arrays; a C compiler you can embed all your modules into a new program, which is then linked with the standard Python modules.

It works by scanning your source recursively for import statements (in both forms) and looking for the modules in the standard Python path as well as in the source directory (for built-in modules). It then turns the bytecode for modules written in Python into C code (array initializers that can be turned into code objects using the marshal module) and creates a custom-made config file that only contains those built-in modules which are actually used in the program. It then compiles the generated C code and links it with the rest of the Python interpreter to form a self-contained binary which acts exactly like your script.

Obviously, freeze requires a C compiler. There are several other utilities which don't. The first is Gordon McMillan's installer at

http://www.mcmillan-inc.com/install1.html

which works on Windows, Linux and at least some forms of Unix.

Another is Thomas Heller's py2exe (Windows only) at

http://starship.python.net/crew/theller/py2exe

A third is Christian Tismer's SQFREEZE which appends the byte code to a specially-prepared Python interpreter that can find the byte code in the executable. It's possible that a similar approach will be added to Python 2.4, due out some time in 2004.

Other tools include Fredrik Lundh's Squeeze and Anthony Tuininga's cx_Freeze.

1.4   Are there coding standards or a style guide for Python programs?

Yes. The coding style required for standard library modules is documented as PEP 8.

1.5   My program is too slow. How do I speed it up?

That's a tough one, in general. There are many tricks to speed up Python code; consider rewriting parts in C as a last resort.

In some cases it's possible to automatically translate Python to C or x86 assembly language, meaning that you don't have to modify your code to gain increased speed.

Pyrex can compile a slightly modified version of Python code into a C extension, and can be used on many different platforms.

Psyco is a just-in-time compiler that translates Python code into x86 assembly language. If you can use it, Psyco can provide dramatic speedups for critical functions.

The rest of this answer will discuss various tricks for squeezing a bit more speed out of Python code. Never apply any optimization tricks unless you know you need them, after profiling has indicated that a particular function is the heavily executed hot spot in the code. Optimizations almost always make the code less clear, and you shouldn't pay the costs of reduced clarity (increased development time, greater likelihood of bugs) unless the resulting performance benefit is worth it.

There is a page on the wiki devoted to performance tips.

Guido van Rossum has written up an anecdote related to optimization at http://www.python.org/doc/essays/list2str.html.

One thing to notice is that function and (especially) method calls are rather expensive; if you have designed a purely OO interface with lots of tiny functions that don't do much more than get or set an instance variable or call another method, you might consider using a more direct way such as directly accessing instance variables. Also see the standard module "profile" (described in the Library Reference manual) which makes it possible to find out where your program is spending most of its time (if you have some patience -- the profiling itself can slow your program down by an order of magnitude).

Remember that many standard optimization heuristics you may know from other programming experience may well apply to Python. For example it may be faster to send output to output devices using larger writes rather than smaller ones in order to reduce the overhead of kernel system calls. Thus CGI scripts that write all output in "one shot" may be faster than those that write lots of small pieces of output.

Also, be sure to use Python's core features where appropriate. For example, slicing allows programs to chop up lists and other sequence objects in a single tick of the interpreter's mainloop using highly optimized C implementations. Thus to get the same effect as:

L2 = []
for i in range[3]:
     L2.append(L1[i])

it is much shorter and far faster to use

L2 = list(L1[:3]) # "list" is redundant if L1 is a list.

Note that the functionally-oriented builtins such as map(), zip(), and friends can be a convenient accelerator for loops that perform a single task. For example to pair the elements of two lists together:

>>> zip([1,2,3], [4,5,6])
[(1, 4), (2, 5), (3, 6)]

or to compute a number of sines:

>>> map( math.sin, (1,2,3,4))
[0.841470984808, 0.909297426826, 0.14112000806,   -0.756802495308]

The operation completes very quickly in such cases.

Other examples include the join() and split() methods of string objects. For example if s1..s7 are large (10K+) strings then "".join([s1,s2,s3,s4,s5,s6,s7])` may be far faster than the more obvious ``s1+s2+s3+s4+s5+s6+s7, since the "summation" will compute many subexpressions, whereas join() does all the copying in one pass. For manipulating strings, use the replace() method on string objects. Use regular expressions only when you're not dealing with constant string patterns. Consider using the string formatting operations string % tuple and string % dictionary.

Be sure to use the list.sort() builtin method to do sorting, and see the sorting mini-HOWTO for examples of moderately advanced usage. list.sort() beats other techniques for sorting in all but the most extreme circumstances.

Another common trick is to "push loops into functions or methods." For example suppose you have a program that runs slowly and you use the profiler to determine that a Python function ff() is being called lots of times. If you notice that ff ():

def ff(x):
    ...do something with x computing result...
    return result

tends to be called in loops like:

list = map(ff, oldlist)

or:

for x in sequence:
    value = ff(x)
    ...do something with value...

then you can often eliminate function call overhead by rewriting ff() to:

def ffseq(seq):
    resultseq = []
    for x in seq:
        ...do something with x computing result...
        resultseq.append(result)
    return resultseq

and rewrite the two examples to list = ffseq(oldlist) and to:

for value in ffseq(sequence):
    ...do something with value...

Single calls to ff(x) translate to ffseq([x])[0] with little penalty. Of course this technique is not always appropriate and there are other variants which you can figure out.

You can gain some performance by explicitly storing the results of a function or method lookup into a local variable. A loop like:

for key in token:
    dict[key] = dict.get(key, 0) + 1

resolves dict.get every iteration. If the method isn't going to change, a slightly faster implementation is:

dict_get = dict.get  # look up the method once
for key in token:
    dict[key] = dict_get(key, 0) + 1

Default arguments can be used to determine values once, at compile time instead of at run time. This can only be done for functions or objects which will not be changed during program execution, such as replacing

def degree_sin(deg):
    return math.sin(deg * math.pi / 180.0)

with

def degree_sin(deg, factor = math.pi/180.0, sin = math.sin):
    return sin(deg * factor)

Because this trick uses default arguments for terms which should not be changed, it should only be used when you are not concerned with presenting a possibly confusing API to your users.

2   Core Language

2.1   How do you set a global variable in a function?

Did you do something like this?

x = 1 # make a global

def f():
      print x # try to print the global
      ...
      for j in range(100):
           if q>3:
              x=4

Any variable assigned in a function is local to that function. unless it is specifically declared global. Since a value is bound to x as the last statement of the function body, the compiler assumes that x is local. Consequently the print x attempts to print an uninitialized local variable and will trigger a NameError.

The solution is to insert an explicit global declaration at the start of the function:

def f():
      global x
      print x # try to print the global
      ...
      for j in range(100):
           if q>3:
              x=4

In this case, all references to x are interpreted as references to the x from the module namespace.

2.2   What are the rules for local and global variables in Python?

In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a new value anywhere within the function's body, it's assumed to be a local. If a variable is ever assigned a new value inside the function, the variable is implicitly local, and you need to explicitly declare it as 'global'.

Though a bit surprising at first, a moment's consideration explains this. On one hand, requiring global for assigned variables provides a bar against unintended side-effects. On the other hand, if global was required for all global references, you'd be using global all the time. You'd have to declare as global every reference to a builtin function or to a component of an imported module. This clutter would defeat the usefulness of the global declaration for identifying side-effects.

2.3   How do I share global variables across modules?

The canonical way to share information across modules within a single program is to create a special module (often called config or cfg). Just import the config module in all modules of your application; the module then becomes available as a global name. Because there is only one instance of each module, any changes made to the module object get reflected everywhere. For example:

config.py:

x = 0   # Default value of the 'x' configuration setting

mod.py:

import config
config.x = 1

main.py:

import config
import mod
print config.x

Note that using a module is also the basis for implementing the Singleton design pattern, for the same reason.

2.4   What are the "best practices" for using import in a module?

In general, don't use from modulename import *. Doing so clutters the importer's namespace. Some people avoid this idiom even with the few modules that were designed to be imported in this manner. Modules designed in this manner include Tkinter, and threading.

Import modules at the top of a file. Doing so makes it clear what other modules your code requires and avoids questions of whether the module name is in scope. Using one import per line makes it easy to add and delete module imports, but using multiple imports per line uses less screen space.

It's good practice if you import modules in the following order:

  1. standard libary modules -- e.g. sys, os, getopt, re)
  2. third-party library modules (anything installed in Python's site-packages directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc.
  3. locally-developed modules

Never use relative package imports. If you're writing code that's in the package.sub.m1 module and want to import package.sub.m2, do not just write import m2, even though it's legal. Write from package.sub import m2 instead. Relative imports can lead to a module being initialized twice, leading to confusing bugs.

It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. Gordon McMillan says:

Circular imports are fine where both modules use the "import <module>" form of import. They fail when the 2nd module wants to grab a name out of the first ("from module import name") and the import is at the top level. That's because names in the 1st are not yet available, because the first module is busy importing the 2nd.

In this case, if the second module is only used in one function, then the import can easily be moved into that function. By the time the import is called, the first module will have finished initializing, and the second module can do its import.

It may also be necessary to move imports out of the top level of code if some of the modules are platform-specific. In that case, it may not even be possible to import all of the modules at the top of the file. In this case, importing the correct modules in the corresponding platform-specific code is a good option.

Only move imports into a local scope, such as inside a function definition, if it's necessary to solve a problem such as avoiding a circular import or are trying to reduce the initialization time of a module. This technique is especially helpful if many of the imports are unnecessary depending on how the program executes. You may also want to move imports into a function if the modules are only ever used in that function. Note that loading a module the first time may be expensive because of the one time initialization of the module, but loading a module multiple times is virtually free, costing only a couple of dictionary lookups. Even if the module name has gone out of scope, the module is probably available in sys.modules.

If only instances of a specific class use a module, then it is reasonable to import the module in the class's __init__ method and then assign the module to an instance variable so that the module is always available (via that instance variable) during the life of the object. Note that to delay an import until the class is instantiated, the import must be inside a method. Putting the import inside the class but outside of any method still causes the import to occur when the module is initialized.

2.5   How can I pass optional or keyword parameters from one function to another?

Collect the arguments using the * and ** specifiers in the function's parameter list; this gives you the positional arguments as a tuple and the keyword arguments as a dictionary. You can then pass these arguments when calling another function by using * and **:

def f(x, *tup, **kwargs):
        ...
        kwargs['width']='14.3c'
        ...
        g(x, *tup, **kwargs)

In the unlikely case that you care about Python versions older than 2.0, use 'apply':

def f(x, *tup, **kwargs):
        ...
        kwargs['width']='14.3c'
        ...
        apply(g, (x,)+tup, kwargs)

2.6   How do I write a function with output parameters (call by reference)?

Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there's no alias between an argument name in the caller and callee, and so no call-by-reference per se. You can achieve the desired effect in a number of ways.

  1. By returning a tuple of the results:

    def func2(a, b):
        a = 'new-value'        # a and b are local names
        b = b + 1              # assigned to new objects
        return a, b            # return new values
    
    x, y = 'old-value', 99
    x, y = func2(x, y)
    print x, y                 # output: new-value 100
    

    This is almost always the clearest solution.

  2. By using global variables. This isn't thread-safe, and is not recommended.

  3. By passing a mutable (changeable in-place) object:

    def func1(a):
        a[0] = 'new-value'     # 'a' references a mutable list
        a[1] = a[1] + 1        # changes a shared object
    
    args = ['old-value', 99]
    func1(args)
    print args[0], args[1]     # output: new-value 100
    
  4. By passing in a dictionary that gets mutated:

    def func3(args):
        args['a'] = 'new-value'     # args is a mutable dictionary
        args['b'] = args['b'] + 1   # change it in-place
    
    args = {'a':' old-value', 'b': 99}
    func3(args)
    print args['a'], args['b']
    
  5. Or bundle up values in a class instance:

    class callByRef:
        def __init__(self, **args):
            for (key, value) in args.items():
                setattr(self, key, value)
    
    def func4(args):
        args.a = 'new-value'        # args is a mutable callByRef
        args.b = args.b + 1         # change object in-place
    
    args = callByRef(a='old-value', b=99)
    func4(args)
    print args.a, args.b
    

    There's almost never a good reason to get this complicated.

Your best choice is to return a tuple containing the multiple results.

2.7   How do you make a higher order function in Python?

You have two choices: you can use nested scopes or you can use callable objects. For example, suppose you wanted to define linear(a,b) which returns a function f(x) that computes the value a*x+b. Using nested scopes:

def linear(a,b):
    def result(x):
        return a*x + b
    return result

Or using a callable object:

class linear:
   def __init__(self, a, b):
       self.a, self.b = a,b
   def __call__(self, x):
       return self.a * x + self.b

In both cases:

taxes = linear(0.3,2)

gives a callable object where taxes(10e6) == 0.3 * 10e6 + 2.

The callable object approach has the disadvantage that it is a bit slower and results in slightly longer code. However, note that a collection of callables can share their signature via inheritance:

class exponential(linear):
   # __init__ inherited
   def __call__(self, x):
       return self.a * (x ** self.b)

Object can encapsulate state for several methods:

class counter:
    value = 0
    def set(self, x): self.value = x
    def up(self): self.value=self.value+1
    def down(self): self.value=self.value-1

count = counter()
inc, dec, reset = count.up, count.down, count.set

Here inc(), dec() and reset() act like functions which share the same counting variable.

2.8   How do I copy an object in Python?

In general, try copy.copy() or copy.deepcopy() for the general case. Not all objects can be copied, but most can.

Some objects can be copied more easily. Dictionaries have a copy() method:

newdict = olddict.copy()

Sequences can be copied by slicing:

new_l = l[:]

2.9   How can I find the methods or attributes of an object?

For an instance x of a user-defined class, dir(x) returns an alphabetized list of the names containing the instance attributes and methods and attributes defined by its class.

2.10   How can my code discover the name of an object?

Generally speaking, it can't, because objects don't really have names. Essentially, assignment always binds a name to a value; The same is true of def and class statements, but in that case the value is a callable. Consider the following code:

class A:
    pass

B = A

a = B()
b = a
print b
<__main__.A instance at 016D07CC>
print a
<__main__.A instance at 016D07CC>

Arguably the class has a name: even though it is bound to two names and invoked through the name B the created instance is still reported as an instance of class A. However, it is impossible to say whether the instance's name is a or b, since both names are bound to the same value.

Generally speaking it should not be necessary for your code to "know the names" of particular values. Unless you are deliberately writing introspective programs, this is usually an indication that a change of approach might be beneficial.

In comp.lang.python, Fredrik Lundh once gave an excellent analogy in answer to this question:

The same way as you get the name of that cat you found on your porch: the cat (object) itself cannot tell you its name, and it doesn't really care -- so the only way to find out what it's called is to ask all your neighbours (namespaces) if it's their cat (object)...

....and don't be surprised if you'll find that it's known by many names, or no name at all!

2.11   Is there an equivalent of C's "?:" ternary operator?

No. In many cases you can mimic a?b:c with "a and b or c", but there's a flaw: if b is zero (or empty, or None -- anything that tests false) then c will be selected instead. In many cases you can prove by looking at the code that this can't happen (e.g. because b is a constant or has a type that can never be false), but in general this can be a problem.

Tim Peters (who wishes it was Steve Majewski) suggested the following solution: (a and [b] or [c])[0]. Because [b] is a singleton list it is never false, so the wrong path is never taken; then applying [0] to the whole thing gets the b or c that you really wanted. Ugly, but it gets you there in the rare cases where it is really inconvenient to rewrite your code using 'if'.

The best course is usually to write a simple if...else statement. Another solution is to implement the "?:" operator as a function:

def q(cond,on_true,on_false):
    if cond:
        if not isfunction(on_true): return on_true
        else: return apply(on_true)
    else:
        if not isfunction(on_false): return on_false
        else: return apply(on_false)

In most cases you'll pass b and c directly: q(a,b,c). To avoid evaluating b or c when they shouldn't be, encapsulate them within a lambda function, e.g.: q(a,lambda: b, lambda: c).

It has been asked why Python has no if-then-else expression. There are several answers: many languages do just fine without one; it can easily lead to less readable code; no sufficiently "Pythonic" syntax has been discovered; a search of the standard library found remarkably few places where using an if-then-else expression would make the code more understandable.

In 2002, PEP 308 was written proposing several possible syntaxes and the community was asked to vote on the issue. The vote was inconclusive. Most people liked one of the syntaxes, but also hated other syntaxes; many votes implied that people preferred no ternary operator rather than having a syntax they hated.

2.12   Is it possible to write obfuscated one-liners in Python?

Yes. Usually this is done by nesting lambda within lambda. See the following three examples, due to Ulf Bartelt:

# Primes < 1000
print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0,
map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000)))

# First 10 Fibonacci numbers
print map(lambda x,f=lambda x,f:(x<=1) or (f(x-1,f)+f(x-2,f)): f(x,f),
range(10))

# Mandelbrot set
print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y,
Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM,
Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro,
i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y
>=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr(
64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy
))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24)
#    \___ ___  \___ ___  |   |   |__ lines on screen
#        V          V      |   |______ columns on screen
#        |          |      |__________ maximum of "iterations"
#        |          |_________________ range on y axis
#        |____________________________ range on x axis

Don't try this at home, kids!

3   Numbers and strings

3.1   How do I specify hexadecimal and octal integers?

To specify an octal digit, precede the octal value with a zero. For example, to set the variable "a" to the octal value "10" (8 in decimal), type:

>>> a = 010
>>> a
8

Hexadecimal is just as easy. Simply precede the hexadecimal number with a zero, and then a lower or uppercase "x". Hexadecimal digits can be specified in lower or uppercase. For example, in the Python interpreter:

>>> a = 0xa5
>>> a
165
>>> b = 0XB2
>>> b
178

3.2   Why does -22 / 10 return -3?

It's primarily driven by the desire that i%j have the same sign as j. If you want that, and also want:

i == (i/j)*j + (i%j)

then integer division has to return the floor. C also requres that identity to hold, and then compilers that truncate i/j need to make i%j have the same sign as i.

There are few real use cases for i%j when j is negative. When j is positive, there are many, and in virtually all of them it's more useful for i%j to be >= 0. If the clock says 10 now, what did it say 200 hours ago? -190 % 12 == 2 is useful; -190 % 12 == -10 is a bug waiting to bite.

3.3   How do I convert a string to a number?

For integers, use the built-in int() type constructor, e.g. int('144') == 144. Similarly, float() converts to floating-point, e.g. float('144') == 144.0.

By default, these interpret the number as decimal, so that int('0144') == 144 and int('0x144') raises ValueError. int(string, base) takes the base to convert from as a second optional argument, so int('0x144', 16) == 324. If the base is specified as 0, the number is interpreted using Python's rules: a leading '0' indicates octal, and '0x' indicates a hex number.

Do not use the built-in function eval() if all you need is to convert strings to numbers. eval() will be significantly slower and it presents a security risk: someone could pass you a Python expression that might have unwanted side effects. For example, someone could pass __import__('os').system("rm -rf $HOME") which would erase your home directory.

eval() also has the effect of interpreting numbers as Python expressions, so that e.g. eval('09') gives a syntax error because Python regards numbers starting with '0' as octal (base 8).

3.4   How do I convert a number to a string?

To convert, e.g., the number 144 to the string '144', use the built-in function str(). If you want a hexadecimal or octal representation, use the built-in functions hex() or oct(). For fancy formatting, use the % operator on strings, e.g. "%04d" % 144 yields '0144' and "%.3f" % (1/3.0) yields '0.333'. See the library reference manual for details.

3.5   How do I modify a string in place?

You can't, because strings are immutable. If you need an object with this ability, try converting the string to a list or use the array module:

>>> s = "Hello, world"
>>> a = list(s)
>>> print a
['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd']
>>> a[7:] = list("there!")
>>> ''.join(a)
'Hello, there!'

>>> import array
>>> a = array.array('c', s)
>>> print a
array('c', 'Hello, world')
>>> a[0] = 'y' ; print a
array('c', 'yello world')
>>> a.tostring()
'yello, world'

3.6   How do I use strings to call functions/methods?

There are various techniques.

  • The best is to use a dictionary that maps strings to functions. The primary advantage of this technique is that the strings do not need to match the names of the functions. This is also the primary technique used to emulate a case construct:

    def a():
        pass
    
    def b():
        pass
    
    dispatch = {'go': a, 'stop': b}  # Note lack of parens for funcs
    
    dispatch[get_input()]()  # Note trailing parens to call function
    
  • Use the built-in function getattr():

    import foo
    getattr(foo, 'bar')()
    

    Note that getattr() works on any object, including classes, class instances, modules, and so on.

    This is used in several places in the standard library, like this:

    class Foo:
        def do_foo(self):
            ...
    
        def do_bar(self):
            ...
    
     f = getattr(foo_instance, 'do_' + opname)
     f()
    
  • Use locals() or eval() to resolve the function name:

    def myFunc():
        print "hello"
    
    fname = "myFunc"
    
    f = locals()[fname]
    f()
    
    f = eval(fname)
    f()
    

    Note: Using eval() is slow and dangerous. If you don't have absolute control over the contents of the string, someone could pass a string that resulted in an arbitrary function being executed.

3.7   Is there an equivalent to Perl's chomp() for removing trailing newlines from strings?

Starting with Python 2.2, you can use S.rstrip("\r\n") to remove all occurances of any line terminator from the end of the string S without removing other trailing whitespace. If the string S represents more than one line, with several empty lines at the end, the line terminators for all the blank lines will be removed:

>>> lines = ("line 1 \r\n"
...          "\r\n"
...          "\r\n")
>>> lines.rstrip("\n\r")
"line 1 "

Since this is typically only desired when reading text one line at a time, using S.rstrip() this way works well.

For older versions of Python, There are two partial substitutes:

  • If you want to remove all trailing whitespace, use the rstrip() method of string objects. This removes all trailing whitespace, not just a single newline.
  • Otherwise, if there is only one line in the string S, use S.splitlines()[0].

3.8   Is there a scanf() or sscanf() equivalent?

Not as such.

For simple input parsing, the easiest approach is usually to split the line into whitespace-delimited words using the split() method of string objects and then convert decimal strings to numeric values using int() or float(). split() supports an optional "sep" parameter which is useful if the line uses something other than whitespace as a separator.

For more complicated input parsing, regular expressions more powerful than C's sscanf() and better suited for the task.

3.9   What does 'UnicodeError: ASCII [decoding,encoding] error: ordinal not in range(128)' mean?

This error indicates that your Python installation can handle only 7-bit ASCII strings. There are a couple ways to fix or work around the problem.

If your programs must handle data in arbitary character set encodings, the environment the application runs in will generally identify the encoding of the data it is handing you. You need to convert the input to Unicode data using that encoding. For example, a program that handles email or web input will typically find character set encoding information in Content-Type headers. This can then be used to properly convert input data to Unicode. Assuming the string referred to by value is encoded as UTF-8:

value = unicode(value, "utf-8")

will return a Unicode object. If the data is not correctly encoded as UTF-8, the above call will raise a UnicodeError exception.

If you only want strings coverted to Unicode which have non-ASCII data, you can try converting them first assuming an ASCII encoding, and then generate Unicode objects if that fails:

try:
    x = unicode(value, "ascii")
except UnicodeError:
    value = unicode(value, "utf-8")
else:
    # value was valid ASCII data
    pass

It's possible to set a default encoding in a file called sitecustomize.py that's part of the Python library. However, this isn't recommended because changing the Python-wide default encoding may cause third-party extension modules to fail.

Note that on Windows, there is an encoding known as "mbcs", which uses an encoding specific to your current locale. In many cases, and particularly when working with COM, this may be an appropriate default encoding to use.

4   Sequences (Tuples/Lists)

4.1   How do I convert between tuples and lists?

The function tuple(seq) converts any sequence (actually, any iterable) into a tuple with the same items in the same order.

For example, tuple([1, 2, 3]) yields (1, 2, 3) and tuple('abc') yields ('a', 'b', 'c'). If the argument is a tuple, it does not make a copy but returns the same object, so it is cheap to call tuple() when you aren't sure that an object is already a tuple.

The function list(seq) converts any sequence or iterable into a list with the same items in the same order. For example, list((1, 2, 3)) yields [1, 2, 3] and list('abc') yields ['a', 'b', 'c']. If the argument is a list, it makes a copy just like seq[:] would.

4.2   What's a negative index?

Python sequences are indexed with positive numbers and negative numbers. For positive numbers 0 is the first index 1 is the second index and so forth. For negative indices -1 is the last index and -2 is the pentultimate (next to last) index and so forth. Think of seq[-n] as the same as seq[len(seq)-n].

Using negative indices can be very convenient. For example S[:-1] is all of the string except for its last character, which is useful for removing the trailing newline from a string.

4.3   How do I iterate over a sequence in reverse order?

If it is a list, the fastest solution is

list.reverse()
try:
    for x in list:
        "do something with x"
finally:
    list.reverse()

This has the disadvantage that while you are in the loop, the list is temporarily reversed. If you don't like this, you can make a copy. This appears expensive but is actually faster than other solutions:

rev = list[:]
rev.reverse()
for x in rev:
        <do something with x>

If it's not a list, a more general but slower solution is:

for i in range(len(sequence)-1, -1, -1):
        x = sequence[i]
        <do something with x>

A more elegant solution, is to define a class which acts as a sequence and yields the elements in reverse order (solution due to Steve Majewski):

class Rev:
        def __init__(self, seq):
                self.forw = seq
        def __len__(self):
                return len(self.forw)
        def __getitem__(self, i):
                return self.forw[-(i + 1)]

You can now simply write:

for x in Rev(list):
        <do something with x>

Unfortunately, this solution is slowest of all, due to the method call overhead.

With Python 2.3, you can use an extended slice syntax:

for x in sequence[::-1]:
       <do something with x>

4.4   How do you remove duplicates from a list?

See the Python Cookbook for a long discussion of many ways to do this:

http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560

If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:

if List:
   List.sort()
   last = List[-1]
   for i in range(len(List)-2, -1, -1):
       if last==List[i]: del List[i]
       else: last=List[i]

If all elements of the list may be used as dictionary keys (i.e. they are all hashable) this is often faster

d = {}
for x in List: d[x]=x
List = d.values()

4.5   How do you make an array in Python?

Use a list:

["this", 1, "is", "an", "array"]

Lists are equivalent to C or Pascal arrays in their time complexity; the primary difference is that a Python list can contain objects of many different types.

The array module also provides methods for creating arrays of fixed types with compact representations, but they are slower to index than lists. Also note that the Numeric extensions and others define array-like structures with various characteristics as well.

To get Lisp-style linked lists, you can emulate cons cells using tuples:

lisp_list = ("like",  ("this",  ("example", None) ) )

If mutability is desired, you could use lists instead of tuples. Here the analogue of lisp car is lisp_list[0] and the analogue of cdr is lisp_list[1]. Only do this if you're sure you really need to, because it's usually a lot slower than using Python lists.

4.6   How do I create a multidimensional list?

You probably tried to make a multidimensional array like this:

A = [[None] * 2] * 3

This looks correct if you print it:

>>> A
[[None, None], [None, None], [None, None]]

But when you assign a value, it shows up in multiple places:

>>> A[0][0] = 5
>>> A
[[5, None], [5, None], [5, None]]

The reason is that replicating a list with * doesn't create copies, it only creates references to the existing objects. The *3 creates a list containing 3 references to the same list of length two. Changes to one row will show in all rows, which is almost certainly not what you want.

The suggested approach is to create a list of the desired length first and then fill in each element with a newly created list:

A = [None]*3
for i in range(3):
     A[i] = [None] * 2

This generates a list containing 3 different lists of length two. You can also use a list comprehension:

w,h = 2,3
A = [ [None]*w for i in range(h) ]

Or, you can use an extension that provides a matrix datatype; Numeric Python is the best known.

4.7   How do I apply a method to a sequence of objects?

Use a list comprehension:

result = [obj.method() for obj in List]

More generically, you can try the following function:

def method_map(objects, method, arguments):
     """method_map([a,b], "meth", (1,2)) gives [a.meth(1,2), b.meth(1,2)]"""
     nobjects = len(objects)
     methods = map(getattr, objects, [method]*nobjects)
     return map(apply, methods, [arguments]*nobjects)

5   Dictionaries

5.1   How can I get a dictionary to display its keys in a consistent order?

You can't. Dictionaries store their keys in an unpredictable order, so the display order of a dictionary's elements will be similarly unpredictable.

This can be frustrating if you want to save a printable version to a file, make some changes and then compare it with some other printed dictionary. In this case, use the pprint module to pretty-print the dictionary; the items will be presented in order sorted by the key.

A more complicated solution is to subclass UserDict.UserDict to create a SortedDict class that prints itself in a predictable order. Here's one simpleminded implementation of such a class:

import UserDict, string

class SortedDict(UserDict.UserDict):
  def __repr__(self):
    result = []
    append = result.append
    keys = self.data.keys()
    keys.sort()
    for k in keys:
      append("%s: %s" % (`k`, `self.data[k]`))
    return "{%s}" % string.join(result, ", ")

  ___str__ = __repr__

This will work for many common situations you might encounter, though it's far from a perfect solution. The largest flaw is that if some values in the dictionary are also dictionaries, their values won't be presented in any particular order.

5.2   I want to do a complicated sort: can you do a Schwartzian Transform in Python?

Yes, it's quite simple with list comprehensions.

The technique, attributed to Randal Schwartz of the Perl community, sorts the elements of a list by a metric which maps each element to its "sort value". To sort a list of strings by their uppercase values:

tmp1 = [ (x.upper(), x) for x in L ] # Schwartzian transform
tmp1.sort()
Usorted = [ x[1] for x in tmp1 ]

To sort by the integer value of a subfield extending from positions 10-15 in each string:

tmp2 = [ (int(s[10:15]), s) for s in L ] # Schwartzian transform
tmp2.sort()
Isorted = [ x[1] for x in tmp2 ]

Note that Isorted may also be computed by

def intfield(s):
    return int(s[10:15])

def Icmp(s1, s2):
    return cmp(intfield(s1), intfield(s2))

Isorted = L[:]
Isorted.sort(Icmp)

but since this method calls intfield() many times for each element of L, it is slower than the Schwartzian Transform.

5.3   How can I sort one list by values from another list?

Merge them into a single list of tuples, sort the resulting list, and then pick out the element you want.

>>> list1 = ["what", "I'm", "sorting", "by"]
>>> list2 = ["something", "else", "to", "sort"]
>>> pairs = zip(list1, list2)
>>> pairs
[('what', 'something'), ("I'm", 'else'), ('sorting', 'to'), ('by', 'sort')]
>>> pairs.sort()
>>> result = [ x[1] for x in pairs ]
>>> result
['else', 'sort', 'to', 'something']

An alternative for the last step is:

result = []
for p in pairs: result.append(p[1])

If you find this more legible, you might prefer to use this instead of the final list comprehension. However, it is almost twice as slow for long lists. Why? First, the append() operation has to reallocate memory, and while it uses some tricks to avoid doing that each time, it still has to do it occasionally, and that costs quite a bit. Second, the expression "result.append" requires an extra attribute lookup, and third, there's a speed reduction from having to make all those function calls.

6   Objects

6.1   What is a class?

A class is the particular object type created by executing a class statement. Class objects are used as templates to create instance objects, which embody both the data (attributes) and code (methods) specific to a datatype.

A class can be based on one or more other classes, called its base class(es). It then inherits the attributes and methods of its base classes. This allows an object model to be successively refined by inheritance. You might have a generic Mailbox class that provides basic accessor methods for a mailbox, and subclasses such as MboxMailbox, MaildirMailbox, OutlookMailbox that handle various specific mailbox formats.

6.2   What is a method?

A method is a function on some object x that you normally call as x.name(arguments...). Methods are defined as functions inside the class definition:

class C:
    def meth (self, arg):
        return arg*2 + self.attribute

6.3   What is self?

Self is merely a conventional name for the first argument of a method. A method defined as meth(self, a, b, c) should be called as x.meth(a, b, c) for some instance x of the class in which the definition occurs; the called method will think it is called as meth(x, a, b, c).

See also Why must 'self' be used explicitly in method definitions and calls?

6.4   How do I check if an object is an instance of a given class or of a subclass of it?

Use the built-in function isinstance(obj, cls). You can check if an object is an instance of any of a number of classes by providing a tuple instead of a single class, e.g. isinstance(obj, (class1, class2, ...)), and can also check whether an object is one of Python's built-in types, e.g. isinstance(obj, str) or isinstance(obj, (int, long, float, complex)).

Note that most programs do not use isinstance() on user-defined classes very often. If you are developing the classes yourself, a more proper object-oriented style is to define methods on the classes that encapsulate a particular behaviour, instead of checking the object's class and doing a different thing based on what class it is. For example, if you have a function that does something:

def search (obj):
    if isinstance(obj, Mailbox):
        # ... code to search a mailbox
    elif isinstance(obj, Document):
        # ... code to search a document
    elif ...

A better approach is to define a search() method on all the classes and just call it:

class Mailbox:
    def search(self):
        # ... code to search a mailbox

class Document:
    def search(self):
        # ... code to search a document

obj.search()

6.5   What is delegation?

Delegation is an object oriented technique (also called a design pattern). Let's say you have an object x and want to change the behaviour of just one of its methods. You can create a new class that provides a new implementation of the method you're interested in changing and delegates all other methods to the corresponding method of x.

Python programmers can easily implement delegation. For example, the following class implements a class that behaves like a file but converts all written data to uppercase:

class UpperOut:
      def __init__(self, outfile):
            self.__outfile = outfile
      def write(self, s):
            self.__outfile.write(s.upper())
      def __getattr__(self, name):
            return getattr(self.__outfile, name)

Here the UpperOut class redefines the write() method to convert the argument string to uppercase before calling the underlying self.__outfile.write() method. All other methods are delegated to the underlying self.__outfile object. The delegation is accomplished via the __getattr__ method; consult the language reference for more information about controlling attribute access.

Note that for more general cases delegation can get trickier. When attributes must be set as well as retrieved, the class must define a __settattr__ method too, and it must do so carefully. The basic implementation of __setattr__ is roughly equivalent to the following:

class X:
     ...
     def __setattr__(self, name, value):
          self.__dict__[name] = value
     ...

Most __setattr__ implementations must modify self.__dict__ to store local state for self without causing an infinite recursion.

6.6   How do I call a method defined in a base class from a derived class that overrides it?

If you're using new-style classes, use the built-in super() function:

class Derived(Base):
    def meth (self):
        super(Derived, self).meth()

If you're using classic classes: For a class definition such as class Derived(Base): ... you can call method meth() defined in Base (or one of Base's base classes) as Base.meth(self, arguments...). Here, Base.meth is an unbound method, so you need to provide the self argument.

6.7   How can I organize my code to make it easier to change the base class?

You could define an alias for the base class, assign the real base class to it before your class definition, and use the alias throughout your class. Then all you have to change is the value assigned to the alias. Incidentally, this trick is also handy if you want to decide dynamically (e.g. depending on availability of resources) which base class to use. Example:

BaseAlias = <real base class>
class Derived(BaseAlias):
        def meth(self):
                BaseAlias.meth(self)
                ...

6.8   How do I create static class data and static class methods?

Static data (in the sense of C++ or Java) is easy; static methods (again in the sense of C++ or Java) are not supported directly.

For static data, simply define a class attribute. To assign a new value to the attribute, you have to explicitly use the class name in the assignment:

class C:
    count = 0   # number of times C.__init__ called

    def __init__(self):
        C.count = C.count + 1

    def getcount(self):
        return C.count  # or return self.count

c.count also refers to C.count for any c such that isinstance(c, C) holds, unless overridden by c itself or by some class on the base-class search path from c.__class__ back to C.

Caution: within a method of C, an assignment like self.count = 42 creates a new and unrelated instance vrbl named "count" in self's own dict. Rebinding of a class-static data name must always specify the class whether inside a method or not:

C.count = 314

Static methods are possible when you're using new-style classes:

class C:
    def static(arg1, arg2, arg3):
        # No 'self' parameter!
        ...
    static = staticmethod(static)

However, a far more straightforward way to get the effect of a static method is via a simple module-level function:

def getcount():
    return C.count

If your code is structured so as to define one class (or tightly related class hierarchy) per module, this supplies the desired encapsulation.

6.9   How can I overload constructors (or methods) in Python?

This answer actually applies to all methods, but the question usually comes up first in the context of constructors.

In C++ you'd write

class C {
    C() { cout << "No arguments\n"; }
    C(int i) { cout << "Argument is " << i << "\n"; }
}

in Python you have to write a single constructor that catches all cases using default arguments. For example:

class C:
    def __init__(self, i=None):
        if i is None:
            print "No arguments"
        else:
            print "Argument is", i

This is not entirely equivalent, but close enough in practice.

You could also try a variable-length argument list, e.g.

def __init__(self, *args):
    ....

The same approach works for all method definitions.

6.10   I try to use __spam and I get an error about _SomeClassName__spam.

Variables with double leading underscore are "mangled" to provide a simple but effective way to define class private variables. Any identifier of the form __spam (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__spam, where classname is the current class name with any leading underscores stripped.

This doesn't guarantee privacy: an outside user can still deliberately access the "_classname__spam" attribute, and private values are visible in the object's __dict__. Many Python programmers never bother to use private variable names at all.

6.11   My class defines __del__ but it is not called when I delete the object.

There are several possible reasons for this.

The del statement does not necessarily call __del__ -- it simply decrements the object's reference count, and if this reaches zero __del__ is called.

If your data structures contain circular links (e.g. a tree where each child has a parent reference and each parent has a list of children) the reference counts will never go back to zero. Once in a while Python runs an algorithm to detect such cycles, but the garbage collector might run some time after the last reference to your data structure vanishes, so your __del__ method may be called at an inconvenient and random time. This is inconvenient if you're trying to reproduce a problem. Worse, the order in which object's __del__ methods are executed is arbitrary. You can run gc.collect() to force a collection, but there are pathological cases where objects will never be collected.

Despite the cycle collector, it's still a good idea to define an explicit close() method on objects to be called whenever you're done with them. The close() method can then remove attributes that refer to subobjecs. Don't call __del__ directly -- __del__ should call close() and close() should make sure that it can be called more than once for the same object.

Another way to avoid cyclical references is to use the "weakref" module, which allows you to point to objects without incrementing their reference count. Tree data structures, for instance, should use weak references for their parent and sibling references (if they need them!).

If the object has ever been a local variable in a function that caught an expression in an except clause, chances are that a reference to the object still exists in that function's stack frame as contained in the stack trace. Normally, calling sys.exc_clear() will take care of this by clearing the last recorded exception.

Finally, if your __del__ method raises an exception, a warning message is printed to sys.stderr.

6.12   How do I get a list of all instances of a given class?

Python does not keep track of all instances of a class (or of a built-in type). You can program the class's constructor to keep track of all instances by keeping a list of weak references to each instance.

7   Modules

7.1   How do I create a .pyc file?

When a module is imported for the first time (or when the source is more recent than the current compiled file) a .pyc file containing the compiled code should be created in the same directory as the .py file.

One reason that a .pyc file may not be created is permissions problems with the directory. This can happen, for example, if you develop as one user but run as another, such as if you are testing with a web server. Creation of a .pyc file is automatic if you're importing a module and Python has the ability (permissions, free space, etc...) to write the compiled module back to the directory.

Running Python on a top level script is not considered an import and no .pyc will be created. For example, if you have a top-level module abc.py that imports another module xyz.py, when you run abc, xyz.pyc will be created since xyz is imported, but no abc.pyc file will be created since abc.py isn't being imported.

If you need to create abc.pyc -- that is, to create a .pyc file for a module that is not imported -- you can, using the py_compile and compileall modules.

The py_compile module can manually compile any module. One way is to use the compile() function in that module interactively:

>>> import py_compile
>>> py_compile.compile('abc.py')

This will write the .pyc to the same location as abc.py (or you can override that with the optional parameter cfile).

You can also automatically compile all files in a directory or directories using the compileall module. You can do it from the shell prompt by running compileall.py and providing the path of a directory containing Python files to compile:

python compileall.py .

7.2   How do I find the current module name?

A module can find out its own module name by looking at the predefined global variable __name__. If this has the value '__main__', the program is running as a script. Many modules that are usually used by importing them also provide a command-line interface or a self-test, and only execute this code after checking __name__:

def main():
    print 'Running test...'
    ...

if __name__ == '__main__':
    main()

7.3   How can I have modules that mutually import each other?

Suppose you have the following modules:

foo.py:

from bar import bar_var
foo_var=1

bar.py:

from foo import foo_var
bar_var=2

The problem is that the interpreter will perform the following steps:

  • main imports foo
  • Empty globals for foo are created
  • foo is compiled and starts executing
  • foo imports bar
  • Empty globals for bar are created
  • bar is compiled and starts executing
  • bar imports foo (which is a no-op since there already is a module named foo)
  • bar.foo_var = foo.foo_var

The last step fails, because Python isn't done with interpreting foo yet and the global symbol dictionary for foo is still empty.

The same thing happens when you use import foo, and then try to access foo.foo_var in global code.

There are (at least) three possible workarounds for this problem.

Guido van Rossum recommends avoiding all uses of from <module> import ..., and placing all code inside functions. Initializations of global variables and class variables should use constants or built-in functions only. This means everything from an imported module is referenced as <module>.<name>.

Jim Roskind suggests performing steps in the following order in each module:

  • exports (globals, functions, and classes that don't need imported base classes)
  • import statements
  • active code (including globals that are initialized from imported values).

van Rossum doesn't like this approach much because the imports appear in a strange place, but it does work.

Matthias Urlichs recommends restructuring your code so that the recursive import is not necessary in the first place.

These solutions are not mutually exclusive.

7.4   __import__('x.y.z') returns <module 'x'>; how do I get z?

Try:

__import__('x.y.z').y.z

For more realistic situations, you may have to do something like

m = __import__(s)
for i in s.split(".")[1:]:
    m = getattr(m, i)

7.5   When I edit an imported module and reimport it, the changes don't show up. Why does this happen?

For reasons of efficiency as well as consistency, Python only reads the module file on the first time a module is imported. If it didn't, in a program consisting of many modules where each one imports the same basic module, the basic module would be parsed and re-parsed many times. To force rereading of a changed module, do this:

import modname
reload(modname)

Warning: this technique is not 100% fool-proof. In particular, modules containing statements like

from modname import some_objects

will continue to work with the old version of the imported objects. If the module contains class definitions, existing class instances will not be updated to use the new class definition. This can result in the following paradoxical behaviour:

>>> import cls
>>> c = cls.C()                # Create an instance of C
>>> reload(cls)
<module 'cls' from 'cls.pyc'>
>>> isinstance(c, cls.C)       # isinstance is false?!?
False

The nature of the problem is made clear if you print out the class objects:

>>> c.__class__
<class cls.C at 0x7352a0>
>>> cls.C
<class cls.C at 0x4198d0>
python-defaults-2.7.12/faq/library.html0000664000000000000000000016223612632016514014734 0ustar Python Library and Extension FAQ

Python Library and Extension FAQ

Date: 2005-12-16
Version: 8684
Web site:http://www.python.org/

Contents

1   General Library Questions

1.1   How do I find a module or application to perform task X?

Check the Library Reference to see if there's a relevant standard library module. (Eventually you'll learn what's in the standard library and will able to skip this step.)

Search the Python Package Index.

Next, check the Vaults of Parnassus, an older index of packages.

Finally, try Google or other Web search engine. Searching for "Python" plus a keyword or two for your topic of interest will usually find something helpful.

1.2   Where is the math.py (socket.py, regex.py, etc.) source file?

If you can't find a source file for a module it may be a builtin or dynamically loaded module implemented in C, C++ or other compiled language. In this case you may not have the source file or it may be something like mathmodule.c, somewhere in a C source directory (not on the Python Path).

There are (at least) three kinds of modules in Python:

  1. modules written in Python (.py);

  2. modules written in C and dynamically loaded (.dll, .pyd, .so, .sl, etc);

  3. modules written in C and linked with the interpreter; to get a list of these, type:

    import sys
    print sys.builtin_module_names
    

1.3   How do I make a Python script executable on Unix?

You need to do two things: the script file's mode must be executable and the first line must begin with #! followed by the path of the Python interpreter.

The first is done by executing chmod +x scriptfile or perhaps chmod 755 scriptfile.

The second can be done in a number of ways. The most straightforward way is to write

#!/usr/local/bin/python

as the very first line of your file, using the pathname for where the Python interpreter is installed on your platform.

If you would like the script to be independent of where the Python interpreter lives, you can use the "env" program. Almost all Unix variants support the following, assuming the python interpreter is in a directory on the user's $PATH:

#! /usr/bin/env python

Don't do this for CGI scripts. The $PATH variable for CGI scripts is often very minimal, so you need to use the actual absolute pathname of the interpreter.

Occasionally, a user's environment is so full that the /usr/bin/env program fails; or there's no env program at all. In that case, you can try the following hack (due to Alex Rezinsky):

#! /bin/sh
""":"
exec python $0 ${1+"$@"}
"""

The minor disadvantage is that this defines the script's __doc__ string. However, you can fix that by adding

__doc__ = """...Whatever..."""

1.4   Is there a curses/termcap package for Python?

For Unix variants: The standard Python source distribution comes with a curses module in the Modules/ subdirectory, though it's not compiled by default (note that this is not available in the Windows distribution -- there is no curses module for Windows).

The curses module supports basic curses features as well as many additional functions from ncurses and SYSV curses such as colour, alternative character set support, pads, and mouse support. This means the module isn't compatible with operating systems that only have BSD curses, but there don't seem to be any currently maintained OSes that fall into this category.

For Windows: use the consolelib module.

1.5   Is there an equivalent to C's onexit() in Python?

The atexit module provides a register function that is similar to C's onexit.

1.6   Why don't my signal handlers work?

The most common problem is that the signal handler is declared with the wrong argument list. It is called as

handler(signum, frame)

so it should be declared with two arguments:

def handler(signum, frame):
    ...

2   Common tasks

2.1   How do I test a Python program or component?

Python comes with two testing frameworks. The doctest module finds examples in the docstrings for a module and runs them, comparing the output with the expected output given in the docstring.

The unittest module is a fancier testing framework modelled on Java and Smalltalk testing frameworks.

For testing, it helps to write the program so that it may be easily tested by using good modular design. Your program should have almost all functionality encapsulated in either functions or class methods -- and this sometimes has the surprising and delightful effect of making the program run faster (because local variable accesses are faster than global accesses). Furthermore the program should avoid depending on mutating global variables, since this makes testing much more difficult to do.

The "global main logic" of your program may be as simple as

if __name__=="__main__":
     main_logic()

at the bottom of the main module of your program.

Once your program is organized as a tractable collection of functions and class behaviours you should write test functions that exercise the behaviours. A test suite can be associated with each module which automates a sequence of tests. This sounds like a lot of work, but since Python is so terse and flexible it's surprisingly easy. You can make coding much more pleasant and fun by writing your test functions in parallel with the "production code", since this makes it easy to find bugs and even design flaws earlier.

"Support modules" that are not intended to be the main module of a program may include a self-test of the module.

if __name__ == "__main__":
   self_test()

Even programs that interact with complex external interfaces may be tested when the external interfaces are unavailable by using "fake" interfaces implemented in Python.

2.2   How do I create documentation from doc strings?

The pydoc module can create HTML from the doc strings in your Python source code. An alternative is pythondoc.

2.3   How do I get a single keypress at a time?

For Unix variants:There are several solutions. It's straightforward to do this using curses, but curses is a fairly large module to learn. Here's a solution without curses:

import termios, fcntl, sys, os
fd = sys.stdin.fileno()

oldterm = termios.tcgetattr(fd)
newattr = termios.tcgetattr(fd)
newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
termios.tcsetattr(fd, termios.TCSANOW, newattr)

oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)

try:
    while 1:
        try:
            c = sys.stdin.read(1)
            print "Got character", `c`
        except IOError: pass
finally:
    termios.tcsetattr(fd, termios.TCSAFLUSH, oldterm)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags)

You need the termios and the fcntl module for any of this to work, and I've only tried it on Linux, though it should work elsewhere. In this code, characters are read and printed one at a time.

termios.tcsetattr() turns off stdin's echoing and disables canonical mode. fcntl.fnctl() is used to obtain stdin's file descriptor flags and modify them for non-blocking mode. Since reading stdin when it is empty results in an IOError, this error is caught and ignored.

3   Threads

3.1   How do I program using threads?

Be sure to use the threading module and not the thread module. The threading module builds convenient abstractions on top of the low-level primitives provided by the thread module.

Aahz has a set of slides from his threading tutorial that are helpful; see http://starship.python.net/crew/aahz/OSCON2001/.

3.2   None of my threads seem to run: why?

As soon as the main thread exits, all threads are killed. Your main thread is running too quickly, giving the threads no time to do any work.

A simple fix is to add a sleep to the end of the program that's long enough for all the threads to finish:

import threading, time

def thread_task(name, n):
    for i in range(n): print name, i

for i in range(10):
    T = threading.Thread(target=thread_task, args=(str(i), i))
    T.start()

time.sleep(10) # <----------------------------!

But now (on many platforms) the threads don't run in parallel, but appear to run sequentially, one at a time! The reason is that the OS thread scheduler doesn't start a new thread until the previous thread is blocked.

A simple fix is to add a tiny sleep to the start of the run function:

def thread_task(name, n):
    time.sleep(0.001) # <---------------------!
    for i in range(n): print name, i

for i in range(10):
    T = threading.Thread(target=thread_task, args=(str(i), i))
    T.start()

time.sleep(10)

Instead of trying to guess how long a time.sleep() delay will be enough, it's better to use some kind of semaphore mechanism. One idea is to use the Queue module to create a queue object, let each thread append a token to the queue when it finishes, and let the main thread read as many tokens from the queue as there are threads.

3.3   How do I parcel out work among a bunch of worker threads?

Use the Queue module to create a queue containing a list of jobs. The Queue class maintains a list of objects with .put(obj) to add an item to the queue and .get() to return an item. The class will take care of the locking necessary to ensure that each job is handed out exactly once.

Here's a trivial example:

import threading, Queue, time

# The worker thread gets jobs off the queue.  When the queue is empty, it
# assumes there will be no more work and exits.
# (Realistically workers will run until terminated.)
def worker ():
    print 'Running worker'
    time.sleep(0.1)
    while True:
        try:
            arg = q.get(block=False)
        except Queue.Empty:
            print 'Worker', threading.currentThread(),
            print 'queue empty'
            break
        else:
            print 'Worker', threading.currentThread(),
            print 'running with argument', arg
            time.sleep(0.5)

# Create queue
q = Queue.Queue()

# Start a pool of 5 workers
for i in range(5):
    t = threading.Thread(target=worker, name='worker %i' % (i+1))
    t.start()

# Begin adding work to the queue
for i in range(50):
    q.put(i)

# Give threads time to run
print 'Main thread sleeping'
time.sleep(5)

When run, this will produce the following output:

Running worker Running worker Running worker Running worker Running worker Main thread sleeping Worker <Thread(worker 1, started)> running with argument 0 Worker <Thread(worker 2, started)> running with argument 1 Worker <Thread(worker 3, started)> running with argument 2 Worker <Thread(worker 4, started)> running with argument 3 Worker <Thread(worker 5, started)> running with argument 4 Worker <Thread(worker 1, started)> running with argument 5 ...

Consult the module's documentation for more details; the Queue class provides a featureful interface.

3.4   What kinds of global value mutation are thread-safe?

A global interpreter lock (GIL) is used internally to ensure that only one thread runs in the Python VM at a time. In general, Python offers to switch among threads only between bytecode instructions; how frequently it switches can be set via sys.setcheckinterval(). Each bytecode instruction and therefore all the C implementation code reached from each instruction is therefore atomic from the point of view of a Python program.

In theory, this means an exact accounting requires an exact understanding of the PVM bytecode implementation. In practice, it means that operations on shared variables of builtin data types (ints, lists, dicts, etc) that "look atomic" really are.

For example, the following operations are all atomic (L, L1, L2 are lists, D, D1, D2 are dicts, x, y are objects, i, j are ints):

L.append(x)
L1.extend(L2)
x = L[i]
x = L.pop()
L1[i:j] = L2
L.sort()
x = y
x.field = y
D[x] = y
D1.update(D2)
D.keys()

These aren't:

i = i+1
L.append(L[-1])
L[i] = L[j]
D[x] = D[x] + 1

Operations that replace other objects may invoke those other objects' __del__ method when their reference count reaches zero, and that can affect things. This is especially true for the mass updates to dictionaries and lists. When in doubt, use a mutex!

3.5   Can't we get rid of the Global Interpreter Lock?

The Global Interpreter Lock (GIL) is often seen as a hindrance to Python's deployment on high-end multiprocessor server machines, because a multi-threaded Python program effectively only uses one CPU, due to the insistence that (almost) all Python code can only run while the GIL is held.

Back in the days of Python 1.5, Greg Stein actually implemented a comprehensive patch set (the "free threading" patches) that removed the GIL and replaced it with fine-grained locking. Unfortunately, even on Windows (where locks are very efficient) this ran ordinary Python code about twice as slow as the interpreter using the GIL. On Linux the performance loss was even worse because pthread locks aren't as efficient.

Since then, the idea of getting rid of the GIL has occasionally come up but nobody has found a way to deal with the expected slowdown, and users who don't use threads would not be happy if their code ran at half at the speed. Greg's free threading patch set has not been kept up-to-date for later Python versions.

This doesn't mean that you can't make good use of Python on multi-CPU machines! You just have to be creative with dividing the work up between multiple processes rather than multiple threads. Judicious use of C extensions will also help; if you use a C extension to perform a time-consuming task, the extension can release the GIL while the thread of execution is in the C code and allow other threads to get some work done.

It has been suggested that the GIL should be a per-interpreter-state lock rather than truly global; interpreters then wouldn't be able to share objects. Unfortunately, this isn't likely to happen either. It would be a tremendous amount of work, because many object implementations currently have global state. For example, small integers and short strings are cached; these caches would have to be moved to the interpreter state. Other object types have their own free list; these free lists would have to be moved to the interpreter state. And so on.

And I doubt that it can even be done in finite time, because the same problem exists for 3rd party extensions. It is likely that 3rd party extensions are being written at a faster rate than you can convert them to store all their global state in the interpreter state.

And finally, once you have multiple interpreters not sharing any state, what have you gained over running each interpreter in a separate process?

4   Input and Output

4.1   How do I delete a file? (And other file questions...)

Use os.remove(filename) or os.unlink(filename); for documentation, see the POSIX module. The two functions are identical; unlink() is simply the name of the Unix system call for this function.

To remove a directory, use os.rmdir(); use os.mkdir() to create one. os.makedirs(path) will create any intermediate directories in path that don't exist. os.removedirs(path) will remove intermediate directories as long as they're empty; if you want to delete an entire directory tree and its contents, use shutil.rmtree().

To rename a file, use os.rename(old_path, new_path).

To truncate a file, open it using f = open(filename, "r+"), and use f.truncate(offset); offset defaults to the current seek position. There's also `os.ftruncate(fd, offset) for files opened with os.open(), where fd is the file descriptor (a small integer).

The shutil module also contains a number of functions to work on files including copyfile, copytree, and rmtree.

4.2   How do I copy a file?

The shutil module contains a copyfile() function. Note that on MacOS 9 it doesn't copy the resource fork and Finder info.

4.3   How do I read (or write) binary data?

or complex data formats, it's best to use the struct module. It allows you to take a string containing binary data (usually numbers) and convert it to Python objects; and vice versa.

For example, the following code reads two 2-byte integers and one 4-byte integer in big-endian format from a file:

import struct

f = open(filename, "rb")  # Open in binary mode for portability
s = f.read(8)
x, y, z = struct.unpack(">hhl", s)

The '>' in the format string forces big-endian data; the letter 'h' reads one "short integer" (2 bytes), and 'l' reads one "long integer" (4 bytes) from the string.

For data that is more regular (e.g. a homogeneous list of ints or thefloats), you can also use the array module.

4.4   I can't seem to use os.read() on a pipe created with os.popen(); why?

os.read() is a low-level function which takes a file descriptor, a small integer representing the opened file. os.popen() creates a high-level file object, the same type returned by the builtin open() function. Thus, to read n bytes from a pipe p created with os.popen(), you need to use p.read(n).

4.5   How do I run a subprocess with pipes connected to both input and output?

Use the popen2 module. For example:

import popen2
fromchild, tochild = popen2.popen2("command")
tochild.write("input\n")
tochild.flush()
output = fromchild.readline()

Warning: in general it is unwise to do this because you can easily cause a deadlock where your process is blocked waiting for output from the child while the child is blocked waiting for input from you. This can be caused because the parent expects the child to output more text than it does, or it can be caused by data being stuck in stdio buffers due to lack of flushing. The Python parent can of course explicitly flush the data it sends to the child before it reads any output, but if the child is a naive C program it may have been written to never explicitly flush its output, even if it is interactive, since flushing is normally automatic.

Note that a deadlock is also possible if you use popen3 to read stdout and stderr. If one of the two is too large for the internal buffer (increasing the buffer size does not help) and you read() the other one first, there is a deadlock, too.

Note on a bug in popen2: unless your program calls wait() or waitpid(), finished child processes are never removed, and eventually calls to popen2 will fail because of a limit on the number of child processes. Calling os.waitpid with the os.WNOHANG option can prevent this; a good place to insert such a call would be before calling popen2 again.

In many cases, all you really need is to run some data through a command and get the result back. Unless the amount of data is very large, the easiest way to do this is to write it to a temporary file and run the command with that temporary file as input. The standard module tempfile exports a mktemp() function to generate unique temporary file names.

import tempfile
import os
class Popen3:
   """
   This is a deadlock-safe version of popen that returns
   an object with errorlevel, out (a string) and err (a string).
   (capturestderr may not work under windows.)
   Example: print Popen3('grep spam','\n\nhere spam\n\n').out
   """
   def __init__(self,command,input=None,capturestderr=None):
       outfile=tempfile.mktemp()
       command="( %s ) > %s" % (command,outfile)
       if input:
           infile=tempfile.mktemp()
           open(infile,"w").write(input)
           command=command+" <"+infile
       if capturestderr:
           errfile=tempfile.mktemp()
           command=command+" 2>"+errfile
       self.errorlevel=os.system(command) >> 8
       self.out=open(outfile,"r").read()
       os.remove(outfile)
       if input:
           os.remove(infile)
       if capturestderr:
           self.err=open(errfile,"r").read()
           os.remove(errfile)

Note that many interactive programs (e.g. vi) don't work well with pipes substituted for standard input and output. You will have to use pseudo ttys ("ptys") instead of pipes. Or you can use a Python interface to Don Libes' "expect" library. A Python extension that interfaces to expect is called "expy" and available from http://expectpy.sourceforge.net. A pure Python solution that works like expect is ` pexpect <http://pexpect.sourceforge.net>`_.

4.6   How do I access the serial (RS232) port?

For Win32, POSIX (Linux, BSD, etc.), Jython:

http://pyserial.sourceforge.net

For Unix, see a Usenet post by Mitch Chapman:

http://groups.google.com/groups?selm=34A04430.CF9@ohioee.com

4.7   Why doesn't closing sys.stdout (stdin, stderr) really close it?

Python file objects are a high-level layer of abstraction on top of C streams, which in turn are a medium-level layer of abstraction on top of (among other things) low-level C file descriptors.

For most file objects you create in Python via the builtin file constructor, f.close() marks the Python file object as being closed from Python's point of view, and also arranges to close the underlying C stream. This also happens automatically in f's destructor, when f becomes garbage.

But stdin, stdout and stderr are treated specially by Python, because of the special status also given to them by C. Running sys.stdout.close() marks the Python-level file object as being closed, but does not close the associated C stream.

To close the underlying C stream for one of these three, you should first be sure that's what you really want to do (e.g., you may confuse extension modules trying to do I/O). If it is, use os.close:

os.close(0)   # close C's stdin stream
os.close(1)   # close C's stdout stream
os.close(2)   # close C's stderr stream

5   Network/Internet Programming

5.1   What WWW tools are there for Python?

See the chapters titled "Internet Protocols and Support" and "Internet Data Handling" in the Library Reference Manual. Python has many modules that will help you build server-side and client-side web systems.

A summary of available frameworks is maintained by Paul Boddie at http://www.python.org/cgi-bin/moinmoin/WebProgramming .

Cameron Laird maintains a useful set of pages about Python web technologies at http://phaseit.net/claird/comp.lang.python/web_python.html.

The Web Programming topic guide also points to many useful resources.

5.2   How can I mimic CGI form submission (METHOD=POST)?

I would like to retrieve web pages that are the result of POSTing a form. Is there existing code that would let me do this easily?

Yes. Here's a simple example that uses httplib:

#!/usr/local/bin/python

import httplib, sys, time

### build the query string
qs = "First=Josephine&MI=Q&Last=Public"

### connect and send the server a path
httpobj = httplib.HTTP('www.some-server.out-there', 80)
httpobj.putrequest('POST', '/cgi-bin/some-cgi-script')
### now generate the rest of the HTTP headers...
httpobj.putheader('Accept', '*/*')
httpobj.putheader('Connection', 'Keep-Alive')
httpobj.putheader('Content-type', 'application/x-www-form-urlencoded')
httpobj.putheader('Content-length', '%d' % len(qs))
httpobj.endheaders()
httpobj.send(qs)
### find out what the server said in response...
reply, msg, hdrs = httpobj.getreply()
if reply != 200:
    sys.stdout.write(httpobj.getfile().read())

Note that in general for URL-encoded POST operations, query strings must be quoted by using urllib.quote(). For example to send name="Guy Steele, Jr.":

>>> from urllib import quote
>>> x = quote("Guy Steele, Jr.")
>>> x
'Guy%20Steele,%20Jr.'
>>> query_string = "name="+x
>>> query_string
'name=Guy%20Steele,%20Jr.'

5.3   What module should I use to help with generating HTML?

There are many different modules available:

  • HTMLgen is a class library of objects corresponding to all the HTML 3.2 markup tags. It's used when you are writing in Python and wish to synthesize HTML pages for generating a web or for CGI forms, etc.
  • DocumentTemplate and Zope Page Templates are two different systems that are part of Zope.
  • Quixote's PTL uses Python syntax to assemble strings of text.

Consult the Web Programming topic guide for more links.

5.4   How do I send mail from a Python script?

Use the standard library module smtplib.

Here's a very simple interactive mail sender that uses it. This method will work on any host that supports an SMTP listener.

import sys, smtplib

fromaddr = raw_input("From: ")
toaddrs  = raw_input("To: ").split(',')
print "Enter message, end with ^D:"
msg = ''
while 1:
    line = sys.stdin.readline()
    if not line:
        break
    msg = msg + line

# The actual mail send
server = smtplib.SMTP('localhost')
server.sendmail(fromaddr, toaddrs, msg)
server.quit()

A Unix-only alternative uses sendmail. The location of the sendmail program varies between systems; sometimes it is /usr/lib/sendmail, sometime /usr/sbin/sendmail. The sendmail manual page will help you out. Here's some sample code:

SENDMAIL = "/usr/sbin/sendmail" # sendmail location
import os
p = os.popen("%s -t -i" % SENDMAIL, "w")
p.write("To: receiver@example.com\n")
p.write("Subject: test\n")
p.write("\n") # blank line separating headers from body
p.write("Some text\n")
p.write("some more text\n")
sts = p.close()
if sts != 0:
    print "Sendmail exit status", sts

5.5   How do I avoid blocking in the connect() method of a socket?

The select module is commonly used to help with asynchronous I/O on sockets.

To prevent the TCP connect from blocking, you can set the socket to non-blocking mode. Then when you do the connect(), you will either connect immediately (unlikely) or get an exception that contains the error number as .errno. errno.EINPROGRESS indicates that the connection is in progress, but hasn't finished yet. Different OSes will return different values, so you're going to have to check what's returned on your system.

You can use the connect_ex() method to avoid creating an exception. It will just return the errno value. To poll, you can call connect_ex() again later -- 0 or errno.EISCONN indicate that you're connected -- or you can pass this socket to select to check if it's writeable.

6   Databases

6.1   Are there any interfaces to database packages in Python?

Yes.

Python 2.3 includes the bsddb package which provides an interface to the BerkeleyDB library. Interfaces to disk-based hashes such as DBM and GDBM are also included with standard Python.

Support for most relational databases is available. See the Database Topic Guide for details.

6.2   How do you implement persistent objects in Python?

The pickle library module solves this in a very general way (though you still can't store things like open files, sockets or windows), and the shelve library module uses pickle and (g)dbm to create persistent mappings containing arbitrary Python objects. For better performance, you can use the cPickle module.

A more awkward way of doing things is to use pickle's little sister, marshal. The marshal module provides very fast ways to store noncircular basic Python types to files and strings, and back again. Although marshal does not do fancy things like store instances or handle shared references properly, it does run extremely fast. For example loading a half megabyte of data may take less than a third of a second. This often beats doing something more complex and general such as using gdbm with pickle/shelve.

6.3   Why is cPickle so slow?

The default format used by the pickle module is a slow one that results in readable pickles. Making it the default, but it would break backward compatibility:

largeString = 'z' * (100 * 1024)
myPickle = cPickle.dumps(largeString, protocol=1)

6.4   If my program crashes with a bsddb (or anydbm) database open, it gets corrupted. How come?

Databases opened for write access with the bsddb module (and often by the anydbm module, since it will preferentially use bsddb) must explicitly be closed using the .close() method of the database. The underlying library caches database contents which need to be converted to on-disk form and written.

If you have initialized a new bsddb database but not written anything to it before the program crashes, you will often wind up with a zero-length file and encounter an exception the next time the file is opened.

6.5   I tried to open Berkeley DB file, but bsddb produces bsddb.error: (22, 'Invalid argument'). Help! How can I restore my data?

Don't panic! Your data is probably intact. The most frequent cause for the error is that you tried to open an earlier Berkeley DB file with a later version of the Berkeley DB library.

Many Linux systems now have all three versions of Berkeley DB available. If you are migrating from version 1 to a newer version use db_dump185 to dump a plain text version of the database. If you are migrating from version 2 to version 3 use db2_dump to create a plain text version of the database. In either case, use db_load to create a new native database for the latest version installed on your computer. If you have version 3 of Berkeley DB installed, you should be able to use db2_load to create a native version 2 database.

You should move away from Berkeley DB version 1 files because the hash file code contains known bugs that can corrupt your data.

7   Mathematics and Numerics

7.1   How do I generate random numbers in Python?

The standard module random implements a random number generator. Usage is simple:

import random
random.random()

This returns a random floating point number in the range [0, 1).

There are also many other specialized generators in this module, such as:

  • randrange(a, b) chooses an integer in the range [a, b).
  • uniform(a, b) chooses a floating point number in the range [a, b).
  • normalvariate(mean, sdev) samples the normal (Gaussian) distribution.

Some higher-level functions operate on sequences directly, such as:

  • choice(S) chooses random element from a given sequence
  • shuffle(L) shuffles a list in-place, i.e. permutes it randomly

There's also a Random class you can instantiate to create independent multiple random number generators.

python-defaults-2.7.12/faq/FAQ.html0000664000000000000000000002026412632016513013670 0ustar Python Frequently Asked Question Lists

Python Frequently Asked Question Lists

This is a local copy of the online FAQ located at http://python.org/doc/faq. The copy was fetched and generated in May 2007.

python-defaults-2.7.12/faq/extending.html0000664000000000000000000010405512632016513015247 0ustar Extending/Embedding FAQ

Extending/Embedding FAQ

Date: 2004-04-08
Version: 7294
Web site:http://www.python.org/

1   Can I create my own functions in C?

Yes, you can create built-in modules containing functions, variables, exceptions and even new types in C. This is explained in the document "Extending and Embedding the Python Interpreter" (http://docs.python.org/ext/ext.html).

Most intermediate or advanced Python books will also cover this topic.

2   Can I create my own functions in C++?

Yes, using the C compatibility features found in C++. Place extern "C" { ... } around the Python include files and put extern "C" before each function that is going to be called by the Python interpreter. Global or static C++ objects with constructors are probably not a good idea.

3   Writing C is hard; are there any alternatives?

There are a number of alternatives to writing your own C extensions, depending on what you're trying to do.

If you need more speed, Psyco generates x86 assembly code from Python bytecode. You can use Psyco to compile the most time-critical functions in your code, and gain a significant improvement with very little effort, as long as you're running on a machine with an x86-compatible processor.

Pyrex is a compiler that accepts a slightly modified form of Python and generates the corresponding C code. Pyrex makes it possible to write an extension without having to learn Python's C API.

If you need to interface to some C library for which no Python extension currently exists, you can try wrapping the library's data types and functions with a tool such as SWIG. For C++ libraries, you can look at SIP, CXX, Boost, or Weave.

4   How can I execute arbitrary Python statements from C?

The highest-level function to do this is PyRun_SimpleString() which takes a single string argument to be executed in the context of the module __main__ and returns 0 for success and -1 when an exception occurred (including SyntaxError). If you want more control, use PyRun_String(); see the source for PyRun_SimpleString() in Python/pythonrun.c.

5   How can I evaluate an arbitrary Python expression from C?

Call the function PyRun_String() from the previous question with the start symbol Py_eval_input; it parses an expression, evaluates it and returns its value.

6   How do I extract C values from a Python object?

That depends on the object's type. If it's a tuple, PyTupleSize(o) returns its length and PyTuple_GetItem(o, i) returns its i'th item. Lists have similar functions, PyListSize(o) and PyList_GetItem(o, i).

For strings, PyString_Size(o) returns its length and PyString_AsString(o) a pointer to its value. Note that Python strings may contain null bytes so C's strlen() should not be used.

To test the type of an object, first make sure it isn't NULL, and then use PyString_Check(o), PyTuple_Check(o), PyList_Check(o), etc.

There is also a high-level API to Python objects which is provided by the so-called 'abstract' interface -- read Include/abstract.h for further details. It allows interfacing with any kind of Python sequence using calls like PySequence_Length(), PySequence_GetItem(), etc.) as well as many other useful protocols.

7   How do I use Py_BuildValue() to create a tuple of arbitrary length?

You can't. Use t = PyTuple_New(n) instead, and fill it with objects using PyTuple_SetItem(t, i, o) -- note that this "eats" a reference count of o, so you have to Py_INCREF it. Lists have similar functions PyList_New(n) and PyList_SetItem(l, i, o). Note that you must set all the tuple items to some value before you pass the tuple to Python code -- PyTuple_New(n) initializes them to NULL, which isn't a valid Python value.

8   How do I call an object's method from C?

The PyObject_CallMethod() function can be used to call an arbitrary method of an object. The parameters are the object, the name of the method to call, a format string like that used with Py_BuildValue(), and the argument values:

PyObject *
PyObject_CallMethod(PyObject *object, char *method_name,
                    char *arg_format, ...);

This works for any object that has methods -- whether built-in or user-defined. You are responsible for eventually Py_DECREF'ing the return value.

To call, e.g., a file object's "seek" method with arguments 10, 0 (assuming the file object pointer is "f"):

res = PyObject_CallMethod(f, "seek", "(ii)", 10, 0);
if (res == NULL) {
        ... an exception occurred ...
}
else {
        Py_DECREF(res);
}

Note that since PyObject_CallObject() always wants a tuple for the argument list, to call a function without arguments, pass "()" for the format, and to call a function with one argument, surround the argument in parentheses, e.g. "(i)".

9   How do I catch the output from PyErr_Print() (or anything that prints to stdout/stderr)?

In Python code, define an object that supports the write() method. Assign this object to sys.stdout and sys.stderr. Call print_error, or just allow the standard traceback mechanism to work. Then, the output will go wherever your write() method sends it.

The easiest way to do this is to use the StringIO class in the standard library.

Sample code and use for catching stdout:

>>> class StdoutCatcher:
...     def __init__(self):
...         self.data = ''
...     def write(self, stuff):
...         self.data = self.data + stuff
...
>>> import sys
>>> sys.stdout = StdoutCatcher()
>>> print 'foo'
>>> print 'hello world!'
>>> sys.stderr.write(sys.stdout.data)
foo
hello world!

10   How do I access a module written in Python from C?

You can get a pointer to the module object as follows:

module = PyImport_ImportModule("<modulename>");

If the module hasn't been imported yet (i.e. it is not yet present in sys.modules), this initializes the module; otherwise it simply returns the value of sys.modules["<modulename>"]. Note that it doesn't enter the module into any namespace -- it only ensures it has been initialized and is stored in sys.modules.

You can then access the module's attributes (i.e. any name defined in the module) as follows:

attr = PyObject_GetAttrString(module, "<attrname>");

Calling PyObject_SetAttrString() to assign to variables in the module also works.

11   How do I interface to C++ objects from Python?

Depending on your requirements, there are many approaches. To do this manually, begin by reading the "Extending and Embedding" document. Realize that for the Python run-time system, there isn't a whole lot of difference between C and C++ -- so the strategy of building a new Python type around a C structure (pointer) type will also work for C++ objects.

For C++ libraries, you can look at SIP, CXX, Boost, or Weave. SWIG is a similar automated tool that only supports C libraries.

12   I added a module using the Setup file and the make fails; why?

Setup must end in a newline, if there is no newline there, the build process fails. (Fixing this requires some ugly shell script hackery, and this bug is so minor that it doesn't seem worth the effort.)

13   How do I debug an extension?

When using GDB with dynamically loaded extensions, you can't set a breakpoint in your extension until your extension is loaded.

In your .gdbinit file (or interactively), add the command:

br _PyImport_LoadDynamicModule

Then, when you run GDB:

$ gdb /local/bin/python
gdb) run myscript.py
gdb) continue # repeat until your extension is loaded
gdb) finish   # so that your extension is loaded
gdb) br myfunction.c:50
gdb) continue

14   I want to compile a Python module on my Linux system, but some files are missing. Why?

Most packaged versions of Python don't include the /usr/lib/python2.x/config/ directory, which contains various files required for compiling Python extensions.

For Red Hat, install the python-devel RPM to get the necessary files.

For Debian, run apt-get install python-dev.

15   What does "SystemError: _PyImport_FixupExtension: module yourmodule not loaded" mean?

This means that you have created an extension module named "yourmodule", but your module init function does not initialize with that name.

Every module init function will have a line similar to:

module = Py_InitModule("yourmodule", yourmodule_functions);

If the string passed to this function is not the same name as your extenion module, the SystemError exception will be raised.

16   How do I tell "incomplete input" from "invalid input"?

Sometimes you want to emulate the Python interactive interpreter's behavior, where it gives you a continuation prompt when the input is incomplete (e.g. you typed the start of an "if" statement or you didn't close your parentheses or triple string quotes), but it gives you a syntax error message immediately when the input is invalid.

In Python you can use the codeop module, which approximates the parser's behavior sufficiently. IDLE uses this, for example.

The easiest way to do it in C is to call PyRun_InteractiveLoop() (perhaps in a separate thread) and let the Python interpreter handle the input for you. You can also set the PyOS_ReadlineFunctionPointer to point at your custom input function. See Modules/readline.c and Parser/myreadline.c for more hints.

However sometimes you have to run the embedded Python interpreter in the same thread as your rest application and you can't allow the PyRun_InteractiveLoop() to stop while waiting for user input. The one solution then is to call PyParser_ParseString() and test for e.error equal to E_EOF, which means the input is incomplete). Here's a sample code fragment, untested, inspired by code from Alex Farber:

#include <Python.h>
#include <node.h>
#include <errcode.h>
#include <grammar.h>
#include <parsetok.h>
#include <compile.h>

int testcomplete(char *code)
  /* code should end in \n */
  /* return -1 for error, 0 for incomplete, 1 for complete */
{
  node *n;
  perrdetail e;

  n = PyParser_ParseString(code, &_PyParser_Grammar,
                           Py_file_input, &e);
  if (n == NULL) {
    if (e.error == E_EOF)
      return 0;
    return -1;
  }

  PyNode_Free(n);
  return 1;
}

Another solution is trying to compile the received string with Py_CompileString(). If it compiles without errors, try to execute the returned code object by calling PyEval_EvalCode(). Otherwise save the input for later. If the compilation fails, find out if it's an error or just more input is required - by extracting the message string from the exception tuple and comparing it to the string "unexpected EOF while parsing". Here is a complete example using the GNU readline library (you may want to ignore SIGINT while calling readline()):

#include <stdio.h>
#include <readline.h>

#include <Python.h>
#include <object.h>
#include <compile.h>
#include <eval.h>

int main (int argc, char* argv[])
{
  int i, j, done = 0;                          /* lengths of line, code */
  char ps1[] = ">>> ";
  char ps2[] = "... ";
  char *prompt = ps1;
  char *msg, *line, *code = NULL;
  PyObject *src, *glb, *loc;
  PyObject *exc, *val, *trb, *obj, *dum;

  Py_Initialize ();
  loc = PyDict_New ();
  glb = PyDict_New ();
  PyDict_SetItemString (glb, "__builtins__", PyEval_GetBuiltins ());

  while (!done)
  {
    line = readline (prompt);

    if (NULL == line)                          /* CTRL-D pressed */
    {
      done = 1;
    }
    else
    {
      i = strlen (line);

      if (i > 0)
        add_history (line);                    /* save non-empty lines */

      if (NULL == code)                        /* nothing in code yet */
        j = 0;
      else
        j = strlen (code);

      code = realloc (code, i + j + 2);
      if (NULL == code)                        /* out of memory */
        exit (1);

      if (0 == j)                              /* code was empty, so */
        code[0] = '\0';                        /* keep strncat happy */

      strncat (code, line, i);                 /* append line to code */
      code[i + j] = '\n';                      /* append '\n' to code */
      code[i + j + 1] = '\0';

      src = Py_CompileString (code, "<stdin>", Py_single_input);

      if (NULL != src)                         /* compiled just fine - */
      {
        if (ps1  == prompt ||                  /* ">>> " or */
            '\n' == code[i + j - 1])           /* "... " and double '\n' */
        {                                               /* so execute it */
          dum = PyEval_EvalCode ((PyCodeObject *)src, glb, loc);
          Py_XDECREF (dum);
          Py_XDECREF (src);
          free (code);
          code = NULL;
          if (PyErr_Occurred ())
            PyErr_Print ();
          prompt = ps1;
        }
      }                                        /* syntax error or E_EOF? */
      else if (PyErr_ExceptionMatches (PyExc_SyntaxError))
      {
        PyErr_Fetch (&exc, &val, &trb);        /* clears exception! */

        if (PyArg_ParseTuple (val, "sO", &msg, &obj) &&
            !strcmp (msg, "unexpected EOF while parsing")) /* E_EOF */
        {
          Py_XDECREF (exc);
          Py_XDECREF (val);
          Py_XDECREF (trb);
          prompt = ps2;
        }
        else                                   /* some other syntax error */
        {
          PyErr_Restore (exc, val, trb);
          PyErr_Print ();
          free (code);
          code = NULL;
          prompt = ps1;
        }
      }
      else                                     /* some non-syntax error */
      {
        PyErr_Print ();
        free (code);
        code = NULL;
        prompt = ps1;
      }

      free (line);
    }
  }

  Py_XDECREF(glb);
  Py_XDECREF(loc);
  Py_Finalize();
  exit(0);
}

17   How do I find undefined g++ symbols __builtin_new or __pure_virtual?

To dynamically load g++ extension modules, you must recompile Python, relink it using g++ (change LINKCC in the python Modules Makefile), and link your extension module using g++ (e.g., "g++ -shared -o mymodule.so mymodule.o").

18   Can I create an object class with some methods implemented in C and others in Python (e.g. through inheritance)?

In Python 2.2, you can inherit from builtin classes such as int, list, dict, etc.

The Boost Python Library (BPL, http://www.boost.org/libs/python/doc/index.html) provides a way of doing this from C++ (i.e. you can inherit from an extension class written in C++ using the BPL).

19   When importing module X, why do I get "undefined symbol: PyUnicodeUCS2*"?

You are using a version of Python that uses a 4-byte representation for Unicode characters, but some C extension module you are importing was compiled using a Python that uses a 2-byte representation for Unicode characters (the default).

If instead the name of the undefined symbol starts with PyUnicodeUCS4, the problem is the reverse: Python was built using 2-byte Unicode characters, and the extension module was compiled using a Python with 4-byte Unicode characters.

This can easily occur when using pre-built extension packages. RedHat Linux 7.x, in particular, provided a "python2" binary that is compiled with 4-byte Unicode. This only causes the link failure if the extension uses any of the PyUnicode_*() functions. It is also a problem if an extension uses any of the Unicode-related format specifiers for Py_BuildValue (or similar) or parameter specifications for PyArg_ParseTuple().

You can check the size of the Unicode character a Python interpreter is using by checking the value of sys.maxunicode:

>>> import sys
>>> if sys.maxunicode > 65535:
...     print 'UCS4 build'
... else:
...     print 'UCS2 build'

The only way to solve this problem is to use extension modules compiled with a Python binary built using the same size for Unicode characters.

python-defaults-2.7.12/faq/installed.html0000664000000000000000000002352312632016513015241 0ustar "Why is Python Installed on my Computer?" FAQ

"Why is Python Installed on my Computer?" FAQ

What is Python?

Python is a programming language. It's used for many different applications. It's used in some high schools and colleges as an introductory programming language because Python is easy to learn, but it's also used by professional software developers at places such as Google, NASA, and Industrial Light & Magic.

If you're curious about finding out more about Python, start with the Beginner's Guide to Python.

Why is Python installed on my machine?

If you find Python installed on your system but don't remember installing it, there are several possible ways it could have gotten there.

  • Perhaps another user on the computer wanted to learn programming and installed it; you'll have to figure out who's been using the machine and might have installed it.
  • A third-party application installed on the machine might have been written in Python and included a Python installation. For a home computer, the most common such application is PySol, a solitaire game that includes over 200 different games and variations.
  • Some Windows machines also have Python installed. At this writing we're aware of computers from Hewlett-Packard and Compaq that include Python. Apparently some of HP/Compaq's administrative tools are written in Python.
  • All Apple computers running Mac OS X have Python installed; it's included in the base installation.

Can I delete Python?

That depends on where Python came from.

If someone installed it deliberately, you can remove it without hurting anything. On Windows, use the Add/Remove Programs icon in the Control Panel.

If Python was installed by a third-party application, you can also remove it, but that application will no longer work. You should probably use that application's uninstaller rather than removing Python directly.

If Python came with your operating system, removing it is not recommended. If you remove it, whatever tools were written in Python will no longer run, and some of them might be important to you. Reinstalling the whole system would then be required to fix things again.

python-defaults-2.7.12/faq/FAQ.ht0000664000000000000000000000122512057417145013342 0ustar Title: Python Frequently Asked Question Lists Content-type: text/x-rst ========================================== Python Frequently Asked Question Lists ========================================== * `General Python FAQ `_ * `Programming FAQ `_ * `Library and Extension FAQ `_ * `Extending/Embedding FAQ `_ * `Windows FAQ `_ * `GUI Programming FAQ `_ * `"Why is Python Installed on my Computer?" FAQ `_ This is a local copy of the online FAQ located at http://python.org/doc/faq. The copy was fetched and generated in May 2007. python-defaults-2.7.12/faq/installed.ht0000664000000000000000000000473312057417145014721 0ustar Title: "Why is Python Installed on my Computer?" FAQ Content-type: text/x-rst ===================================================== "Why is Python Installed on my Computer?" FAQ ===================================================== What is Python? ---------------------- Python is a programming language. It's used for many different applications. It's used in some high schools and colleges as an introductory programming language because Python is easy to learn, but it's also used by professional software developers at places such as Google, NASA, and Industrial Light & Magic. If you're curious about finding out more about Python, start with the `Beginner's Guide to Python `_. Why is Python installed on my machine? -------------------------------------------------- If you find Python installed on your system but don't remember installing it, there are several possible ways it could have gotten there. * Perhaps another user on the computer wanted to learn programming and installed it; you'll have to figure out who's been using the machine and might have installed it. * A third-party application installed on the machine might have been written in Python and included a Python installation. For a home computer, the most common such application is `PySol `_, a solitaire game that includes over 200 different games and variations. * Some Windows machines also have Python installed. At this writing we're aware of computers from Hewlett-Packard and Compaq that include Python. Apparently some of HP/Compaq's administrative tools are written in Python. * All Apple computers running Mac OS X have Python installed; it's included in the base installation. Can I delete Python? ---------------------------- That depends on where Python came from. If someone installed it deliberately, you can remove it without hurting anything. On Windows, use the Add/Remove Programs icon in the Control Panel. If Python was installed by a third-party application, you can also remove it, but that application will no longer work. You should probably use that application's uninstaller rather than removing Python directly. If Python came with your operating system, removing it is not recommended. If you remove it, whatever tools were written in Python will no longer run, and some of them might be important to you. Reinstalling the whole system would then be required to fix things again. python-defaults-2.7.12/faq/windows.html0000664000000000000000000012122712632016514014755 0ustar Python Windows FAQ

Python Windows FAQ

Date: 2005-07-26
Version: 8295
Web site:http://www.python.org/

1   How do I run a Python program under Windows?

This is not necessarily a straightforward question. If you are already familiar with running programs from the Windows command line then everything will seem obvious; otherwise, you might need a little more guidance. There are also differences between Windows 95, 98, NT, ME, 2000 and XP which can add to the confusion.

Unless you use some sort of integrated development environment, you will end up typing Windows commands into what is variously referred to as a "DOS window" or "Command prompt window". Usually you can create such a window from your Start menu; under Windows 2000 the menu selection is "Start | Programs | Accessories | Command Prompt". You should be able to recognize when you have started such a window because you will see a Windows "command prompt", which usually looks like this:

C:\>

The letter may be different, and there might be other things after it, so you might just as easily see something like:

D:\Steve\Projects\Python>

depending on how your computer has been set up and what else you have recently done with it. Once you have started such a window, you are well on the way to running Python programs.

You need to realize that your Python scripts have to be processed by another program called the Python interpreter. The interpreter reads your script, compiles it into bytecodes, and then executes the bytecodes to run your program. So, how do you arrange for the interpreter to handle your Python?

First, you need to make sure that your command window recognises the word "python" as an instruction to start the interpreter. If you have opened a command window, you should try entering the command python and hitting return. You should then see something like:

Python 2.2 (#28, Dec 21 2001, 12:21:22) [MSC 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>>

You have started the interpreter in "interactive mode". That means you can enter Python statements or expressions interactively and have them executed or evaluated while you wait. This is one of Python's strongest features. Check it by entering a few expressions of your choice and seeing the results:

>>> print "Hello"
Hello
>>> "Hello" * 3
HelloHelloHello

Many people use the interactive mode as a convenient yet highly programmable calculator. When you want to end your interactive Python session, hold the Ctrl key down while you enter a Z, then hit the "Enter" key to get back to your Windows command prompt.

You may also find that you have a Start-menu entry such as "Start | Programs | Python 2.2 | Python (command line)" that results in you seeing the >>> prompt in a new window. If so, the window will disappear after you enter the Ctrl-Z character; Windows is running a single "python" command in the window, and closes it when you terminate the interpreter.

If the python command, instead of displaying the interpreter prompt >>>, gives you a message like:

'python' is not recognized as an internal or external command,
operable program or batch file.

or:

Bad command or filename

then you need to make sure that your computer knows where to find the Python interpreter. To do this you will have to modify a setting called PATH, which is a list of directories where Windows will look for programs. You should arrange for Python's installation directory to be added to the PATH of every command window as it starts. If you installed Python fairly recently then the command

dir C:\py*

will probably tell you where it is installed; the usual location is something like C:\Python23. Otherwise you will be reduced to a search of your whole disk ... use "Tools | Find" or hit the "Search" button and look for "python.exe". Supposing you discover that Python is installed in the C:\Python23 directory (the default at the time of writing), you should make sure that entering the command

c:\Python23\python

starts up the interpreter as above (and don't forget you'll need a "CTRL-Z" and an "Enter" to get out of it). Once you have verified the directory, you need to add it to the start-up routines your computer goes through. For older versions of Windows the easiest way to do this is to edit the C:\AUTOEXEC.BAT file. You would want to add a line like the following to AUTOEXEC.BAT:

PATH C:\Python23;%PATH%

For Windows NT, 2000 and (I assume) XP, you will need to add a string such as

;C:\Python23

to the current setting for the PATH environment variable, which you will find in the properties window of "My Computer" under the "Advanced" tab. Note that if you have sufficient privilege you might get a choice of installing the settings either for the Current User or for System. The latter is preferred if you want everybody to be able to run Python on the machine.

If you aren't confident doing any of these manipulations yourself, ask for help! At this stage you may want to reboot your system to make absolutely sure the new setting has taken effect. You probably won't need to reboot for Windows NT, XP or 2000. You can also avoid it in earlier versions by editing the file C:\WINDOWS\COMMAND\CMDINIT.BAT instead of AUTOEXEC.BAT.

You should now be able to start a new command window, enter python at the C:> (or whatever) prompt, and see the >>> prompt that indicates the Python interpreter is reading interactive commands.

Let's suppose you have a program called pytest.py in directory C:\Steve\Projects\Python. A session to run that program might look like this:

C:\> cd \Steve\Projects\Python
C:\Steve\Projects\Python> python pytest.py

Because you added a file name to the command to start the interpreter, when it starts up it reads the Python script in the named file, compiles it, executes it, and terminates, so you see another C:\> prompt. You might also have entered

C:\> python \Steve\Projects\Python\pytest.py

if you hadn't wanted to change your current directory.

Under NT, 2000 and XP you may well find that the installation process has also arranged that the command pytest.py (or, if the file isn't in the current directory, C:\Steve\Projects\Python\pytest.py) will automatically recognize the ".py" extension and run the Python interpreter on the named file. Using this feature is fine, but some versions of Windows have bugs which mean that this form isn't exactly equivalent to using the interpreter explicitly, so be careful.

The important things to remember are:

  1. Start Python from the Start Menu, or make sure the PATH is set correctly so Windows can find the Python interpreter.

    python
    

    should give you a '>>>" prompt from the Python interpreter. Don't forget the CTRL-Z and ENTER to terminate the interpreter (and, if you started the window from the Start Menu, make the window disappear).

  2. Once this works, you run programs with commands:

    python {program-file}
    
  3. When you know the commands to use you can build Windows shortcuts to run the Python interpreter on any of your scripts, naming particular working directories, and adding them to your menus. Take a look at

    python --help
    

    if your needs are complex.

  4. Interactive mode (where you see the >>> prompt) is best used for checking that individual statements and expressions do what you think they will, and for developing code by experiment.

2   How do I make python scripts executable?

On Windows 2000, the standard Python installer already associates the .py extension with a file type (Python.File) and gives that file type an open command that runs the interpreter (D:\Program Files\Python\python.exe "%1" %*). This is enough to make scripts executable from the command prompt as 'foo.py'. If you'd rather be able to execute the script by simple typing 'foo' with no extension you need to add .py to the PATHEXT environment variable.

On Windows NT, the steps taken by the installer as described above allow you to run a script with 'foo.py', but a longtime bug in the NT command processor prevents you from redirecting the input or output of any script executed in this way. This is often important.

The incantation for making a Python script executable under WinNT is to give the file an extension of .cmd and add the following as the first line:

@setlocal enableextensions & python -x %~f0 %* & goto :EOF

3   Why does Python sometimes take so long to start?

Usually Python starts very quickly on Windows, but occasionally there are bug reports that Python suddenly begins to take a long time to start up. This is made even more puzzling because Python will work fine on other Windows systems which appear to be configured identically.

The problem may be caused by a misconfiguration of virus checking software on the problem machine. Some virus scanners have been known to introduce startup overhead of two orders of magnitude when the scanner is configured to monitor all reads from the filesystem. Try checking the configuration of virus scanning software on your systems to ensure that they are indeed configured identically. McAfee, when configured to scan all file system read activity, is a particular offender.

4   Where is Freeze for Windows?

"Freeze" is a program that allows you to ship a Python program as a single stand-alone executable file. It is not a compiler; your programs don't run any faster, but they are more easily distributable, at least to platforms with the same OS and CPU. Read the README file of the freeze program for more disclaimers.

You can use freeze on Windows, but you must download the source tree (see http://www.python.org/download/download_source.html). The freeze program is in the Tools\freeze subdirectory of the source tree.

You need the Microsoft VC++ compiler, and you probably need to build Python. The required project files are in the PCbuild directory.

5   Is a *.pyd file the same as a DLL?

Yes, .pyd files are dll's, but there are a few differences. If you have a DLL named foo.pyd, then it must have a function initfoo(). You can then write Python "import foo", and Python will search for foo.pyd (as well as foo.py, foo.pyc) and if it finds it, will attempt to call initfoo() to initialize it. You do not link your .exe with foo.lib, as that would cause Windows to require the DLL to be present.

Note that the search path for foo.pyd is PYTHONPATH, not the same as the path that Windows uses to search for foo.dll. Also, foo.pyd need not be present to run your program, whereas if you linked your program with a dll, the dll is required. Of course, foo.pyd is required if you want to say "import foo". In a DLL, linkage is declared in the source code with __declspec(dllexport). In a .pyd, linkage is defined in a list of available functions.

6   How can I embed Python into a Windows application?

Embedding the Python interpreter in a Windows app can be summarized as follows:

  1. Do _not_ build Python into your .exe file directly. On Windows, Python must be a DLL to handle importing modules that are themselves DLL's. (This is the first key undocumented fact.) Instead, link to pythonNN.dll; it is typically installed in C:\Windows\System. NN is the Python version, a number such as "23" for Python 2.3.

    You can link to Python statically or dynamically. Linking statically means linking against pythonNN.lib, while dynamically linking means linking against pythonNN.dll. The drawback to dynamic linking is that your app won't run if pythonNN.dll does not exist on your system. (General note: pythonNN.lib is the so-called "import lib" corresponding to python.dll. It merely defines symbols for the linker.)

    Linking dynamically greatly simplifies link options; everything happens at run time. Your code must load pythonNN.dll using the Windows LoadLibraryEx() routine. The code must also use access routines and data in pythonNN.dll (that is, Python's C API's) using pointers obtained by the Windows GetProcAddress() routine. Macros can make using these pointers transparent to any C code that calls routines in Python's C API.

    Borland note: convert pythonNN.lib to OMF format using Coff2Omf.exe first.

  2. If you use SWIG, it is easy to create a Python "extension module" that will make the app's data and methods available to Python. SWIG will handle just about all the grungy details for you. The result is C code that you link into your .exe file (!) You do _not_ have to create a DLL file, and this also simplifies linking.

  3. SWIG will create an init function (a C function) whose name depends on the name of the extension module. For example, if the name of the module is leo, the init function will be called initleo(). If you use SWIG shadow classes, as you should, the init function will be called initleoc(). This initializes a mostly hidden helper class used by the shadow class.

    The reason you can link the C code in step 2 into your .exe file is that calling the initialization function is equivalent to importing the module into Python! (This is the second key undocumented fact.)

  4. In short, you can use the following code to initialize the Python interpreter with your extension module.

    #include "python.h"
    ...
    Py_Initialize();  // Initialize Python.
    initmyAppc();  // Initialize (import) the helper class.
    PyRun_SimpleString("import myApp") ;  // Import the shadow class.
    
  5. There are two problems with Python's C API which will become apparent if you use a compiler other than MSVC, the compiler used to build pythonNN.dll.

    Problem 1: The so-called "Very High Level" functions that take FILE * arguments will not work in a multi-compiler environment because each compiler's notion of a struct FILE will be different. From an implementation standpoint these are very _low_ level functions.

    Problem 2: SWIG generates the following code when generating wrappers to void functions:

    Py_INCREF(Py_None);
    _resultobj = Py_None;
    return _resultobj;
    

    Alas, Py_None is a macro that expands to a reference to a complex data structure called _Py_NoneStruct inside pythonNN.dll. Again, this code will fail in a mult-compiler environment. Replace such code by:

    return Py_BuildValue("");
    

    It may be possible to use SWIG's %typemap command to make the change automatically, though I have not been able to get this to work (I'm a complete SWIG newbie).

  6. Using a Python shell script to put up a Python interpreter window from inside your Windows app is not a good idea; the resulting window will be independent of your app's windowing system. Rather, you (or the wxPythonWindow class) should create a "native" interpreter window. It is easy to connect that window to the Python interpreter. You can redirect Python's i/o to _any_ object that supports read and write, so all you need is a Python object (defined in your extension module) that contains read() and write() methods.

7   How do I use Python for CGI?

On the Microsoft IIS server or on the Win95 MS Personal Web Server you set up Python in the same way that you would set up any other scripting engine.

Run regedt32 and go to:

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\ScriptMap

and enter the following line (making any specific changes that your system may need):

.py :REG_SZ: c:\<path to python>\python.exe -u %s %s

This line will allow you to call your script with a simple reference like: http://yourserver/scripts/yourscript.py provided "scripts" is an "executable" directory for your server (which it usually is by default). The "-u" flag specifies unbuffered and binary mode for stdin - needed when working with binary data.

In addition, it is recommended that using ".py" may not be a good idea for the file extensions when used in this context (you might want to reserve *.py for support modules and use *.cgi or *.cgp for "main program" scripts).

In order to set up Internet Information Services 5 to use Python for CGI processing, please see the following links:

http://www.e-coli.net/pyiis_server.html (for Win2k Server) http://www.e-coli.net/pyiis.html (for Win2k pro)

Configuring Apache is much simpler. In the Apache configuration file httpd.conf, add the following line at the end of the file:

ScriptInterpreterSource Registry

Then, give your Python CGI-scripts the extension .py and put them in the cgi-bin directory.

8   How do I keep editors from inserting tabs into my Python source?

The FAQ does not recommend using tabs, and the Python style guide recommends 4 spaces for distributed Python code; this is also the Emacs python-mode default.

Under any editor, mixing tabs and spaces is a bad idea. MSVC is no different in this respect, and is easily configured to use spaces: Take Tools -> Options -> Tabs, and for file type "Default" set "Tab size" and "Indent size" to 4, and select the "Insert spaces" radio button.

If you suspect mixed tabs and spaces are causing problems in leading whitespace, run Python with the -t switch or run Tools/Scripts/tabnanny.py to check a directory tree in batch mode.

9   How do I check for a keypress without blocking?

Use the msvcrt module. This is a standard Windows-specific extension module. It defines a function kbhit() which checks whether a keyboard hit is present, and getch() which gets one character without echoing it.

10   How do I emulate os.kill() in Windows?

Use win32api:

def kill(pid):
    """kill function for Win32"""
    import win32api
    handle = win32api.OpenProcess(1, 0, pid)
    return (0 != win32api.TerminateProcess(handle, 0))

11   Why does os.path.isdir() fail on NT shared directories?

The solution appears to be always append the "\" on the end of shared drives.

>>> import os
>>> os.path.isdir( '\\\\rorschach\\public')
0
>>> os.path.isdir( '\\\\rorschach\\public\\')
1

It helps to think of share points as being like drive letters. Example:

k: is not a directory
k:\ is a directory
k:\media is a directory
k:\media\ is not a directory

The same rules apply if you substitute "k:" with "\conkyfoo":

\\conky\foo  is not a directory
\\conky\foo\ is a directory
\\conky\foo\media is a directory
\\conky\foo\media\ is not a directory

12   cgi.py (or other CGI programming) doesn't work sometimes on NT or win95!

Be sure you have the latest python.exe, that you are using python.exe rather than a GUI version of Python and that you have configured the server to execute

"...\python.exe -u ..."

for the CGI execution. The -u (unbuffered) option on NT and Win95 prevents the interpreter from altering newlines in the standard input and output. Without it post/multipart requests will seem to have the wrong length and binary (e.g. GIF) responses may get garbled (resulting in broken images, PDF files, and other binary downloads failing).

13   Why doesn't os.popen() work in PythonWin on NT?

The reason that os.popen() doesn't work from within PythonWin is due to a bug in Microsoft's C Runtime Library (CRT). The CRT assumes you have a Win32 console attached to the process.

You should use the win32pipe module's popen() instead which doesn't depend on having an attached Win32 console.

Example:

import win32pipe
f = win32pipe.popen('dir /c c:\\')
print f.readlines()
f.close()

14   Why doesn't os.popen()/win32pipe.popen() work on Win9x?

There is a bug in Win9x that prevents os.popen/win32pipe.popen* from working. The good news is there is a way to work around this problem. The Microsoft Knowledge Base article that you need to lookup is: Q150956. You will find links to the knowledge base at: http://www.microsoft.com/kb.

15   PyRun_SimpleFile() crashes on Windows but not on Unix; why?

This is very sensitive to the compiler vendor, version and (perhaps) even options. If the FILE* structure in your embedding program isn't the same as is assumed by the Python interpreter it won't work.

The Python 1.5.* DLLs (python15.dll) are all compiled with MS VC++ 5.0 and with multithreading-DLL options (/MD).

If you can't change compilers or flags, try using Py_RunSimpleString(). A trick to get it to run an arbitrary file is to construct a call to execfile() with the name of your file as argument.

Also note that you can not mix-and-match Debug and Release versions. If you wish to use the Debug Multithreaded DLL, then your module _must_ have an "_d" appended to the base name.

16   Importing _tkinter fails on Windows 95/98: why?

Sometimes, the import of _tkinter fails on Windows 95 or 98, complaining with a message like the following:

ImportError: DLL load failed: One of the library files needed
to run this application cannot be found.

It could be that you haven't installed Tcl/Tk, but if you did install Tcl/Tk, and the Wish application works correctly, the problem may be that its installer didn't manage to edit the autoexec.bat file correctly. It tries to add a statement that changes the PATH environment variable to include the Tcl/Tk 'bin' subdirectory, but sometimes this edit doesn't quite work. Opening it with notepad usually reveals what the problem is.

(One additional hint, noted by David Szafranski: you can't use long filenames here; e.g. use C:\PROGRA~1\Tcl\bin instead of C:\Program Files\Tcl\bin.)

17   How do I extract the downloaded documentation on Windows?

Sometimes, when you download the documentation package to a Windows machine using a web browser, the file extension of the saved file ends up being .EXE. This is a mistake; the extension should be .TGZ.

Simply rename the downloaded file to have the .TGZ extension, and WinZip will be able to handle it. (If your copy of WinZip doesn't, get a newer one from http://www.winzip.com.)

18   Missing cw3215mt.dll (or missing cw3215.dll)

Sometimes, when using Tkinter on Windows, you get an error that cw3215mt.dll or cw3215.dll is missing.

Cause: you have an old Tcl/Tk DLL built with cygwin in your path (probably C:\Windows). You must use the Tcl/Tk DLLs from the standard Tcl/Tk installation (Python 1.5.2 comes with one).

19   Warning about CTL3D32 version from installer

The Python installer issues a warning like this:

This version uses ``CTL3D32.DLL`` whitch is not the correct version.
This version is used for windows NT applications only.

[Tim Peters] This is a Microsoft DLL, and a notorious source of problems. The message means what it says: you have the wrong version of this DLL for your operating system. The Python installation did not cause this -- something else you installed previous to this overwrote the DLL that came with your OS (probably older shareware of some sort, but there's no way to tell now). If you search for "CTL3D32" using any search engine (AltaVista, for example), you'll find hundreds and hundreds of web pages complaining about the same problem with all sorts of installation programs. They'll point you to ways to get the correct version reinstalled on your system (since Python doesn't cause this, we can't fix it).

David A Burton has written a little program to fix this. Go to http://www.burtonsys.com/download.html and click on "ctl3dfix.zip"

python-defaults-2.7.12/faq/programming.ht0000664000000000000000000017673112057417145015274 0ustar Title: Python Programming FAQ Content-type: text/x-rst ==================================== Programming FAQ ==================================== :Date: $Date: 2005-12-21 22:00:52 -0700 (Wed, 21 Dec 2005) $ :Version: $Revision: 8721 $ :Web site: http://www.python.org/ .. contents:: .. sectnum:: General Questions =========================== Is there a source code level debugger with breakpoints, single-stepping, etc.? ------------------------------------------------------------------------------- Yes. The pdb module is a simple but adequate console-mode debugger for Python. It is part of the standard Python library, and is `documented in the Library Reference Manual `_. You can also write your own debugger by using the code for pdb as an example. The IDLE interactive development environment, which is part of the standard Python distribution (normally available as Tools/scripts/idle), includes a graphical debugger. There is documentation for the IDLE debugger at http://www.python.org/idle/doc/idle2.html#Debugger PythonWin is a Python IDE that includes a GUI debugger based on pdb. The Pythonwin debugger colors breakpoints and has quite a few cool features such as debugging non-Pythonwin programs. A reference can be found at http://www.python.org/windows/pythonwin/. Recent versions of PythonWin are available as a part of the ActivePython distribution (see http://www.activestate.com/Products/ActivePython/index.html). `Boa Constructor `_ is an IDE and GUI builder that uses wxPython. It offers visual frame creation and manipulation, an object inspector, many views on the source like object browsers, inheritance hierarchies, doc string generated html documentation, an advanced debugger, integrated help, and Zope support. `Eric3 `_ is an IDE built on PyQt and the Scintilla editing component. Pydb is a version of the standard Python debugger pdb, modified for use with DDD (Data Display Debugger), a popular graphical debugger front end. Pydb can be found at http://packages.debian.org/unstable/devel/pydb.html> and DDD can be found at http://www.gnu.org/software/ddd. There are a number of commmercial Python IDEs that include graphical debuggers. They include: * Wing IDE (http://wingide.com) * Komodo IDE (http://www.activestate.com/Products/Komodo) Is there a tool to help find bugs or perform static analysis? ---------------------------------------------------------------------- Yes. PyChecker is a static analysis tool that finds bugs in Python source code and warns about code complexity and style. You can get PyChecker from http://pychecker.sf.net. `Pylint `_ is another tool that checks if a module satisfies a coding standard, and also makes it possible to write plug-ins to add a custom feature. In addition to the bug checking that PyChecker performs, Pylint offers some additional features such as checking line length, whether variable names are well-formed according to your coding standard, whether declared interfaces are fully implemented, and more. http://www.logilab.org/projects/pylint/documentation provides a full list of Pylint's features. How can I create a stand-alone binary from a Python script? ------------------------------------------------------------------- You don't need the ability to compile Python to C code if all you want is a stand-alone program that users can download and run without having to install the Python distribution first. There are a number of tools that determine the set of modules required by a program and bind these modules together with a Python binary to produce a single executable. One is to use the freeze tool, which is included in the Python source tree as ``Tools/freeze``. It converts Python byte code to C arrays; a C compiler you can embed all your modules into a new program, which is then linked with the standard Python modules. It works by scanning your source recursively for import statements (in both forms) and looking for the modules in the standard Python path as well as in the source directory (for built-in modules). It then turns the bytecode for modules written in Python into C code (array initializers that can be turned into code objects using the marshal module) and creates a custom-made config file that only contains those built-in modules which are actually used in the program. It then compiles the generated C code and links it with the rest of the Python interpreter to form a self-contained binary which acts exactly like your script. Obviously, freeze requires a C compiler. There are several other utilities which don't. The first is Gordon McMillan's installer at http://www.mcmillan-inc.com/install1.html which works on Windows, Linux and at least some forms of Unix. Another is Thomas Heller's py2exe (Windows only) at http://starship.python.net/crew/theller/py2exe A third is Christian Tismer's `SQFREEZE `_ which appends the byte code to a specially-prepared Python interpreter that can find the byte code in the executable. It's possible that a similar approach will be added to Python 2.4, due out some time in 2004. Other tools include Fredrik Lundh's `Squeeze `_ and Anthony Tuininga's `cx_Freeze `_. Are there coding standards or a style guide for Python programs? ------------------------------------------------------------------------ Yes. The coding style required for standard library modules is documented as `PEP 8 <../../peps/pep-0008.html>`_. My program is too slow. How do I speed it up? ---------------------------------------------------- That's a tough one, in general. There are many tricks to speed up Python code; consider rewriting parts in C as a last resort. In some cases it's possible to automatically translate Python to C or x86 assembly language, meaning that you don't have to modify your code to gain increased speed. `Pyrex `_ can compile a slightly modified version of Python code into a C extension, and can be used on many different platforms. `Psyco `_ is a just-in-time compiler that translates Python code into x86 assembly language. If you can use it, Psyco can provide dramatic speedups for critical functions. The rest of this answer will discuss various tricks for squeezing a bit more speed out of Python code. *Never* apply any optimization tricks unless you know you need them, after profiling has indicated that a particular function is the heavily executed hot spot in the code. Optimizations almost always make the code less clear, and you shouldn't pay the costs of reduced clarity (increased development time, greater likelihood of bugs) unless the resulting performance benefit is worth it. There is a page on the wiki devoted to `performance tips `_. Guido van Rossum has written up an anecdote related to optimization at http://www.python.org/doc/essays/list2str.html. One thing to notice is that function and (especially) method calls are rather expensive; if you have designed a purely OO interface with lots of tiny functions that don't do much more than get or set an instance variable or call another method, you might consider using a more direct way such as directly accessing instance variables. Also see the standard module "profile" (`described in the Library Reference manual `_) which makes it possible to find out where your program is spending most of its time (if you have some patience -- the profiling itself can slow your program down by an order of magnitude). Remember that many standard optimization heuristics you may know from other programming experience may well apply to Python. For example it may be faster to send output to output devices using larger writes rather than smaller ones in order to reduce the overhead of kernel system calls. Thus CGI scripts that write all output in "one shot" may be faster than those that write lots of small pieces of output. Also, be sure to use Python's core features where appropriate. For example, slicing allows programs to chop up lists and other sequence objects in a single tick of the interpreter's mainloop using highly optimized C implementations. Thus to get the same effect as:: L2 = [] for i in range[3]: L2.append(L1[i]) it is much shorter and far faster to use :: L2 = list(L1[:3]) # "list" is redundant if L1 is a list. Note that the functionally-oriented builtins such as ``map()``, ``zip()``, and friends can be a convenient accelerator for loops that perform a single task. For example to pair the elements of two lists together:: >>> zip([1,2,3], [4,5,6]) [(1, 4), (2, 5), (3, 6)] or to compute a number of sines:: >>> map( math.sin, (1,2,3,4)) [0.841470984808, 0.909297426826, 0.14112000806, -0.756802495308] The operation completes very quickly in such cases. Other examples include the ``join()`` and ``split()`` methods of string objects. For example if s1..s7 are large (10K+) strings then ``"".join([s1,s2,s3,s4,s5,s6,s7])` may be far faster than the more obvious ``s1+s2+s3+s4+s5+s6+s7``, since the "summation" will compute many subexpressions, whereas ``join()`` does all the copying in one pass. For manipulating strings, use the ``replace()`` method on string objects. Use regular expressions only when you're not dealing with constant string patterns. Consider using the string formatting operations ``string % tuple`` and ``string % dictionary``. Be sure to use the ``list.sort()`` builtin method to do sorting, and see the `sorting mini-HOWTO `_ for examples of moderately advanced usage. ``list.sort()`` beats other techniques for sorting in all but the most extreme circumstances. Another common trick is to "push loops into functions or methods." For example suppose you have a program that runs slowly and you use the profiler to determine that a Python function ``ff()`` is being called lots of times. If you notice that ``ff ()``:: def ff(x): ...do something with x computing result... return result tends to be called in loops like:: list = map(ff, oldlist) or:: for x in sequence: value = ff(x) ...do something with value... then you can often eliminate function call overhead by rewriting ``ff()`` to:: def ffseq(seq): resultseq = [] for x in seq: ...do something with x computing result... resultseq.append(result) return resultseq and rewrite the two examples to ``list = ffseq(oldlist)`` and to:: for value in ffseq(sequence): ...do something with value... Single calls to ff(x) translate to ffseq([x])[0] with little penalty. Of course this technique is not always appropriate and there are other variants which you can figure out. You can gain some performance by explicitly storing the results of a function or method lookup into a local variable. A loop like:: for key in token: dict[key] = dict.get(key, 0) + 1 resolves dict.get every iteration. If the method isn't going to change, a slightly faster implementation is:: dict_get = dict.get # look up the method once for key in token: dict[key] = dict_get(key, 0) + 1 Default arguments can be used to determine values once, at compile time instead of at run time. This can only be done for functions or objects which will not be changed during program execution, such as replacing :: def degree_sin(deg): return math.sin(deg * math.pi / 180.0) with :: def degree_sin(deg, factor = math.pi/180.0, sin = math.sin): return sin(deg * factor) Because this trick uses default arguments for terms which should not be changed, it should only be used when you are not concerned with presenting a possibly confusing API to your users. Core Language ================== How do you set a global variable in a function? ---------------------------------------------------------- Did you do something like this? :: x = 1 # make a global def f(): print x # try to print the global ... for j in range(100): if q>3: x=4 Any variable assigned in a function is local to that function. unless it is specifically declared global. Since a value is bound to ``x`` as the last statement of the function body, the compiler assumes that ``x`` is local. Consequently the ``print x`` attempts to print an uninitialized local variable and will trigger a ``NameError``. The solution is to insert an explicit global declaration at the start of the function:: def f(): global x print x # try to print the global ... for j in range(100): if q>3: x=4 In this case, all references to ``x`` are interpreted as references to the ``x`` from the module namespace. What are the rules for local and global variables in Python? -------------------------------------------------------------------------- In Python, variables that are only referenced inside a function are implicitly global. If a variable is assigned a new value anywhere within the function's body, it's assumed to be a local. If a variable is ever assigned a new value inside the function, the variable is implicitly local, and you need to explicitly declare it as 'global'. Though a bit surprising at first, a moment's consideration explains this. On one hand, requiring ``global`` for assigned variables provides a bar against unintended side-effects. On the other hand, if ``global`` was required for all global references, you'd be using ``global`` all the time. You'd have to declare as global every reference to a builtin function or to a component of an imported module. This clutter would defeat the usefulness of the ``global`` declaration for identifying side-effects. How do I share global variables across modules? ------------------------------------------------ The canonical way to share information across modules within a single program is to create a special module (often called config or cfg). Just import the config module in all modules of your application; the module then becomes available as a global name. Because there is only one instance of each module, any changes made to the module object get reflected everywhere. For example: config.py:: x = 0 # Default value of the 'x' configuration setting mod.py:: import config config.x = 1 main.py:: import config import mod print config.x Note that using a module is also the basis for implementing the Singleton design pattern, for the same reason. What are the "best practices" for using import in a module? ------------------------------------------------------------------------------ In general, don't use ``from modulename import *``. Doing so clutters the importer's namespace. Some people avoid this idiom even with the few modules that were designed to be imported in this manner. Modules designed in this manner include ``Tkinter``, and ``threading``. Import modules at the top of a file. Doing so makes it clear what other modules your code requires and avoids questions of whether the module name is in scope. Using one import per line makes it easy to add and delete module imports, but using multiple imports per line uses less screen space. It's good practice if you import modules in the following order: 1. standard libary modules -- e.g. ``sys``, ``os``, ``getopt``, ``re``) 2. third-party library modules (anything installed in Python's site-packages directory) -- e.g. mx.DateTime, ZODB, PIL.Image, etc. 3. locally-developed modules Never use relative package imports. If you're writing code that's in the ``package.sub.m1`` module and want to import ``package.sub.m2``, do not just write ``import m2``, even though it's legal. Write ``from package.sub import m2`` instead. Relative imports can lead to a module being initialized twice, leading to confusing bugs. It is sometimes necessary to move imports to a function or class to avoid problems with circular imports. Gordon McMillan says: Circular imports are fine where both modules use the "import " form of import. They fail when the 2nd module wants to grab a name out of the first ("from module import name") and the import is at the top level. That's because names in the 1st are not yet available, because the first module is busy importing the 2nd. In this case, if the second module is only used in one function, then the import can easily be moved into that function. By the time the import is called, the first module will have finished initializing, and the second module can do its import. It may also be necessary to move imports out of the top level of code if some of the modules are platform-specific. In that case, it may not even be possible to import all of the modules at the top of the file. In this case, importing the correct modules in the corresponding platform-specific code is a good option. Only move imports into a local scope, such as inside a function definition, if it's necessary to solve a problem such as avoiding a circular import or are trying to reduce the initialization time of a module. This technique is especially helpful if many of the imports are unnecessary depending on how the program executes. You may also want to move imports into a function if the modules are only ever used in that function. Note that loading a module the first time may be expensive because of the one time initialization of the module, but loading a module multiple times is virtually free, costing only a couple of dictionary lookups. Even if the module name has gone out of scope, the module is probably available in sys.modules. If only instances of a specific class use a module, then it is reasonable to import the module in the class's ``__init__`` method and then assign the module to an instance variable so that the module is always available (via that instance variable) during the life of the object. Note that to delay an import until the class is instantiated, the import must be inside a method. Putting the import inside the class but outside of any method still causes the import to occur when the module is initialized. How can I pass optional or keyword parameters from one function to another? ------------------------------------------------------------------------------- Collect the arguments using the ``*`` and ``**`` specifiers in the function's parameter list; this gives you the positional arguments as a tuple and the keyword arguments as a dictionary. You can then pass these arguments when calling another function by using ``*`` and ``**``:: def f(x, *tup, **kwargs): ... kwargs['width']='14.3c' ... g(x, *tup, **kwargs) In the unlikely case that you care about Python versions older than 2.0, use 'apply':: def f(x, *tup, **kwargs): ... kwargs['width']='14.3c' ... apply(g, (x,)+tup, kwargs) How do I write a function with output parameters (call by reference)? ----------------------------------------------------------------------------- Remember that arguments are passed by assignment in Python. Since assignment just creates references to objects, there's no alias between an argument name in the caller and callee, and so no call-by-reference per se. You can achieve the desired effect in a number of ways. 1) By returning a tuple of the results:: def func2(a, b): a = 'new-value' # a and b are local names b = b + 1 # assigned to new objects return a, b # return new values x, y = 'old-value', 99 x, y = func2(x, y) print x, y # output: new-value 100 This is almost always the clearest solution. 2) By using global variables. This isn't thread-safe, and is not recommended. 3) By passing a mutable (changeable in-place) object:: def func1(a): a[0] = 'new-value' # 'a' references a mutable list a[1] = a[1] + 1 # changes a shared object args = ['old-value', 99] func1(args) print args[0], args[1] # output: new-value 100 4) By passing in a dictionary that gets mutated:: def func3(args): args['a'] = 'new-value' # args is a mutable dictionary args['b'] = args['b'] + 1 # change it in-place args = {'a':' old-value', 'b': 99} func3(args) print args['a'], args['b'] 5) Or bundle up values in a class instance:: class callByRef: def __init__(self, **args): for (key, value) in args.items(): setattr(self, key, value) def func4(args): args.a = 'new-value' # args is a mutable callByRef args.b = args.b + 1 # change object in-place args = callByRef(a='old-value', b=99) func4(args) print args.a, args.b There's almost never a good reason to get this complicated. Your best choice is to return a tuple containing the multiple results. How do you make a higher order function in Python? ---------------------------------------------------------- You have two choices: you can use nested scopes or you can use callable objects. For example, suppose you wanted to define ``linear(a,b)`` which returns a function ``f(x)`` that computes the value ``a*x+b``. Using nested scopes:: def linear(a,b): def result(x): return a*x + b return result Or using a callable object:: class linear: def __init__(self, a, b): self.a, self.b = a,b def __call__(self, x): return self.a * x + self.b In both cases:: taxes = linear(0.3,2) gives a callable object where taxes(10e6) == 0.3 * 10e6 + 2. The callable object approach has the disadvantage that it is a bit slower and results in slightly longer code. However, note that a collection of callables can share their signature via inheritance:: class exponential(linear): # __init__ inherited def __call__(self, x): return self.a * (x ** self.b) Object can encapsulate state for several methods:: class counter: value = 0 def set(self, x): self.value = x def up(self): self.value=self.value+1 def down(self): self.value=self.value-1 count = counter() inc, dec, reset = count.up, count.down, count.set Here ``inc()``, ``dec()`` and ``reset()`` act like functions which share the same counting variable. How do I copy an object in Python? ------------------------------------------ In general, try copy.copy() or copy.deepcopy() for the general case. Not all objects can be copied, but most can. Some objects can be copied more easily. Dictionaries have a ``copy()`` method:: newdict = olddict.copy() Sequences can be copied by slicing:: new_l = l[:] How can I find the methods or attributes of an object? -------------------------------------------------------------- For an instance x of a user-defined class, ``dir(x)`` returns an alphabetized list of the names containing the instance attributes and methods and attributes defined by its class. How can my code discover the name of an object? ------------------------------------------------------- Generally speaking, it can't, because objects don't really have names. Essentially, assignment always binds a name to a value; The same is true of ``def`` and ``class`` statements, but in that case the value is a callable. Consider the following code:: class A: pass B = A a = B() b = a print b <__main__.A instance at 016D07CC> print a <__main__.A instance at 016D07CC> Arguably the class has a name: even though it is bound to two names and invoked through the name B the created instance is still reported as an instance of class A. However, it is impossible to say whether the instance's name is a or b, since both names are bound to the same value. Generally speaking it should not be necessary for your code to "know the names" of particular values. Unless you are deliberately writing introspective programs, this is usually an indication that a change of approach might be beneficial. In comp.lang.python, Fredrik Lundh once gave an excellent analogy in answer to this question: The same way as you get the name of that cat you found on your porch: the cat (object) itself cannot tell you its name, and it doesn't really care -- so the only way to find out what it's called is to ask all your neighbours (namespaces) if it's their cat (object)... ....and don't be surprised if you'll find that it's known by many names, or no name at all! Is there an equivalent of C's "?:" ternary operator? ---------------------------------------------------------------------- No. In many cases you can mimic a?b:c with "a and b or c", but there's a flaw: if b is zero (or empty, or None -- anything that tests false) then c will be selected instead. In many cases you can prove by looking at the code that this can't happen (e.g. because b is a constant or has a type that can never be false), but in general this can be a problem. Tim Peters (who wishes it was Steve Majewski) suggested the following solution: (a and [b] or [c])[0]. Because [b] is a singleton list it is never false, so the wrong path is never taken; then applying [0] to the whole thing gets the b or c that you really wanted. Ugly, but it gets you there in the rare cases where it is really inconvenient to rewrite your code using 'if'. The best course is usually to write a simple ``if...else`` statement. Another solution is to implement the "?:" operator as a function:: def q(cond,on_true,on_false): if cond: if not isfunction(on_true): return on_true else: return apply(on_true) else: if not isfunction(on_false): return on_false else: return apply(on_false) In most cases you'll pass b and c directly: ``q(a,b,c)``. To avoid evaluating b or c when they shouldn't be, encapsulate them within a lambda function, e.g.: ``q(a,lambda: b, lambda: c)``. It has been asked *why* Python has no if-then-else expression. There are several answers: many languages do just fine without one; it can easily lead to less readable code; no sufficiently "Pythonic" syntax has been discovered; a search of the standard library found remarkably few places where using an if-then-else expression would make the code more understandable. In 2002, `PEP 308 <../../peps/pep-0308.html>`_ was written proposing several possible syntaxes and the community was asked to vote on the issue. The vote was inconclusive. Most people liked one of the syntaxes, but also hated other syntaxes; many votes implied that people preferred no ternary operator rather than having a syntax they hated. Is it possible to write obfuscated one-liners in Python? ---------------------------------------------------------------- Yes. Usually this is done by nesting `lambda` within `lambda`. See the following three examples, due to Ulf Bartelt:: # Primes < 1000 print filter(None,map(lambda y:y*reduce(lambda x,y:x*y!=0, map(lambda x,y=y:y%x,range(2,int(pow(y,0.5)+1))),1),range(2,1000))) # First 10 Fibonacci numbers print map(lambda x,f=lambda x,f:(x<=1) or (f(x-1,f)+f(x-2,f)): f(x,f), range(10)) # Mandelbrot set print (lambda Ru,Ro,Iu,Io,IM,Sx,Sy:reduce(lambda x,y:x+y,map(lambda y, Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,Sy=Sy,L=lambda yc,Iu=Iu,Io=Io,Ru=Ru,Ro=Ro,i=IM, Sx=Sx,Sy=Sy:reduce(lambda x,y:x+y,map(lambda x,xc=Ru,yc=yc,Ru=Ru,Ro=Ro, i=i,Sx=Sx,F=lambda xc,yc,x,y,k,f=lambda xc,yc,x,y,k,f:(k<=0)or (x*x+y*y >=4.0) or 1+f(xc,yc,x*x-y*y+xc,2.0*x*y+yc,k-1,f):f(xc,yc,x,y,k,f):chr( 64+F(Ru+x*(Ro-Ru)/Sx,yc,0,0,i)),range(Sx))):L(Iu+y*(Io-Iu)/Sy),range(Sy ))))(-2.1, 0.7, -1.2, 1.2, 30, 80, 24) # \___ ___ \___ ___ | | |__ lines on screen # V V | |______ columns on screen # | | |__________ maximum of "iterations" # | |_________________ range on y axis # |____________________________ range on x axis Don't try this at home, kids! Numbers and strings ========================== How do I specify hexadecimal and octal integers? -------------------------------------------------------- To specify an octal digit, precede the octal value with a zero. For example, to set the variable "a" to the octal value "10" (8 in decimal), type:: >>> a = 010 >>> a 8 Hexadecimal is just as easy. Simply precede the hexadecimal number with a zero, and then a lower or uppercase "x". Hexadecimal digits can be specified in lower or uppercase. For example, in the Python interpreter:: >>> a = 0xa5 >>> a 165 >>> b = 0XB2 >>> b 178 Why does -22 / 10 return -3? ---------------------------------- It's primarily driven by the desire that ``i%j`` have the same sign as ``j``. If you want that, and also want:: i == (i/j)*j + (i%j) then integer division has to return the floor. C also requres that identity to hold, and then compilers that truncate ``i/j`` need to make ``i%j`` have the same sign as ``i``. There are few real use cases for ``i%j`` when ``j`` is negative. When ``j`` is positive, there are many, and in virtually all of them it's more useful for ``i%j`` to be ``>= 0``. If the clock says 10 now, what did it say 200 hours ago? ``-190 % 12 == 2`` is useful; ``-190 % 12 == -10`` is a bug waiting to bite. How do I convert a string to a number? ---------------------------------------------- For integers, use the built-in ``int()`` type constructor, e.g. int('144') == 144. Similarly, ``float()`` converts to floating-point, e.g. ``float('144') == 144.0``. By default, these interpret the number as decimal, so that ``int('0144') == 144`` and ``int('0x144')`` raises ``ValueError``. ``int(string, base)`` takes the base to convert from as a second optional argument, so ``int('0x144', 16) == 324``. If the base is specified as 0, the number is interpreted using Python's rules: a leading '0' indicates octal, and '0x' indicates a hex number. Do not use the built-in function ``eval()`` if all you need is to convert strings to numbers. ``eval()`` will be significantly slower and it presents a security risk: someone could pass you a Python expression that might have unwanted side effects. For example, someone could pass ``__import__('os').system("rm -rf $HOME")`` which would erase your home directory. ``eval()`` also has the effect of interpreting numbers as Python expressions, so that e.g. eval('09') gives a syntax error because Python regards numbers starting with '0' as octal (base 8). How do I convert a number to a string? ---------------------------------------------- To convert, e.g., the number 144 to the string '144', use the built-in function ``str()``. If you want a hexadecimal or octal representation, use the built-in functions ``hex()`` or ``oct()``. For fancy formatting, use `the % operator <../../doc/lib/typesseq-strings.html>`_ on strings, e.g. ``"%04d" % 144`` yields '0144' and ``"%.3f" % (1/3.0)`` yields '0.333'. See the library reference manual for details. How do I modify a string in place? ------------------------------------------ You can't, because strings are immutable. If you need an object with this ability, try converting the string to a list or use the array module:: >>> s = "Hello, world" >>> a = list(s) >>> print a ['H', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd'] >>> a[7:] = list("there!") >>> ''.join(a) 'Hello, there!' >>> import array >>> a = array.array('c', s) >>> print a array('c', 'Hello, world') >>> a[0] = 'y' ; print a array('c', 'yello world') >>> a.tostring() 'yello, world' How do I use strings to call functions/methods? ---------------------------------------------------------- There are various techniques. * The best is to use a dictionary that maps strings to functions. The primary advantage of this technique is that the strings do not need to match the names of the functions. This is also the primary technique used to emulate a case construct:: def a(): pass def b(): pass dispatch = {'go': a, 'stop': b} # Note lack of parens for funcs dispatch[get_input()]() # Note trailing parens to call function * Use the built-in function ``getattr()``:: import foo getattr(foo, 'bar')() Note that getattr() works on any object, including classes, class instances, modules, and so on. This is used in several places in the standard library, like this:: class Foo: def do_foo(self): ... def do_bar(self): ... f = getattr(foo_instance, 'do_' + opname) f() * Use ``locals()`` or ``eval()`` to resolve the function name:: def myFunc(): print "hello" fname = "myFunc" f = locals()[fname] f() f = eval(fname) f() Note: Using ``eval()`` is slow and dangerous. If you don't have absolute control over the contents of the string, someone could pass a string that resulted in an arbitrary function being executed. Is there an equivalent to Perl's chomp() for removing trailing newlines from strings? -------------------------------------------------------------------------------------------- Starting with Python 2.2, you can use ``S.rstrip("\r\n")`` to remove all occurances of any line terminator from the end of the string ``S`` without removing other trailing whitespace. If the string ``S`` represents more than one line, with several empty lines at the end, the line terminators for all the blank lines will be removed:: >>> lines = ("line 1 \r\n" ... "\r\n" ... "\r\n") >>> lines.rstrip("\n\r") "line 1 " Since this is typically only desired when reading text one line at a time, using ``S.rstrip()`` this way works well. For older versions of Python, There are two partial substitutes: - If you want to remove all trailing whitespace, use the ``rstrip()`` method of string objects. This removes all trailing whitespace, not just a single newline. - Otherwise, if there is only one line in the string ``S``, use ``S.splitlines()[0]``. Is there a scanf() or sscanf() equivalent? -------------------------------------------------- Not as such. For simple input parsing, the easiest approach is usually to split the line into whitespace-delimited words using the ``split()`` method of string objects and then convert decimal strings to numeric values using ``int()`` or ``float()``. ``split()`` supports an optional "sep" parameter which is useful if the line uses something other than whitespace as a separator. For more complicated input parsing, regular expressions more powerful than C's ``sscanf()`` and better suited for the task. What does 'UnicodeError: ASCII [decoding,encoding] error: ordinal not in range(128)' mean? ----------------------------------------------------------------------------------------------------- This error indicates that your Python installation can handle only 7-bit ASCII strings. There are a couple ways to fix or work around the problem. If your programs must handle data in arbitary character set encodings, the environment the application runs in will generally identify the encoding of the data it is handing you. You need to convert the input to Unicode data using that encoding. For example, a program that handles email or web input will typically find character set encoding information in Content-Type headers. This can then be used to properly convert input data to Unicode. Assuming the string referred to by ``value`` is encoded as UTF-8:: value = unicode(value, "utf-8") will return a Unicode object. If the data is not correctly encoded as UTF-8, the above call will raise a ``UnicodeError`` exception. If you only want strings coverted to Unicode which have non-ASCII data, you can try converting them first assuming an ASCII encoding, and then generate Unicode objects if that fails:: try: x = unicode(value, "ascii") except UnicodeError: value = unicode(value, "utf-8") else: # value was valid ASCII data pass It's possible to set a default encoding in a file called ``sitecustomize.py`` that's part of the Python library. However, this isn't recommended because changing the Python-wide default encoding may cause third-party extension modules to fail. Note that on Windows, there is an encoding known as "mbcs", which uses an encoding specific to your current locale. In many cases, and particularly when working with COM, this may be an appropriate default encoding to use. Sequences (Tuples/Lists) ================================= How do I convert between tuples and lists? ------------------------------------------------ The function ``tuple(seq)`` converts any sequence (actually, any iterable) into a tuple with the same items in the same order. For example, ``tuple([1, 2, 3])`` yields ``(1, 2, 3)`` and ``tuple('abc')`` yields ``('a', 'b', 'c')``. If the argument is a tuple, it does not make a copy but returns the same object, so it is cheap to call ``tuple()`` when you aren't sure that an object is already a tuple. The function ``list(seq)`` converts any sequence or iterable into a list with the same items in the same order. For example, ``list((1, 2, 3))`` yields ``[1, 2, 3]`` and ``list('abc')`` yields ``['a', 'b', 'c']``. If the argument is a list, it makes a copy just like ``seq[:]`` would. What's a negative index? -------------------------------------------------------------------- Python sequences are indexed with positive numbers and negative numbers. For positive numbers 0 is the first index 1 is the second index and so forth. For negative indices -1 is the last index and -2 is the pentultimate (next to last) index and so forth. Think of ``seq[-n]`` as the same as ``seq[len(seq)-n]``. Using negative indices can be very convenient. For example ``S[:-1]`` is all of the string except for its last character, which is useful for removing the trailing newline from a string. How do I iterate over a sequence in reverse order? --------------------------------------------------------- If it is a list, the fastest solution is :: list.reverse() try: for x in list: "do something with x" finally: list.reverse() This has the disadvantage that while you are in the loop, the list is temporarily reversed. If you don't like this, you can make a copy. This appears expensive but is actually faster than other solutions:: rev = list[:] rev.reverse() for x in rev: If it's not a list, a more general but slower solution is:: for i in range(len(sequence)-1, -1, -1): x = sequence[i] A more elegant solution, is to define a class which acts as a sequence and yields the elements in reverse order (solution due to Steve Majewski):: class Rev: def __init__(self, seq): self.forw = seq def __len__(self): return len(self.forw) def __getitem__(self, i): return self.forw[-(i + 1)] You can now simply write:: for x in Rev(list): Unfortunately, this solution is slowest of all, due to the method call overhead. With Python 2.3, you can use an extended slice syntax:: for x in sequence[::-1]: How do you remove duplicates from a list? ------------------------------------------------- See the Python Cookbook for a long discussion of many ways to do this: http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52560 If you don't mind reordering the list, sort it and then scan from the end of the list, deleting duplicates as you go:: if List: List.sort() last = List[-1] for i in range(len(List)-2, -1, -1): if last==List[i]: del List[i] else: last=List[i] If all elements of the list may be used as dictionary keys (i.e. they are all hashable) this is often faster :: d = {} for x in List: d[x]=x List = d.values() How do you make an array in Python? ---------------------------------------------------- Use a list:: ["this", 1, "is", "an", "array"] Lists are equivalent to C or Pascal arrays in their time complexity; the primary difference is that a Python list can contain objects of many different types. The ``array`` module also provides methods for creating arrays of fixed types with compact representations, but they are slower to index than lists. Also note that the Numeric extensions and others define array-like structures with various characteristics as well. To get Lisp-style linked lists, you can emulate cons cells using tuples:: lisp_list = ("like", ("this", ("example", None) ) ) If mutability is desired, you could use lists instead of tuples. Here the analogue of lisp car is ``lisp_list[0]`` and the analogue of cdr is ``lisp_list[1]``. Only do this if you're sure you really need to, because it's usually a lot slower than using Python lists. How do I create a multidimensional list? --------------------------------------------------------------- You probably tried to make a multidimensional array like this:: A = [[None] * 2] * 3 This looks correct if you print it:: >>> A [[None, None], [None, None], [None, None]] But when you assign a value, it shows up in multiple places: >>> A[0][0] = 5 >>> A [[5, None], [5, None], [5, None]] The reason is that replicating a list with ``*`` doesn't create copies, it only creates references to the existing objects. The ``*3`` creates a list containing 3 references to the same list of length two. Changes to one row will show in all rows, which is almost certainly not what you want. The suggested approach is to create a list of the desired length first and then fill in each element with a newly created list:: A = [None]*3 for i in range(3): A[i] = [None] * 2 This generates a list containing 3 different lists of length two. You can also use a list comprehension:: w,h = 2,3 A = [ [None]*w for i in range(h) ] Or, you can use an extension that provides a matrix datatype; `Numeric Python `_ is the best known. How do I apply a method to a sequence of objects? -------------------------------------------------------------------------- Use a list comprehension:: result = [obj.method() for obj in List] More generically, you can try the following function:: def method_map(objects, method, arguments): """method_map([a,b], "meth", (1,2)) gives [a.meth(1,2), b.meth(1,2)]""" nobjects = len(objects) methods = map(getattr, objects, [method]*nobjects) return map(apply, methods, [arguments]*nobjects) Dictionaries ================== How can I get a dictionary to display its keys in a consistent order? ----------------------------------------------------------------------------- You can't. Dictionaries store their keys in an unpredictable order, so the display order of a dictionary's elements will be similarly unpredictable. This can be frustrating if you want to save a printable version to a file, make some changes and then compare it with some other printed dictionary. In this case, use the ``pprint`` module to pretty-print the dictionary; the items will be presented in order sorted by the key. A more complicated solution is to subclass ``UserDict.UserDict`` to create a ``SortedDict`` class that prints itself in a predictable order. Here's one simpleminded implementation of such a class:: import UserDict, string class SortedDict(UserDict.UserDict): def __repr__(self): result = [] append = result.append keys = self.data.keys() keys.sort() for k in keys: append("%s: %s" % (`k`, `self.data[k]`)) return "{%s}" % string.join(result, ", ") ___str__ = __repr__ This will work for many common situations you might encounter, though it's far from a perfect solution. The largest flaw is that if some values in the dictionary are also dictionaries, their values won't be presented in any particular order. I want to do a complicated sort: can you do a Schwartzian Transform in Python? -------------------------------------------------------------------------------------- Yes, it's quite simple with list comprehensions. The technique, attributed to Randal Schwartz of the Perl community, sorts the elements of a list by a metric which maps each element to its "sort value". To sort a list of strings by their uppercase values:: tmp1 = [ (x.upper(), x) for x in L ] # Schwartzian transform tmp1.sort() Usorted = [ x[1] for x in tmp1 ] To sort by the integer value of a subfield extending from positions 10-15 in each string:: tmp2 = [ (int(s[10:15]), s) for s in L ] # Schwartzian transform tmp2.sort() Isorted = [ x[1] for x in tmp2 ] Note that Isorted may also be computed by :: def intfield(s): return int(s[10:15]) def Icmp(s1, s2): return cmp(intfield(s1), intfield(s2)) Isorted = L[:] Isorted.sort(Icmp) but since this method calls ``intfield()`` many times for each element of L, it is slower than the Schwartzian Transform. How can I sort one list by values from another list? ------------------------------------------------------------ Merge them into a single list of tuples, sort the resulting list, and then pick out the element you want. :: >>> list1 = ["what", "I'm", "sorting", "by"] >>> list2 = ["something", "else", "to", "sort"] >>> pairs = zip(list1, list2) >>> pairs [('what', 'something'), ("I'm", 'else'), ('sorting', 'to'), ('by', 'sort')] >>> pairs.sort() >>> result = [ x[1] for x in pairs ] >>> result ['else', 'sort', 'to', 'something'] An alternative for the last step is:: result = [] for p in pairs: result.append(p[1]) If you find this more legible, you might prefer to use this instead of the final list comprehension. However, it is almost twice as slow for long lists. Why? First, the ``append()`` operation has to reallocate memory, and while it uses some tricks to avoid doing that each time, it still has to do it occasionally, and that costs quite a bit. Second, the expression "result.append" requires an extra attribute lookup, and third, there's a speed reduction from having to make all those function calls. Objects ============= What is a class? ------------------------ A class is the particular object type created by executing a class statement. Class objects are used as templates to create instance objects, which embody both the data (attributes) and code (methods) specific to a datatype. A class can be based on one or more other classes, called its base class(es). It then inherits the attributes and methods of its base classes. This allows an object model to be successively refined by inheritance. You might have a generic ``Mailbox`` class that provides basic accessor methods for a mailbox, and subclasses such as ``MboxMailbox``, ``MaildirMailbox``, ``OutlookMailbox`` that handle various specific mailbox formats. What is a method? ------------------------- A method is a function on some object ``x`` that you normally call as ``x.name(arguments...)``. Methods are defined as functions inside the class definition:: class C: def meth (self, arg): return arg*2 + self.attribute What is self? --------------------- Self is merely a conventional name for the first argument of a method. A method defined as ``meth(self, a, b, c)`` should be called as ``x.meth(a, b, c)`` for some instance ``x`` of the class in which the definition occurs; the called method will think it is called as ``meth(x, a, b, c)``. See also `Why must 'self' be used explicitly in method definitions and calls? `_ How do I check if an object is an instance of a given class or of a subclass of it? ------------------------------------------------------------------------------------------- Use the built-in function ``isinstance(obj, cls)``. You can check if an object is an instance of any of a number of classes by providing a tuple instead of a single class, e.g. ``isinstance(obj, (class1, class2, ...))``, and can also check whether an object is one of Python's built-in types, e.g. ``isinstance(obj, str)`` or ``isinstance(obj, (int, long, float, complex))``. Note that most programs do not use ``isinstance()`` on user-defined classes very often. If you are developing the classes yourself, a more proper object-oriented style is to define methods on the classes that encapsulate a particular behaviour, instead of checking the object's class and doing a different thing based on what class it is. For example, if you have a function that does something:: def search (obj): if isinstance(obj, Mailbox): # ... code to search a mailbox elif isinstance(obj, Document): # ... code to search a document elif ... A better approach is to define a ``search()`` method on all the classes and just call it:: class Mailbox: def search(self): # ... code to search a mailbox class Document: def search(self): # ... code to search a document obj.search() What is delegation? --------------------------- Delegation is an object oriented technique (also called a design pattern). Let's say you have an object ``x`` and want to change the behaviour of just one of its methods. You can create a new class that provides a new implementation of the method you're interested in changing and delegates all other methods to the corresponding method of ``x``. Python programmers can easily implement delegation. For example, the following class implements a class that behaves like a file but converts all written data to uppercase:: class UpperOut: def __init__(self, outfile): self.__outfile = outfile def write(self, s): self.__outfile.write(s.upper()) def __getattr__(self, name): return getattr(self.__outfile, name) Here the ``UpperOut`` class redefines the ``write()`` method to convert the argument string to uppercase before calling the underlying ``self.__outfile.write()`` method. All other methods are delegated to the underlying ``self.__outfile`` object. The delegation is accomplished via the ``__getattr__`` method; consult `the language reference <../../doc/ref/attribute-access.html>`_ for more information about controlling attribute access. Note that for more general cases delegation can get trickier. When attributes must be set as well as retrieved, the class must define a ``__settattr__`` method too, and it must do so carefully. The basic implementation of __setattr__ is roughly equivalent to the following:: class X: ... def __setattr__(self, name, value): self.__dict__[name] = value ... Most __setattr__ implementations must modify self.__dict__ to store local state for self without causing an infinite recursion. How do I call a method defined in a base class from a derived class that overrides it? ---------------------------------------------------------------------------------------------- If you're using new-style classes, use the built-in ``super()`` function:: class Derived(Base): def meth (self): super(Derived, self).meth() If you're using classic classes: For a class definition such as ``class Derived(Base): ...`` you can call method ``meth()`` defined in ``Base`` (or one of ``Base``'s base classes) as ``Base.meth(self, arguments...)``. Here, ``Base.meth`` is an unbound method, so you need to provide the ``self`` argument. How can I organize my code to make it easier to change the base class? ------------------------------------------------------------------------------ You could define an alias for the base class, assign the real base class to it before your class definition, and use the alias throughout your class. Then all you have to change is the value assigned to the alias. Incidentally, this trick is also handy if you want to decide dynamically (e.g. depending on availability of resources) which base class to use. Example:: BaseAlias = class Derived(BaseAlias): def meth(self): BaseAlias.meth(self) ... How do I create static class data and static class methods? ------------------------------------------------------------------- Static data (in the sense of C++ or Java) is easy; static methods (again in the sense of C++ or Java) are not supported directly. For static data, simply define a class attribute. To assign a new value to the attribute, you have to explicitly use the class name in the assignment:: class C: count = 0 # number of times C.__init__ called def __init__(self): C.count = C.count + 1 def getcount(self): return C.count # or return self.count ``c.count`` also refers to ``C.count`` for any ``c`` such that ``isinstance(c, C)`` holds, unless overridden by ``c`` itself or by some class on the base-class search path from ``c.__class__`` back to ``C``. Caution: within a method of C, an assignment like ``self.count = 42`` creates a new and unrelated instance vrbl named "count" in ``self``'s own dict. Rebinding of a class-static data name must always specify the class whether inside a method or not:: C.count = 314 Static methods are possible when you're using new-style classes:: class C: def static(arg1, arg2, arg3): # No 'self' parameter! ... static = staticmethod(static) However, a far more straightforward way to get the effect of a static method is via a simple module-level function:: def getcount(): return C.count If your code is structured so as to define one class (or tightly related class hierarchy) per module, this supplies the desired encapsulation. How can I overload constructors (or methods) in Python? --------------------------------------------------------------- This answer actually applies to all methods, but the question usually comes up first in the context of constructors. In C++ you'd write :: class C { C() { cout << "No arguments\n"; } C(int i) { cout << "Argument is " << i << "\n"; } } in Python you have to write a single constructor that catches all cases using default arguments. For example:: class C: def __init__(self, i=None): if i is None: print "No arguments" else: print "Argument is", i This is not entirely equivalent, but close enough in practice. You could also try a variable-length argument list, e.g. :: def __init__(self, *args): .... The same approach works for all method definitions. I try to use __spam and I get an error about _SomeClassName__spam. -------------------------------------------------------------------------- Variables with double leading underscore are "mangled" to provide a simple but effective way to define class private variables. Any identifier of the form ``__spam`` (at least two leading underscores, at most one trailing underscore) is textually replaced with ``_classname__spam``, where ``classname`` is the current class name with any leading underscores stripped. This doesn't guarantee privacy: an outside user can still deliberately access the "_classname__spam" attribute, and private values are visible in the object's ``__dict__``. Many Python programmers never bother to use private variable names at all. My class defines __del__ but it is not called when I delete the object. ------------------------------------------------------------------------------- There are several possible reasons for this. The del statement does not necessarily call __del__ -- it simply decrements the object's reference count, and if this reaches zero __del__ is called. If your data structures contain circular links (e.g. a tree where each child has a parent reference and each parent has a list of children) the reference counts will never go back to zero. Once in a while Python runs an algorithm to detect such cycles, but the garbage collector might run some time after the last reference to your data structure vanishes, so your __del__ method may be called at an inconvenient and random time. This is inconvenient if you're trying to reproduce a problem. Worse, the order in which object's __del__ methods are executed is arbitrary. You can run ``gc.collect()`` to force a collection, but there *are* pathological cases where objects will never be collected. Despite the cycle collector, it's still a good idea to define an explicit ``close()`` method on objects to be called whenever you're done with them. The ``close()`` method can then remove attributes that refer to subobjecs. Don't call ``__del__`` directly -- ``__del__`` should call ``close()`` and ``close()`` should make sure that it can be called more than once for the same object. Another way to avoid cyclical references is to use the "weakref" module, which allows you to point to objects without incrementing their reference count. Tree data structures, for instance, should use weak references for their parent and sibling references (if they need them!). If the object has ever been a local variable in a function that caught an expression in an except clause, chances are that a reference to the object still exists in that function's stack frame as contained in the stack trace. Normally, calling ``sys.exc_clear()`` will take care of this by clearing the last recorded exception. Finally, if your __del__ method raises an exception, a warning message is printed to sys.stderr. How do I get a list of all instances of a given class? -------------------------------------------------------------- Python does not keep track of all instances of a class (or of a built-in type). You can program the class's constructor to keep track of all instances by keeping a list of weak references to each instance. Modules ============= How do I create a .pyc file? ------------------------------------- When a module is imported for the first time (or when the source is more recent than the current compiled file) a ``.pyc`` file containing the compiled code should be created in the same directory as the ``.py`` file. One reason that a ``.pyc`` file may not be created is permissions problems with the directory. This can happen, for example, if you develop as one user but run as another, such as if you are testing with a web server. Creation of a .pyc file is automatic if you're importing a module and Python has the ability (permissions, free space, etc...) to write the compiled module back to the directory. Running Python on a top level script is not considered an import and no ``.pyc`` will be created. For example, if you have a top-level module ``abc.py`` that imports another module ``xyz.py``, when you run abc, ``xyz.pyc`` will be created since xyz is imported, but no ``abc.pyc`` file will be created since ``abc.py`` isn't being imported. If you need to create abc.pyc -- that is, to create a .pyc file for a module that is not imported -- you can, using the py_compile and compileall modules. The ``py_compile`` module can manually compile any module. One way is to use the ``compile()`` function in that module interactively:: >>> import py_compile >>> py_compile.compile('abc.py') This will write the ``.pyc`` to the same location as ``abc.py`` (or you can override that with the optional parameter ``cfile``). You can also automatically compile all files in a directory or directories using the ``compileall`` module. You can do it from the shell prompt by running ``compileall.py`` and providing the path of a directory containing Python files to compile:: python compileall.py . How do I find the current module name? --------------------------------------------- A module can find out its own module name by looking at the predefined global variable ``__name__``. If this has the value '__main__', the program is running as a script. Many modules that are usually used by importing them also provide a command-line interface or a self-test, and only execute this code after checking ``__name__``:: def main(): print 'Running test...' ... if __name__ == '__main__': main() How can I have modules that mutually import each other? --------------------------------------------------------------- Suppose you have the following modules: foo.py:: from bar import bar_var foo_var=1 bar.py:: from foo import foo_var bar_var=2 The problem is that the interpreter will perform the following steps: * main imports foo * Empty globals for foo are created * foo is compiled and starts executing * foo imports bar * Empty globals for bar are created * bar is compiled and starts executing * bar imports foo (which is a no-op since there already is a module named foo) * bar.foo_var = foo.foo_var The last step fails, because Python isn't done with interpreting ``foo`` yet and the global symbol dictionary for ``foo`` is still empty. The same thing happens when you use ``import foo``, and then try to access ``foo.foo_var`` in global code. There are (at least) three possible workarounds for this problem. Guido van Rossum recommends avoiding all uses of ``from import ...``, and placing all code inside functions. Initializations of global variables and class variables should use constants or built-in functions only. This means everything from an imported module is referenced as ``.``. Jim Roskind suggests performing steps in the following order in each module: * exports (globals, functions, and classes that don't need imported base classes) * ``import`` statements * active code (including globals that are initialized from imported values). van Rossum doesn't like this approach much because the imports appear in a strange place, but it does work. Matthias Urlichs recommends restructuring your code so that the recursive import is not necessary in the first place. These solutions are not mutually exclusive. __import__('x.y.z') returns ; how do I get z? ----------------------------------------------------------------------- Try:: __import__('x.y.z').y.z For more realistic situations, you may have to do something like :: m = __import__(s) for i in s.split(".")[1:]: m = getattr(m, i) When I edit an imported module and reimport it, the changes don't show up. Why does this happen? -------------------------------------------------------------------------------------------------------------------------------------------- For reasons of efficiency as well as consistency, Python only reads the module file on the first time a module is imported. If it didn't, in a program consisting of many modules where each one imports the same basic module, the basic module would be parsed and re-parsed many times. To force rereading of a changed module, do this:: import modname reload(modname) Warning: this technique is not 100% fool-proof. In particular, modules containing statements like :: from modname import some_objects will continue to work with the old version of the imported objects. If the module contains class definitions, existing class instances will *not* be updated to use the new class definition. This can result in the following paradoxical behaviour:: >>> import cls >>> c = cls.C() # Create an instance of C >>> reload(cls) >>> isinstance(c, cls.C) # isinstance is false?!? False The nature of the problem is made clear if you print out the class objects: >>> c.__class__ >>> cls.C python-defaults-2.7.12/faq/windows.ht0000664000000000000000000006043612057417145014436 0ustar Title: Python Windows FAQ Content-type: text/x-rst ==================================== Python Windows FAQ ==================================== :Date: $Date: 2005-07-26 07:21:45 -0600 (Tue, 26 Jul 2005) $ :Version: $Revision: 8295 $ :Web site: http://www.python.org/ .. contents:: .. sectnum:: How do I run a Python program under Windows? ---------------------------------------------------- This is not necessarily a straightforward question. If you are already familiar with running programs from the Windows command line then everything will seem obvious; otherwise, you might need a little more guidance. There are also differences between Windows 95, 98, NT, ME, 2000 and XP which can add to the confusion. Unless you use some sort of integrated development environment, you will end up *typing* Windows commands into what is variously referred to as a "DOS window" or "Command prompt window". Usually you can create such a window from your Start menu; under Windows 2000 the menu selection is "Start | Programs | Accessories | Command Prompt". You should be able to recognize when you have started such a window because you will see a Windows "command prompt", which usually looks like this:: C:\> The letter may be different, and there might be other things after it, so you might just as easily see something like:: D:\Steve\Projects\Python> depending on how your computer has been set up and what else you have recently done with it. Once you have started such a window, you are well on the way to running Python programs. You need to realize that your Python scripts have to be processed by another program called the Python interpreter. The interpreter reads your script, compiles it into bytecodes, and then executes the bytecodes to run your program. So, how do you arrange for the interpreter to handle your Python? First, you need to make sure that your command window recognises the word "python" as an instruction to start the interpreter. If you have opened a command window, you should try entering the command ``python`` and hitting return. You should then see something like:: Python 2.2 (#28, Dec 21 2001, 12:21:22) [MSC 32 bit (Intel)] on win32 Type "help", "copyright", "credits" or "license" for more information. >>> You have started the interpreter in "interactive mode". That means you can enter Python statements or expressions interactively and have them executed or evaluated while you wait. This is one of Python's strongest features. Check it by entering a few expressions of your choice and seeing the results:: >>> print "Hello" Hello >>> "Hello" * 3 HelloHelloHello Many people use the interactive mode as a convenient yet highly programmable calculator. When you want to end your interactive Python session, hold the Ctrl key down while you enter a Z, then hit the "Enter" key to get back to your Windows command prompt. You may also find that you have a Start-menu entry such as "Start | Programs | Python 2.2 | Python (command line)" that results in you seeing the ``>>>`` prompt in a new window. If so, the window will disappear after you enter the Ctrl-Z character; Windows is running a single "python" command in the window, and closes it when you terminate the interpreter. If the ``python`` command, instead of displaying the interpreter prompt ``>>>``, gives you a message like:: 'python' is not recognized as an internal or external command, operable program or batch file. or:: Bad command or filename then you need to make sure that your computer knows where to find the Python interpreter. To do this you will have to modify a setting called PATH, which is a list of directories where Windows will look for programs. You should arrange for Python's installation directory to be added to the PATH of every command window as it starts. If you installed Python fairly recently then the command :: dir C:\py* will probably tell you where it is installed; the usual location is something like ``C:\Python23``. Otherwise you will be reduced to a search of your whole disk ... use "Tools | Find" or hit the "Search" button and look for "python.exe". Supposing you discover that Python is installed in the ``C:\Python23`` directory (the default at the time of writing), you should make sure that entering the command :: c:\Python23\python starts up the interpreter as above (and don't forget you'll need a "CTRL-Z" and an "Enter" to get out of it). Once you have verified the directory, you need to add it to the start-up routines your computer goes through. For older versions of Windows the easiest way to do this is to edit the ``C:\AUTOEXEC.BAT`` file. You would want to add a line like the following to ``AUTOEXEC.BAT``:: PATH C:\Python23;%PATH% For Windows NT, 2000 and (I assume) XP, you will need to add a string such as :: ;C:\Python23 to the current setting for the PATH environment variable, which you will find in the properties window of "My Computer" under the "Advanced" tab. Note that if you have sufficient privilege you might get a choice of installing the settings either for the Current User or for System. The latter is preferred if you want everybody to be able to run Python on the machine. If you aren't confident doing any of these manipulations yourself, ask for help! At this stage you may want to reboot your system to make absolutely sure the new setting has taken effect. You probably won't need to reboot for Windows NT, XP or 2000. You can also avoid it in earlier versions by editing the file ``C:\WINDOWS\COMMAND\CMDINIT.BAT`` instead of ``AUTOEXEC.BAT``. You should now be able to start a new command window, enter ``python`` at the ``C:>`` (or whatever) prompt, and see the ``>>>`` prompt that indicates the Python interpreter is reading interactive commands. Let's suppose you have a program called ``pytest.py`` in directory ``C:\Steve\Projects\Python``. A session to run that program might look like this:: C:\> cd \Steve\Projects\Python C:\Steve\Projects\Python> python pytest.py Because you added a file name to the command to start the interpreter, when it starts up it reads the Python script in the named file, compiles it, executes it, and terminates, so you see another ``C:\>`` prompt. You might also have entered :: C:\> python \Steve\Projects\Python\pytest.py if you hadn't wanted to change your current directory. Under NT, 2000 and XP you may well find that the installation process has also arranged that the command ``pytest.py`` (or, if the file isn't in the current directory, ``C:\Steve\Projects\Python\pytest.py``) will automatically recognize the ".py" extension and run the Python interpreter on the named file. Using this feature is fine, but *some* versions of Windows have bugs which mean that this form isn't exactly equivalent to using the interpreter explicitly, so be careful. The important things to remember are: 1. Start Python from the Start Menu, or make sure the PATH is set correctly so Windows can find the Python interpreter. :: python should give you a '>>>" prompt from the Python interpreter. Don't forget the CTRL-Z and ENTER to terminate the interpreter (and, if you started the window from the Start Menu, make the window disappear). 2. Once this works, you run programs with commands:: python {program-file} 3. When you know the commands to use you can build Windows shortcuts to run the Python interpreter on any of your scripts, naming particular working directories, and adding them to your menus. Take a look at :: python --help if your needs are complex. 4. Interactive mode (where you see the ``>>>`` prompt) is best used for checking that individual statements and expressions do what you think they will, and for developing code by experiment. How do I make python scripts executable? ---------------------------------------------- On Windows 2000, the standard Python installer already associates the .py extension with a file type (Python.File) and gives that file type an open command that runs the interpreter (D:\\Program Files\\Python\\python.exe "%1" %*). This is enough to make scripts executable from the command prompt as 'foo.py'. If you'd rather be able to execute the script by simple typing 'foo' with no extension you need to add .py to the PATHEXT environment variable. On Windows NT, the steps taken by the installer as described above allow you to run a script with 'foo.py', but a longtime bug in the NT command processor prevents you from redirecting the input or output of any script executed in this way. This is often important. The incantation for making a Python script executable under WinNT is to give the file an extension of .cmd and add the following as the first line:: @setlocal enableextensions & python -x %~f0 %* & goto :EOF Why does Python sometimes take so long to start? ------------------------------------------------------- Usually Python starts very quickly on Windows, but occasionally there are bug reports that Python suddenly begins to take a long time to start up. This is made even more puzzling because Python will work fine on other Windows systems which appear to be configured identically. The problem may be caused by a misconfiguration of virus checking software on the problem machine. Some virus scanners have been known to introduce startup overhead of two orders of magnitude when the scanner is configured to monitor all reads from the filesystem. Try checking the configuration of virus scanning software on your systems to ensure that they are indeed configured identically. McAfee, when configured to scan all file system read activity, is a particular offender. Where is Freeze for Windows? ------------------------------------ "Freeze" is a program that allows you to ship a Python program as a single stand-alone executable file. It is *not* a compiler; your programs don't run any faster, but they are more easily distributable, at least to platforms with the same OS and CPU. Read the README file of the freeze program for more disclaimers. You can use freeze on Windows, but you must download the source tree (see http://www.python.org/download/download_source.html). The freeze program is in the ``Tools\freeze`` subdirectory of the source tree. You need the Microsoft VC++ compiler, and you probably need to build Python. The required project files are in the PCbuild directory. Is a ``*.pyd`` file the same as a DLL? ------------------------------------------ Yes, .pyd files are dll's, but there are a few differences. If you have a DLL named ``foo.pyd``, then it must have a function initfoo(). You can then write Python "import foo", and Python will search for foo.pyd (as well as foo.py, foo.pyc) and if it finds it, will attempt to call initfoo() to initialize it. You do not link your .exe with foo.lib, as that would cause Windows to require the DLL to be present. Note that the search path for foo.pyd is PYTHONPATH, not the same as the path that Windows uses to search for foo.dll. Also, foo.pyd need not be present to run your program, whereas if you linked your program with a dll, the dll is required. Of course, foo.pyd is required if you want to say "import foo". In a DLL, linkage is declared in the source code with __declspec(dllexport). In a .pyd, linkage is defined in a list of available functions. How can I embed Python into a Windows application? ---------------------------------------------------------- Embedding the Python interpreter in a Windows app can be summarized as follows: 1. Do _not_ build Python into your .exe file directly. On Windows, Python must be a DLL to handle importing modules that are themselves DLL's. (This is the first key undocumented fact.) Instead, link to pythonNN.dll; it is typically installed in ``C:\Windows\System``. NN is the Python version, a number such as "23" for Python 2.3. You can link to Python statically or dynamically. Linking statically means linking against pythonNN.lib, while dynamically linking means linking against pythonNN.dll. The drawback to dynamic linking is that your app won't run if pythonNN.dll does not exist on your system. (General note: pythonNN.lib is the so-called "import lib" corresponding to python.dll. It merely defines symbols for the linker.) Linking dynamically greatly simplifies link options; everything happens at run time. Your code must load pythonNN.dll using the Windows LoadLibraryEx() routine. The code must also use access routines and data in pythonNN.dll (that is, Python's C API's) using pointers obtained by the Windows GetProcAddress() routine. Macros can make using these pointers transparent to any C code that calls routines in Python's C API. Borland note: convert pythonNN.lib to OMF format using Coff2Omf.exe first. 2. If you use SWIG, it is easy to create a Python "extension module" that will make the app's data and methods available to Python. SWIG will handle just about all the grungy details for you. The result is C code that you link *into* your .exe file (!) You do _not_ have to create a DLL file, and this also simplifies linking. 3. SWIG will create an init function (a C function) whose name depends on the name of the extension module. For example, if the name of the module is leo, the init function will be called initleo(). If you use SWIG shadow classes, as you should, the init function will be called initleoc(). This initializes a mostly hidden helper class used by the shadow class. The reason you can link the C code in step 2 into your .exe file is that calling the initialization function is equivalent to importing the module into Python! (This is the second key undocumented fact.) 4. In short, you can use the following code to initialize the Python interpreter with your extension module. :: #include "python.h" ... Py_Initialize(); // Initialize Python. initmyAppc(); // Initialize (import) the helper class. PyRun_SimpleString("import myApp") ; // Import the shadow class. 5. There are two problems with Python's C API which will become apparent if you use a compiler other than MSVC, the compiler used to build pythonNN.dll. Problem 1: The so-called "Very High Level" functions that take FILE * arguments will not work in a multi-compiler environment because each compiler's notion of a struct FILE will be different. From an implementation standpoint these are very _low_ level functions. Problem 2: SWIG generates the following code when generating wrappers to void functions:: Py_INCREF(Py_None); _resultobj = Py_None; return _resultobj; Alas, Py_None is a macro that expands to a reference to a complex data structure called _Py_NoneStruct inside pythonNN.dll. Again, this code will fail in a mult-compiler environment. Replace such code by:: return Py_BuildValue(""); It may be possible to use SWIG's %typemap command to make the change automatically, though I have not been able to get this to work (I'm a complete SWIG newbie). 6. Using a Python shell script to put up a Python interpreter window from inside your Windows app is not a good idea; the resulting window will be independent of your app's windowing system. Rather, you (or the wxPythonWindow class) should create a "native" interpreter window. It is easy to connect that window to the Python interpreter. You can redirect Python's i/o to _any_ object that supports read and write, so all you need is a Python object (defined in your extension module) that contains read() and write() methods. How do I use Python for CGI? ------------------------------------------------------- On the Microsoft IIS server or on the Win95 MS Personal Web Server you set up Python in the same way that you would set up any other scripting engine. Run regedt32 and go to:: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\W3SVC\Parameters\ScriptMap and enter the following line (making any specific changes that your system may need):: .py :REG_SZ: c:\\python.exe -u %s %s This line will allow you to call your script with a simple reference like: http://yourserver/scripts/yourscript.py provided "scripts" is an "executable" directory for your server (which it usually is by default). The "-u" flag specifies unbuffered and binary mode for stdin - needed when working with binary data. In addition, it is recommended that using ".py" may not be a good idea for the file extensions when used in this context (you might want to reserve ``*.py`` for support modules and use ``*.cgi`` or ``*.cgp`` for "main program" scripts). In order to set up Internet Information Services 5 to use Python for CGI processing, please see the following links: http://www.e-coli.net/pyiis_server.html (for Win2k Server) http://www.e-coli.net/pyiis.html (for Win2k pro) Configuring Apache is much simpler. In the Apache configuration file ``httpd.conf``, add the following line at the end of the file:: ScriptInterpreterSource Registry Then, give your Python CGI-scripts the extension .py and put them in the cgi-bin directory. How do I keep editors from inserting tabs into my Python source? ------------------------------------------------------------------ The FAQ does not recommend using tabs, and `the Python style guide `_ recommends 4 spaces for distributed Python code; this is also the Emacs python-mode default. Under any editor, mixing tabs and spaces is a bad idea. MSVC is no different in this respect, and is easily configured to use spaces: Take Tools -> Options -> Tabs, and for file type "Default" set "Tab size" and "Indent size" to 4, and select the "Insert spaces" radio button. If you suspect mixed tabs and spaces are causing problems in leading whitespace, run Python with the -t switch or run ``Tools/Scripts/tabnanny.py`` to check a directory tree in batch mode. How do I check for a keypress without blocking? ---------------------------------------------------- Use the msvcrt module. This is a standard Windows-specific extension module. It defines a function kbhit() which checks whether a keyboard hit is present, and getch() which gets one character without echoing it. How do I emulate os.kill() in Windows? --------------------------------------------- Use win32api:: def kill(pid): """kill function for Win32""" import win32api handle = win32api.OpenProcess(1, 0, pid) return (0 != win32api.TerminateProcess(handle, 0)) Why does os.path.isdir() fail on NT shared directories? -------------------------------------------------------------- The solution appears to be always append the "\\" on the end of shared drives. :: >>> import os >>> os.path.isdir( '\\\\rorschach\\public') 0 >>> os.path.isdir( '\\\\rorschach\\public\\') 1 It helps to think of share points as being like drive letters. Example:: k: is not a directory k:\ is a directory k:\media is a directory k:\media\ is not a directory The same rules apply if you substitute "k:" with "\\conky\foo":: \\conky\foo is not a directory \\conky\foo\ is a directory \\conky\foo\media is a directory \\conky\foo\media\ is not a directory cgi.py (or other CGI programming) doesn't work sometimes on NT or win95! ----------------------------------------------------------------------------- Be sure you have the latest python.exe, that you are using python.exe rather than a GUI version of Python and that you have configured the server to execute :: "...\python.exe -u ..." for the CGI execution. The -u (unbuffered) option on NT and Win95 prevents the interpreter from altering newlines in the standard input and output. Without it post/multipart requests will seem to have the wrong length and binary (e.g. GIF) responses may get garbled (resulting in broken images, PDF files, and other binary downloads failing). Why doesn't os.popen() work in PythonWin on NT? ------------------------------------------------------- The reason that os.popen() doesn't work from within PythonWin is due to a bug in Microsoft's C Runtime Library (CRT). The CRT assumes you have a Win32 console attached to the process. You should use the win32pipe module's popen() instead which doesn't depend on having an attached Win32 console. Example:: import win32pipe f = win32pipe.popen('dir /c c:\\') print f.readlines() f.close() Why doesn't os.popen()/win32pipe.popen() work on Win9x? --------------------------------------------------------------- There is a bug in Win9x that prevents os.popen/win32pipe.popen* from working. The good news is there is a way to work around this problem. The Microsoft Knowledge Base article that you need to lookup is: Q150956. You will find links to the knowledge base at: http://www.microsoft.com/kb. PyRun_SimpleFile() crashes on Windows but not on Unix; why? ------------------------------------------------------------ This is very sensitive to the compiler vendor, version and (perhaps) even options. If the FILE* structure in your embedding program isn't the same as is assumed by the Python interpreter it won't work. The Python 1.5.* DLLs (``python15.dll``) are all compiled with MS VC++ 5.0 and with multithreading-DLL options (``/MD``). If you can't change compilers or flags, try using Py_RunSimpleString(). A trick to get it to run an arbitrary file is to construct a call to execfile() with the name of your file as argument. Also note that you can not mix-and-match Debug and Release versions. If you wish to use the Debug Multithreaded DLL, then your module _must_ have an "_d" appended to the base name. Importing _tkinter fails on Windows 95/98: why? ------------------------------------------------ Sometimes, the import of _tkinter fails on Windows 95 or 98, complaining with a message like the following:: ImportError: DLL load failed: One of the library files needed to run this application cannot be found. It could be that you haven't installed Tcl/Tk, but if you did install Tcl/Tk, and the Wish application works correctly, the problem may be that its installer didn't manage to edit the autoexec.bat file correctly. It tries to add a statement that changes the PATH environment variable to include the Tcl/Tk 'bin' subdirectory, but sometimes this edit doesn't quite work. Opening it with notepad usually reveals what the problem is. (One additional hint, noted by David Szafranski: you can't use long filenames here; e.g. use ``C:\PROGRA~1\Tcl\bin`` instead of ``C:\Program Files\Tcl\bin``.) How do I extract the downloaded documentation on Windows? ------------------------------------------------------------ Sometimes, when you download the documentation package to a Windows machine using a web browser, the file extension of the saved file ends up being .EXE. This is a mistake; the extension should be .TGZ. Simply rename the downloaded file to have the .TGZ extension, and WinZip will be able to handle it. (If your copy of WinZip doesn't, get a newer one from http://www.winzip.com.) Missing cw3215mt.dll (or missing cw3215.dll) ---------------------------------------------------- Sometimes, when using Tkinter on Windows, you get an error that cw3215mt.dll or cw3215.dll is missing. Cause: you have an old Tcl/Tk DLL built with cygwin in your path (probably ``C:\Windows``). You must use the Tcl/Tk DLLs from the standard Tcl/Tk installation (Python 1.5.2 comes with one). Warning about CTL3D32 version from installer ---------------------------------------------------- The Python installer issues a warning like this:: This version uses ``CTL3D32.DLL`` whitch is not the correct version. This version is used for windows NT applications only. [Tim Peters] This is a Microsoft DLL, and a notorious source of problems. The message means what it says: you have the wrong version of this DLL for your operating system. The Python installation did not cause this -- something else you installed previous to this overwrote the DLL that came with your OS (probably older shareware of some sort, but there's no way to tell now). If you search for "CTL3D32" using any search engine (AltaVista, for example), you'll find hundreds and hundreds of web pages complaining about the same problem with all sorts of installation programs. They'll point you to ways to get the correct version reinstalled on your system (since Python doesn't cause this, we can't fix it). David A Burton has written a little program to fix this. Go to http://www.burtonsys.com/download.html and click on "ctl3dfix.zip" python-defaults-2.7.12/faq/gui.ht0000664000000000000000000001405312057417145013522 0ustar Title: Graphic User Interface FAQ Content-type: text/x-rst ==================================== Graphic User Interface FAQ ==================================== :Date: $Date: 2003-09-04 18:00:23 -0600 (Thu, 04 Sep 2003) $ :Version: $Revision: 6607 $ :Web site: http://www.python.org/ .. contents:: .. sectnum:: General GUI Questions ============================ What platform-independent GUI toolkits exist for Python? ---------------------------------------------------------------- Depending on what platform(s) you are aiming at, there are several. Tkinter '''''''''''' Standard builds of Python include an object-oriented interface to the Tcl/Tk widget set, called Tkinter. This is probably the easiest to install and use. For more info about Tk, including pointers to the source, see the Tcl/Tk home page at http://www.tcl.tk. Tcl/Tk is fully portable to the MacOS, Windows, and Unix platforms. wxWindows ''''''''''''' wxWindows is a portable GUI class library written in C++ that's a portable interface to various platform-specific libraries; wxPython is a Python interface to wxWindows. wxWindows supports Windows and MacOS; on Unix variants, it supports both GTk+ and Motif toolkits. wxWindows preserves the look and feel of the underlying graphics toolkit, and there is quite a rich widget set and collection of GDI classes. See `the wxWindows page `_ for more details. `wxPython `_ is an extension module that wraps many of the wxWindows C++ classes, and is quickly gaining popularity amongst Python developers. You can get wxPython as part of the source or CVS distribution of wxWindows, or directly from its home page. Qt '''''' There are bindings available for the Qt toolkit (`PyQt `_) and for KDE (PyKDE). If you're writing open source software, you don't need to pay for PyQt, but if you want to write proprietary applications, you must buy a PyQt license from `Riverbank Computing `_ and a Qt license from `Trolltech `_. GTk+ ''''''''''' PyGTk bindings for the `GTk+ toolkit `_ have been implemented by by James Henstridge; see ftp://ftp.gtk.org/pub/gtk/python/. FLTK ''''''''''' Python bindings for `the FLTK toolkit `_, a simple yet powerful and mature cross-platform windowing system, are available from `the PyFLTK project `_. FOX ''''''''''' A wrapper for `the FOX toolkit `_ called `FXpy `_ is available. FOX supports both Unix variants and Windows. OpenGL ''''''''''''' For OpenGL bindings, see `PyOpenGL `_. What platform-specific GUI toolkits exist for Python? ---------------------------------------------------------------- `The Mac port `_ by Jack Jansen has a rich and ever-growing set of modules that support the native Mac toolbox calls. The port includes support for MacOS9 and MacOS X's Carbon libraries. By installing the `PyObjc Objective-C bridge `_, Python programs can use MacOS X's Cocoa libraries. See the documentation that comes with the Mac port. `Pythonwin `_ by Mark Hammond includes an interface to the Microsoft Foundation Classes and a Python programming environment using it that's written mostly in Python. Tkinter questions ===================== How do I freeze Tkinter applications? --------------------------------------------- Freeze is a tool to create stand-alone applications. When freezing Tkinter applications, the applications will not be truly stand-alone, as the application will still need the Tcl and Tk libraries. One solution is to ship the application with the tcl and tk libraries, and point to them at run-time using the TCL_LIBRARY and TK_LIBRARY environment variables. To get truly stand-alone applications, the Tcl scripts that form the library have to be integrated into the application as well. One tool supporting that is SAM (stand-alone modules), which is part of the Tix distribution (http://tix.mne.com). Build Tix with SAM enabled, perform the appropriate call to Tclsam_init etc inside Python's Modules/tkappinit.c, and link with libtclsam and libtksam (you might include the Tix libraries as well). Can I have Tk events handled while waiting for I/O? ----------------------------------------------------------- Yes, and you don't even need threads! But you'll have to restructure your I/O code a bit. Tk has the equivalent of Xt's XtAddInput() call, which allows you to register a callback function which will be called from the Tk mainloop when I/O is possible on a file descriptor. Here's what you need:: from Tkinter import tkinter tkinter.createfilehandler(file, mask, callback) The file may be a Python file or socket object (actually, anything with a fileno() method), or an integer file descriptor. The mask is one of the constants tkinter.READABLE or tkinter.WRITABLE. The callback is called as follows:: callback(file, mask) You must unregister the callback when you're done, using :: tkinter.deletefilehandler(file) Note: since you don't know *how many bytes* are available for reading, you can't use the Python file object's read or readline methods, since these will insist on reading a predefined number of bytes. For sockets, the recv() or recvfrom() methods will work fine; for other files, use os.read(file.fileno(), maxbytecount). I can't get key bindings to work in Tkinter: why? --------------------------------------------------- An often-heard complaint is that event handlers bound to events with the bind() method don't get handled even when the appropriate key is pressed. The most common cause is that the widget to which the binding applies doesn't have "keyboard focus". Check out the Tk documentation for the focus command. Usually a widget is given the keyboard focus by clicking in it (but not for labels; see the takefocus option). python-defaults-2.7.12/README.derivatives0000664000000000000000000000273612057417145015043 0ustar How to change a list of supported Python versions? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Open debian/debian_defaults file and change `supported-versions` variable * Open debian/control.in file and edit python-all, python-all-dev and python-all-dbg's Depends line (add or remove pythonX.Y packages) * Open debian/pyversions.py file and edit `_supported_versions` list around line 141 * Open debpython/version.py file and edit `SUPPORTED` list around line 26 How to change default Python version? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Open debian/debian_defaults file and change `default-version` variable * Open debian/rules file and edit `VER` variable (default version), `NVER` (default + 1 version) and `PVER` (default version with "python" prefix) * Open debian/pyversions.py file and edit `debian_default` variable around line 171 * Open debpython/version.py file and edit `DEFAULT` variable around line 27 How to bump minimum required Python version by dh_python2? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ * Open debpython/depends.py file and edit `MINPYCDEP` variable around line 26 How to regenerate dist_fallback file for dh_python2? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Please note that we recommend to extend this file instead (i.e. removing items from it can break other packages' dependencies) * Update pydist/sources.list file to point to your distro/suit * Remove pydist/dist_fallback file * Run `make dist_fallback` python-defaults-2.7.12/pycompile.10000664000000000000000000000452612374331373013721 0ustar .\" Man page generated from reStructuredText. . .TH PYCOMPILE 1 "" "" "" .SH NAME pycompile \- byte compile Python source files . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .INDENT 0.0 .INDENT 3.5 pycompile [\-V [X.Y][\-][A.B]] DIR_OR_FILE [\-X REGEXPR] .sp pycompile \-p PACKAGE .UNINDENT .UNINDENT .SH DESCRIPTION .sp Wrapper around Python standard library\(aqs py_compile module to byte\-compile Python files. .SH OPTIONS .INDENT 0.0 .TP .B \-\-version show program\(aqs version number and exit .TP .B \-h\fP,\fB \-\-help show this help message and exit .TP .B \-f\fP,\fB \-\-force force rebuild of byte\-code files even if timestamps are up\-to\-date .TP .B \-O byte\-compile to .pyo files .TP .B \-q\fP,\fB \-\-quiet be quiet .TP .B \-v\fP,\fB \-\-verbose turn verbose mode on .TP .BI \-p \ PACKAGE\fP,\fB \ \-\-package\fB= PACKAGE specify Debian package name whose files should be bytecompiled (combining with DIR_OR_FILE will additionally limit list of files) .TP .BI \-V \ VRANGE force private modules to be bytecompiled with Python version from given range, regardless of the default Python version in the system. If there are no other options, bytecompile all public modules for installed Python versions that match given range. VERSION_RANGE examples: .INDENT 7.0 .INDENT 3.5 .INDENT 0.0 .IP \(bu 2 \fB2.5\fP version 2.5 only .IP \(bu 2 \fB2.5\-\fP version 2.5 or newer .IP \(bu 2 \fB2.5\-2.7\fP version 2.5 or 2.6 .IP \(bu 2 \fB\-3.0\fP all supported 2.X versions .UNINDENT .UNINDENT .UNINDENT .TP .BI \-X \ REGEXPR\fP,\fB \ \-\-exclude\fB= REGEXPR exclude items that match given REGEXPR. You may use this option multiple times to build up a list of things to exclude .UNINDENT .SH AUTHOR Piotr Ożarowski, 2012-2013 .\" Generated by docutils manpage writer. . python-defaults-2.7.12/.bzrignore0000664000000000000000000000073112632016220013616 0ustar stamp-build stamp-dh_python debian/idle debian/*.debhelper.log debian/libpython-all-dbg debian/libpython-all-dev debian/libpython-dbg debian/libpython-dev debian/libpython-stdlib debian/python debian/python-all debian/python-all-dbg debian/python-all-dev debian/python-dbg debian/python-dev debian/python-doc debian/python-examples debian/python-minimal debian/python-minimal.postinst debian/python.postinst debian/python.postrm debian/python.preinst debian/python.prerm python-defaults-2.7.12/dh_python2.rst0000664000000000000000000001717712154106100014434 0ustar ============ dh_python2 ============ ----------------------------------------------------------------------------------- calculates Python dependencies, adds maintainer scripts to byte compile files, etc. ----------------------------------------------------------------------------------- :Manual section: 1 :Author: Piotr Ożarowski, 2012-2013 SYNOPSIS ======== dh_python2 -p PACKAGE [-V [X.Y][-][A.B]] DIR_OR_FILE [-X REGEXPR] DESCRIPTION =========== QUICK GUIDE FOR MAINTAINERS --------------------------- * if necessary, describe supported Python versions via X-Python-Version field in debian/control, * build-depend on python or python-all or python-all-dev (>= 2.6.6-3~), * build module/application using its standard build system, remember to build extensions for all supported Python versions (loop over ``pyversions -vr``), * install files to the *standard* locations, add `--install-layout=deb` to setup.py's install command if your package is using distutils, * add `python2` to dh's --with option, or: * `include /usr/share/cdbs/1/class/python-distutils.mk` in debian/rules and depend on `cdbs (>= 0.4.90)`, or: * call ``dh_python2`` in the `binary-*` target, * add `${python:Depends}` to Depends NOTES ----- In order to support more than one Python version in the same binary package, dh_python2 (unlike dh_pycentral and dh_pysupport) creates symlinks to all supported Python versions at build time. It means binNMU (or sourceful upload in case of architecture independent packages) is required once a list of supported Python version is changed. It's faster and more robust than its competitors, though. dependencies ~~~~~~~~~~~~ dh_python2 tries to translate Python dependencies from requires.txt file to Debian dependencies. Use debian/pydist-overrides or --no-guessing-deps option to override it if the guess is incorrect. If you want dh_python2 to generate more strict dependencies (f.e. to avoid ABI problems) create debian/python-foo.pydist file. See /usr/share/doc/python-doc/README.PyDist (provided by python-doc package) for more information. If the pydist file contains PEP386 flag or set of (uscan like) rules, dh_python2 will make the depedency versioned (version requirements are ignored by default). namespace feature ~~~~~~~~~~~~~~~~~ dh_python2 parses Egg's namespace_packages.txt files (in addition to --namespace command line argument(s)) and drops empty __init__.py files from binary package. pycompile will regenerate them at install time and pyclean will remove them at uninstall time (if they're no longer used in installed packages). It's still a good idea to provide __init__.py file in one of binary packages (even if all other packages use this feature). private dirs ~~~~~~~~~~~~ `/usr/share/foo`, `/usr/share/games/foo`, `/usr/lib/foo` and `/usr/lib/games/foo` private directories are scanned for Python files by default (where `foo` is binary package name). If your package is shipping Python files in some other directory, add another dh_python2 call in debian/rules with directory name as an argument - you can use different set of options in this call. If you need to change options (f.e. a list of supported Python versions) for a private directory that is checked by default, invoke dh_python2 with --skip-private option and add another call with a path to this directory and new options. debug packages ~~~~~~~~~~~~~~ In binary packages which name ends with `-dbg`, all files in `/usr/lib/python2.X/{site,dist}-packages/` directory that have extensions different than `so` or `h` are removed by default. Use --no-dbg-cleaning option to disable this feature. pyinstall files ~~~~~~~~~~~~~~~ Files listed in debian/pkg.pyinstall file will be installed as public modules for all requested Python versions (dh_install doesn't know about python's site- vs. dist-packages issue). Syntax: ``path/to/file [VERSION_RANGE] [NAMESPACE]`` debian directory is automatically removed from the path, so you can place your files in debian/ directory and install them from this location (if you want to install them in "debian" namespace, set NAMESPACE to debian). If NAMESPACE is set, all listed files will be installed in .../dist-packages/NAMESPACE/ directory. Examples: * ``foo.py`` installs .../dist-packages/foo.py for all supported Python versions * ``foo/bar.py 2.6-`` installs .../dist-packages/foo/bar.py for versions >= 2.6 * ``foo/bar.py spam`` installs .../dist-packages/spam/bar.py * ``debian/*.py spam.egg 2.5`` installs .../python2.5/site-packages/spam/egg/\*.py files pyremove files ~~~~~~~~~~~~~~ If you want to remove some files installed by build system (from all supported Python versions or only from a subset of these versions), add them to debian/pkg.pyremove file. Examples: * ``*.pth`` removes .pth files from .../dist-packages/ * ``bar/baz.py 2.5`` removes .../python2.5/site-packages/bar/baz.py overriding supported / default Python versions ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If you want to override system's list of supported Python versions or the default one (f.e. to build a package that includes symlinks for older version of Python or compile .py files only for given interpreter version), you can do that via `DEBPYTHON_SUPPORTED` and/or `DEBPYTHON_DEFAULT` env. variables. Example: ``2.5,2.7`` limits the list of supported Python versions to Python 2.5 and Python 2.7. OPTIONS ======= --version show program's version number and exit -h, --help show help message and exit --no-guessing-versions disable guessing other supported Python versions --no-guessing-deps disable guessing dependencies --no-dbg-cleaning do not remove any files from debug packages --no-shebang-rewrite do not rewrite shebangs --skip-private don't check private directories -v, --verbose turn verbose mode on -i, --indep act on architecture independent packages -a, --arch act on architecture dependent packages -q, --quiet be quiet -p PACKAGE, --package=PACKAGE act on the package named PACKAGE -N NO_PACKAGE, --no-package=NO_PACKAGE do not act on the specified package -V VRANGE specify list of supported Python versions. See pycompile(1) for examples -X REGEXPR, --exclude=REGEXPR exclude items that match given REGEXPR. You may use this option multiple times to build up a list of things to exclude. --compile-all compile all files from given private directory in postinst/rtupdate not just the ones provided by the package (i.e. do not pass the --package parameter to pycompile/pyclean) --depends=DEPENDS translate given requirements into Debian dependencies and add them to ${python:Depends}. Use it for missing items in requires.txt --recommends=RECOMMENDS translate given requirements into Debian dependencies and add them to ${python:Recommends} --suggests=SUGGESTS translate given requirements into Debian dependencies and add them to ${python:Suggests} --namespace use this option (multiple time if necessary) if namespace_packages.txt is not complete --ignore-namespace ignore Egg's namespace declaration and --namespace option. This option will disable removing (and recreating at install time) empty __init__.py files. Removing namespace_packages.txt from egg-info directory has the same effect. --clean-pycentral generate maintainer script that will remove byte code generated by python-central helper --shebang=COMMAND use given command as shebang in scripts --ignore-shebangs do not translate shebangs into Debian dependencies SEE ALSO ======== * /usr/share/doc/python/python-policy.txt.gz * /usr/share/doc/python-doc/README.PyDist (python-doc package) * pycompile(1), pyclean(1) * dh_python3(1), py3compile(1), py3clean(1) * Wiki page about converting package to dh_python2: http://wiki.debian.org/Python/TransitionToDHPython2 python-defaults-2.7.12/debian/0000775000000000000000000000000013205532536013047 5ustar python-defaults-2.7.12/debian/copyright0000664000000000000000000003713212057417145015012 0ustar This is the Debian GNU/Linux prepackaged version of the Python programming language. Python was written by Guido van Rossum and others. This package was put together by Klee Dienes from sources from ftp.python.org:/pub/python, based on the Debianization by the previous maintainers Bernd S. Brentrup and Bruce Perens. Current maintainer is Matthias Klose until the final 2.3 version is released. Copyright notice (as found in LICENSE in the original source). -------------------------------------------------------------- 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.3.5 2.3.4 2005 PSF yes 2.4 2.3 2004 PSF yes 2.4.1 2.4 2005 PSF yes 2.4.2 2.4.1 2005 PSF yes 2.4.3 2.4.2 2006 PSF yes 2.4.4 2.4.3 2006 PSF yes 2.5 2.4 2006 PSF yes 2.5.1 2.5 2007 PSF yes 2.5.2 2.5.1 2008 PSF yes 2.5.3 2.5.2 2008 PSF yes 2.6 2.5 2008 PSF yes 2.6.1 2.6 2008 PSF yes 2.6.2 2.6.1 2009 PSF yes 2.6.3 2.6.2 2009 PSF yes 2.6.4 2.6.3 2009 PSF yes 2.6.5 2.6.4 2010 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, 2005, 2006, 2007, 2008, 2009, 2010 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. dh_python2, pycompile, pyclean and debpython module: ==================================================== Copyright © 2010,2011 Piotr Ożarowski Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. python-defaults-2.7.12/debian/debian_defaults0000664000000000000000000000052712141575124016105 0ustar [DEFAULT] # the default python version default-version = python2.7 # all supported python versions supported-versions = python2.7 # formerly supported python versions old-versions = python2.3, python2.4, python2.5, python2.6 # unsupported versions, including older versions unsupported-versions = python2.3, python2.4, python2.5, python2.6 python-defaults-2.7.12/debian/python.manpages0000664000000000000000000000001512057417145016103 0ustar dh_python2.1 python-defaults-2.7.12/debian/python.desktop0000664000000000000000000000020712057417145015764 0ustar [Desktop Entry] Type=KonsoleApplication Name=Python Interpreter Comment=Python Exec=/usr/bin/python Icon=/usr/share/pixmaps/python.xpm python-defaults-2.7.12/debian/compat0000664000000000000000000000000212057417145014247 0ustar 5 python-defaults-2.7.12/debian/control0000664000000000000000000002221713205532536014456 0ustar Source: python-defaults Section: python Priority: optional Maintainer: Matthias Klose Uploaders: Scott Kitterman , Piotr Ożarowski , Barry Warsaw Build-Depends: debhelper (>= 8~), dpkg-dev (>= 1.17.11), python2.7 (>= 2.7.12-1), lsb-release, python-all, python2.7 (>= 2.7.12-1~), debiandoc-sgml, Standards-Version: 3.9.6 Homepage: http://www.python.org/ Vcs-Bzr: http://alioth.debian.org/anonscm/bzr/pkg-python/python-defaults-debian Vcs-Browser: http://alioth.debian.org/scm/loggerhead/pkg-python/python-defaults-debian/files Package: python Architecture: any Multi-Arch: allowed Priority: standard Pre-Depends: python-minimal (= ${binary:Version}) Depends: ${misc:Depends}, python2.7 (>= 2.7.12-1~), libpython-stdlib (= ${binary:Version}) Suggests: python-doc (= ${binary:Version}), python-tk (>= 2.7.12-1~) Conflicts: python-central (<< 0.5.5) Breaks: update-manager-core (<< 0.200.5-2) Replaces: python-dev (<< 2.6.5-2) Provides: python-email, python-ctypes, python-wsgiref, python-importlib, python-profiler Description: interactive high-level object-oriented language (default version) Python, the high-level, interactive object oriented language, includes an extensive class library with lots of goodies for network programming, system administration, sounds and graphics. . This package is a dependency package, which depends on Debian's default Python version (currently v2.7). Package: python-minimal Architecture: any Multi-Arch: allowed Priority: standard Depends: ${misc:Depends}, python2.7-minimal (>= 2.7.12-1~), dpkg (>= 1.13.20) Recommends: python Conflicts: python-central (<< 0.5.5) Breaks: python (<= 2.7.3-1~), python-dev (<< 2.6), python-dbg (<< 2.6), python-all (<< 2.6), python-all-dev (<< 2.6), python-all-dbg (<< 2.6), python-examples (<< 2.6), idle (<< 2.6), python2.5-minimal (<< 2.5.5-7), python2.6-minimal (<< 2.6.5~rc2-2), python3.1-minimal (<< 3.1.2~rc1-2), python-support (<< 1.0.10ubuntu2) Replaces: python (<= 2.7.3-1~) Description: minimal subset of the Python language (default version) This package contains the interpreter and some essential modules. It's used in the boot process for some basic tasks. See /usr/share/doc/python2.7-minimal/README.Debian for a list of the modules contained in this package. Package: python-examples Architecture: all Depends: ${misc:Depends}, python (>= ${binary:Version}), python2.7-examples (>= 2.7.12-1~) Description: examples for the Python language (default version) Examples, Demos and Tools for Python. These are files included in the upstream Python distribution. . This package is a dependency package, which depends on Debian's default Python version (currently v2.7). Package: python-dev Architecture: any Multi-Arch: allowed Depends: ${misc:Depends}, python (= ${binary:Version}), libpython-dev (= ${binary:Version}), python2.7-dev (>= 2.7.12-1~) Description: header files and a static library for Python (default) Header files, a static library and development tools for building Python modules, extending the Python interpreter or embedding Python in applications. . This package is a dependency package, which depends on Debian's default Python version (currently v2.7). Package: libpython-dev Architecture: any Multi-Arch: same Section: libdevel Depends: libpython2.7-dev (>= 2.7.12-1~), ${misc:Depends} Description: header files and a static library for Python (default) Header files, a static library and development tools for building Python modules, extending the Python interpreter or embedding Python in applications. . This package is a dependency package, which depends on Debian's default Python version (currently v2.7). Package: libpython-stdlib Architecture: any Multi-Arch: same Priority: standard Depends: libpython2.7-stdlib (>= 2.7.12-1~), ${misc:Depends} Description: interactive high-level object-oriented language (default python version) Python, the high-level, interactive object oriented language, includes an extensive class library with lots of goodies for network programming, system administration, sounds and graphics. . This package is a dependency package, which depends on Debian's default Python version (currently v2.7). Package: idle Architecture: all Depends: ${misc:Depends}, python (>= ${binary:Version}), python-tk, idle-python2.7 Enhances: python Replaces: python (<< 2.7.3-1~) Breaks: python (<< 2.7.3-1~) Description: IDE for Python using Tkinter (default version) IDLE is an Integrated Development Environment for Python. IDLE is written using Tkinter and therefore quite platform-independent. . This package is a dependency package, which depends on Debian's default Python version (currently v2.7) of IDLE. Package: python-doc Section: doc Architecture: all Depends: ${misc:Depends}, python2.7-doc (>= 2.7.12-1~) Suggests: python-examples, python (= ${binary:Version}) Breaks: python (<< 2.3.5) Replaces: python (<< 2.3.5) Description: documentation for the high-level object-oriented language Python This is the official set of documentation for the interactive high-level object-oriented language Python (v2.7). All documents are provided in HTML format, some in info format. The package consists of nine documents: . * Tutorial * Python Library Reference * Macintosh Module Reference * Python Language Reference * Extending and Embedding Python * Python/C API Reference * Installing Python Modules * Documenting Python * Distributing Python Modules . This package is a dependency package, which depends on Debian's default Python version (currently v2.7). Package: python-dbg Architecture: any Multi-Arch: allowed Section: debug Priority: extra Depends: ${misc:Depends}, python (= ${binary:Version}), libpython-dbg (= ${binary:Version}), python2.7-dbg (>= 2.7.12-1~) Description: debug build of the Python Interpreter (version 2.7) Python interpreter configured with --pydebug. Dynamically loaded modules are searched in /usr/lib/python2.7/lib-dynload/debug first. Package: libpython-dbg Architecture: any Multi-Arch: same Section: debug Priority: extra Depends: libpython2.7-dbg (>= 2.7.12-1~), ${misc:Depends} Description: debug build of the Python Interpreter (version 2.7) Python interpreter configured with --pydebug. Dynamically loaded modules are searched in /usr/lib/python2.7/lib-dynload/debug first. Package: python-all Architecture: any Multi-Arch: allowed Depends: ${misc:Depends}, python (= ${binary:Version}), python2.7 (>= 2.7.2-3) Description: package depending on all supported Python runtime versions The package currently depends on python2.7, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python runtimes. Package: python-all-dev Architecture: any Multi-Arch: allowed Depends: ${misc:Depends}, python (= ${binary:Version}), python-all (= ${binary:Version}), libpython-all-dev (= ${binary:Version}), python-dev (= ${binary:Version}), python2.7-dev (>= 2.7-7) Description: package depending on all supported Python development packages The package currently depends on python2.7-dev, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python development packages. Package: python-all-dbg Architecture: any Multi-Arch: allowed Section: debug Priority: extra Depends: ${misc:Depends}, python (= ${binary:Version}), python-all (= ${binary:Version}), libpython-all-dbg (= ${binary:Version}), python-dbg (= ${binary:Version}), python2.7-dbg (>= 2.7-7) Description: package depending on all supported Python debugging packages The package currently depends on python2.7-dbg, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python debug packages. Package: libpython-all-dev Architecture: any Multi-Arch: same Section: libdevel Depends: libpython-dev (= ${binary:Version}), ${misc:Depends}, libpython2.7-dev Description: package depending on all supported Python development packages The package currently depends on libpython2.7-dev, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python development packages. Package: libpython-all-dbg Architecture: any Multi-Arch: same Section: debug Priority: extra Depends: libpython-dbg (= ${binary:Version}), ${misc:Depends}, libpython2.7-dbg Description: package depending on all supported Python debugging packages The package currently depends on libpython2.7-dbg, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python debug packages. python-defaults-2.7.12/debian/python.postrm.in0000664000000000000000000000012112111634304016224 0ustar #! /bin/sh set -e case "$1" in purge) rm -rf /etc/python esac #DEBHELPER# python-defaults-2.7.12/debian/idle.lintian-overrides0000664000000000000000000000011512154107470017336 0ustar # icon file available in a dependent package. idle binary: menu-icon-missing python-defaults-2.7.12/debian/idle.py0000775000000000000000000000013312057417145014340 0ustar #! /usr/bin/python from idlelib.PyShell import main if __name__ == '__main__': main() python-defaults-2.7.12/debian/pyversions.10000664000000000000000000000225412057417145015357 0ustar .TH PYVERSIONS .SH NAME pyversions \- print python version information .SH SYNOPSIS .PP .B pyversions .I [-h] [-v] [] .SH DESCRIPTION .PP .B pyversions prints information about installed, supported python runtimes, the default runtime, and parses the information of the PythonVersion fields in the package control file. .SH OPTIONS .TP .I -d, --default Show the default python version. .TP .I -s, --supported Show the supported python versions. .TP .I -r, --requested [|] Reads the value of the .B XS-Python-Version field in the source section of a control file and shows all matching python versions. The parameter is interpreted as a version string, if it is not the name of a file. If the XS-Python-Version field is missing, get the version information from debian/pyversions. Without any parameter, it will fall back to list the supported Python versions after checking debian/control and debian/pyversions. .TP .I -i, --installed Show the installed supported python versions. .TP .I -v, --version Limit the output to the version numbers of the python versions. .TP .I -h, --help Print a help text. .SH SEE ALSO Python policy. .SH AUTHOR Matthias Klose python-defaults-2.7.12/debian/python-dev.dirs0000664000000000000000000000001112057417145016021 0ustar /usr/bin python-defaults-2.7.12/debian/python-minimal.prerm0000664000000000000000000000012112057417145017057 0ustar #! /bin/sh set -e find /usr/share/python/ -name '*.py[oc]' -delete #DEBHELPER# python-defaults-2.7.12/debian/python-minimal.dirs0000664000000000000000000000001112057417145016671 0ustar /usr/bin python-defaults-2.7.12/debian/python.lintian-overrides0000664000000000000000000000033012632015665017746 0ustar # this is the only package that can depend on it python binary: depends-on-python-minimal # we rely on our patched python library, don't pick up a local version python binary: command-with-path-in-maintainer-script python-defaults-2.7.12/debian/libpython-all-dbg.postinst0000664000000000000000000000027412254623031020161 0ustar #! /bin/sh set -e DOCDIR=/usr/share/doc/libpython-all-dbg DOCLINK=libpython-dbg if [ -d $DOCDIR ] && [ ! -L $DOCDIR ]; then rmdir $DOCDIR ln -s $DOCLINK $DOCDIR fi #DEBHELPER# python-defaults-2.7.12/debian/pyversions.py0000664000000000000000000003540212374331373015650 0ustar #! /usr/bin/python import os, re, sys try: SetType = set except NameError: import sets SetType = sets.Set set = sets.Set _defaults = None def read_default(name=None): global _defaults from ConfigParser import SafeConfigParser, NoOptionError if not _defaults: if os.path.exists('/usr/share/python/debian_defaults'): config = SafeConfigParser() try: config.readfp(file('/usr/share/python/debian_defaults')) except IOError, msg: print msg sys.exit(1) _defaults = config if _defaults and name: try: value = _defaults.get('DEFAULT', name) except NoOptionError: raise ValueError return value return None def parse_versions(vstring, add_exact=False): import operator operators = { None: operator.eq, '=': operator.eq, '>=': operator.ge, '<=': operator.le, '<<': operator.lt } vinfo = {} exact_versions = set([]) version_range = set(supported_versions(version_only=True) + old_versions(version_only=True)) relop_seen = False for field in vstring.split(','): field = field.strip() if field == 'all': vinfo['all'] = 'all' continue if field in ('current', 'current_ext'): vinfo['current'] = field continue vinfo.setdefault('versions', set()) ve = re.compile('(>=|<=|<<|=)? *(\d\.\d)$') m = ve.match(field) try: if not m: raise ValueError('error parsing Python-Version attribute') op, v = m.group(1), m.group(2) vmaj, vmin = v.split('.') # Don't silently ignore Python 3 versions. if int(vmaj) > 2: raise ValueError('error parsing Python-Version attribute, Python 3 version found') if op in (None, '='): exact_versions.add(v) else: relop_seen = True filtop = operators[op] version_range = [av for av in version_range if filtop(av ,v)] except Exception: raise ValueError, 'error parsing Python-Version attribute' if add_exact: if exact_versions: vinfo['vexact'] = exact_versions if 'versions' in vinfo: if relop_seen: vinfo['versions'] = set(version_range) else: del vinfo['versions'] else: if 'versions' in vinfo: vinfo['versions'] = exact_versions if relop_seen: vinfo['versions'] = exact_versions.union(version_range) return vinfo _old_versions = None def old_versions(version_only=False): global _old_versions if not _old_versions: try: value = read_default('old-versions') _old_versions = [s.strip() for s in value.split(',')] except ValueError: _old_versions = [] if version_only: return [v[6:] for v in _old_versions] else: return _old_versions _unsupported_versions = None def unsupported_versions(version_only=False): global _unsupported_versions if not _unsupported_versions: try: value = read_default('unsupported-versions') _unsupported_versions = [s.strip() for s in value.split(',')] except ValueError: _unsupported_versions = [] if version_only: return [v[6:] for v in _unsupported_versions] else: return _unsupported_versions _supported_versions = ["python%s" % ver.strip() for ver in os.environ.get('DEBPYTHON_SUPPORTED', '').split(',') if ver.strip()] def supported_versions(version_only=False): global _supported_versions if not _supported_versions: try: value = read_default('supported-versions') _supported_versions = [s.strip() for s in value.split(',')] except ValueError: cmd = ['/usr/bin/apt-cache', '--no-all-versions', 'show', 'python-all'] try: import subprocess p = subprocess.Popen(cmd, bufsize=1, shell=False, stdout=subprocess.PIPE) fd = p.stdout except ImportError: fd = os.popen(' '.join(cmd)) depends = None for line in fd: if line.startswith('Depends:'): depends = line.split(':', 1)[1].strip().split(',') fd.close() if depends: depends = [re.sub(r'\s*(\S+)[ (]?.*', r'\1', s) for s in depends] _supported_versions = depends if not _supported_versions: # last resort: python-minimal not installed, apt-cache # not available, hard code the value, #394084 _supported_versions = ['python2.6', 'python2.7'] if version_only: return [v[6:] for v in _supported_versions] else: return _supported_versions _default_version = "python%s" % os.environ.get('DEBPYTHON_DEFAULT', '') if _default_version == 'python': _default_version = None def default_version(version_only=False): global _default_version if not _default_version: try: _default_version = link = os.readlink('/usr/bin/python') except OSError: _default_version = None try: cmd = ['/usr/bin/python', '-c', 'import sys; print sys.version[:3]'] import subprocess p = subprocess.Popen(cmd, bufsize=1, shell=False, stdout=subprocess.PIPE) fd = p.stdout except ImportError: fd = os.popen("/usr/bin/python -c 'import sys; print sys.version[:3]'") line = fd.readline().strip() fd.close() if re.match(r'\d\.\d$', line): _default_version = 'python' + line # consistency check try: debian_default = read_default('default-version') except ValueError: debian_default = "python2.7" if not _default_version in (debian_default, os.path.join('/usr/bin', debian_default)): raise ValueError, "/usr/bin/python does not match the python default version. It must be reset to point to %s" % debian_default _default_version = debian_default if version_only: return _default_version[6:] else: return _default_version def requested_versions(vstring, version_only=False): versions = None vinfo = parse_versions(vstring, add_exact=True) supported = supported_versions(version_only=True) if len(vinfo) == 1: if 'all' in vinfo: versions = supported elif 'current' in vinfo: versions = [default_version(version_only=True)] elif 'vexact' in vinfo: versions = vinfo['vexact'] else: versions = vinfo['versions'].intersection(supported) elif 'all' in vinfo and 'current' in vinfo: raise ValueError, "both `current' and `all' in version string" elif 'all' in vinfo: if 'versions' in vinfo: versions = vinfo['versions'].intersection(supported) else: versions = set(supported) if 'vexact' in vinfo: versions.update(vinfo['vexact']) elif 'current' in vinfo: current = default_version(version_only=True) if not current in vinfo['versions']: raise ValueError, "`current' version not in supported versions" versions = [current] elif 'versions' in vinfo or 'vexact' in vinfo: versions = set() if 'versions' in vinfo: versions = vinfo['versions'].intersection(supported) if 'vexact' in vinfo: versions.update(vinfo['vexact']) else: raise ValueError, 'No Python versions in version string' if not versions: raise ValueError('computed set of supported versions is empty') if version_only: return versions else: return ['python%s' % v for v in versions] def installed_versions(version_only=False): import glob supported = supported_versions() versions = [os.path.basename(s) for s in glob.glob('/usr/bin/python[0-9].[0-9]') if os.path.basename(s) in supported] versions.sort() if version_only: return [v[6:] for v in versions] else: return versions class ControlFileValueError(ValueError): pass class MissingVersionValueError(ValueError): pass def extract_pyversion_attribute(fn, pkg): """read the debian/control file, extract the X-Python-Version or XS-Python-Version field; check that XB-Python-Version exists for the package.""" version = None sversion = None section = None try: fp = file(fn, 'r') except IOError, msg: print "Cannot open %s: %s" % (fn, msg) sys.exit(2) for line in fp: line = line.strip() if line == '': if section == None: continue if pkg == 'Source': break section = None elif line.startswith('Source:'): section = 'Source' elif line.startswith('Package: ' + pkg): section = pkg elif line.lower().startswith(('xs-python-version:', 'x-python-version:')): if section != 'Source': raise ValueError, \ 'attribute X(S)-Python-Version not in Source section' sversion = line.split(':', 1)[1].strip() elif line.lower().startswith('xb-python-version:'): if section == pkg: version = line.split(':', 1)[1].strip() if section == None: raise ControlFileValueError, 'not a control file' if pkg == 'Source': if sversion == None: raise MissingVersionValueError, \ 'no X(S)-Python-Version in control file' return sversion if version == None: raise MissingVersionValueError, \ 'no XB-Python-Version for package `%s' % pkg return version # compatibility functions to parse debian/pyversions def version_cmp(ver1,ver2): v1=[int(i) for i in ver1.split('.')] v2=[int(i) for i in ver2.split('.')] return cmp(v1,v2) def requested_versions_bis(vstring, version_only=False): versions = [] py_supported_short = supported_versions(version_only=True) for item in vstring.split(','): v=item.split('-') if len(v)>1: if not v[0]: v[0] = py_supported_short[0] if not v[1]: v[1] = py_supported_short[-1] for ver in py_supported_short: try: if version_cmp(ver,v[0]) >= 0 \ and version_cmp(ver,v[1]) <= 0: versions.append(ver) except ValueError: pass else: if v[0] in py_supported_short: versions.append(v[0]) versions.sort(version_cmp) if not versions: raise ValueError, 'empty set of versions' if not version_only: versions=['python'+i for i in versions] return versions def extract_pyversion_attribute_bis(fn): vstring = file(fn).readline().rstrip('\n') return vstring def main(): from optparse import OptionParser usage = '[-v] [-h] [-d|--default] [-s|--supported] [-i|--installed] [-r|--requested |]' parser = OptionParser(usage=usage) parser.add_option('-d', '--default', help='print the default python version', action='store_true', dest='default') parser.add_option('-s', '--supported', help='print the supported python versions', action='store_true', dest='supported') parser.add_option('-r', '--requested', help='print the python versions requested by a build; the argument is either the name of a control file or the value of the X(S)-Python-Version attribute', action='store_true', dest='requested') parser.add_option('-i', '--installed', help='print the installed supported python versions', action='store_true', dest='installed') parser.add_option('-v', '--version', help='print just the version number(s)', default=False, action='store_true', dest='version_only') opts, args = parser.parse_args() program = os.path.basename(sys.argv[0]) if opts.default and len(args) == 0: try: print default_version(opts.version_only) except ValueError, msg: print "%s:" % program, msg sys.exit(1) elif opts.supported and len(args) == 0: print ' '.join(supported_versions(opts.version_only)) elif opts.installed and len(args) == 0: print ' '.join(installed_versions(opts.version_only)) elif opts.requested and len(args) <= 1: if len(args) == 0: versions = 'debian/control' else: versions = args[0] try: if os.path.isfile(versions): fn = versions try: vstring = extract_pyversion_attribute(fn, 'Source') vs = requested_versions(vstring, opts.version_only) except ControlFileValueError: sys.stderr.write("%s: not a control file: %s, " \ % (program, fn)) sys.exit(1) except MissingVersionValueError: fn = os.path.join(os.path.dirname(fn), 'pyversions') sys.stderr.write("%s: missing X(S)-Python-Version in control file, fall back to %s\n" \ % (program, fn)) try: vstring = extract_pyversion_attribute_bis(fn) vs = requested_versions_bis(vstring, opts.version_only) except IOError: sys.stderr.write("%s: missing debian/pyversions file, fall back to supported versions\n" \ % program) vs = supported_versions(opts.version_only) except ValueError, e: sys.stderr.write("%s: %s\n" % (program, e)) sys.exit(4) else: vs = requested_versions(versions, opts.version_only) print ' '.join(vs) except ValueError, msg: sys.stderr.write("%s: %s\n" % (program, msg)) sys.exit(1) else: sys.stderr.write("usage: %s %s\n" % (program, usage)) sys.exit(1) if __name__ == '__main__': main() python-defaults-2.7.12/debian/README.Debian0000664000000000000000000000071512057417145015115 0ustar More documentation and README's for this package can be found in the directory /usr/share/doc/python2.6/ The upstream documentation can be found after installation of the python-doc package in the directory /usr/share/doc/python/html A draft of the "Debian Python Policy", mostly needed for Debian package maintainers 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-defaults-2.7.12/debian/pyversions0000775000000000000000000000015213205532536015214 0ustar #! /usr/bin/python2 import sys sys.path[0:0] = ['/usr/share/python'] import pyversions pyversions.main() python-defaults-2.7.12/debian/valgrind-python.supp0000664000000000000000000001640112057417145017111 0ustar # # This is a valgrind suppression file that should be used when using valgrind. # # --------------------------------------------------------------------------- # Debian note: # The file Misc/valgrind-python.supp is placed in an modified form into the # directory /usr/lib/valgrind as python.supp. There's no need to to add it # with the --suppressions option. # The unmodified file is found in /usr/share/doc/python2.6/ # # The python2.6-dbg build has been compiled with -DPy_USING_MEMORY_DEBUGGER # so you can safely comment out the suppressions for PyObject_Free and # PyObject_Realloc. # --------------------------------------------------------------------------- # Here's an example of running valgrind: # # cd python/dist/src # valgrind --tool=memcheck --suppressions=Misc/valgrind-python.supp \ # ./python -E -tt ./Lib/test/regrtest.py -u bsddb,network # # You must edit Objects/obmalloc.c and uncomment Py_USING_MEMORY_DEBUGGER # to use the preferred suppressions with Py_ADDRESS_IN_RANGE. # # If you do not want to recompile Python, you can uncomment # suppressions for PyObject_Free and PyObject_Realloc. # # See /usr/share/doc/python2.6/README.valgrind for more information. # all tool names: Addrcheck,Memcheck,cachegrind,helgrind,massif { ADDRESS_IN_RANGE/Invalid read of size 4 Memcheck:Addr4 fun:Py_ADDRESS_IN_RANGE } { ADDRESS_IN_RANGE/Invalid read of size 4 Memcheck:Value4 fun:Py_ADDRESS_IN_RANGE } { ADDRESS_IN_RANGE/Invalid read of size 8 (x86_64 aka amd64) Memcheck:Value8 fun:Py_ADDRESS_IN_RANGE } { ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value Memcheck:Cond fun:Py_ADDRESS_IN_RANGE } # # Leaks (including possible leaks) # Hmmm, I wonder if this masks some real leaks. I think it does. # Will need to fix that. # { Suppress leaking the GIL. Happens once per process, see comment in ceval.c. Memcheck:Leak fun:malloc fun:PyThread_allocate_lock fun:PyEval_InitThreads } { Suppress leaking the GIL after a fork. Memcheck:Leak fun:malloc fun:PyThread_allocate_lock fun:PyEval_ReInitThreads } { Suppress leaking the autoTLSkey. This looks like it shouldn't leak though. Memcheck:Leak fun:malloc fun:PyThread_create_key fun:_PyGILState_Init fun:Py_InitializeEx fun:Py_Main } { Hmmm, is this a real leak or like the GIL? Memcheck:Leak fun:malloc fun:PyThread_ReInitTLS } { Handle PyMalloc confusing valgrind (possibly leaked) Memcheck:Leak fun:realloc fun:_PyObject_GC_Resize fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING } { Handle PyMalloc confusing valgrind (possibly leaked) Memcheck:Leak fun:malloc fun:_PyObject_GC_New fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING } { Handle PyMalloc confusing valgrind (possibly leaked) Memcheck:Leak fun:malloc fun:_PyObject_GC_NewVar fun:COMMENT_THIS_LINE_TO_DISABLE_LEAK_WARNING } # # Non-python specific leaks # { Handle pthread issue (possibly leaked) Memcheck:Leak fun:calloc fun:allocate_dtv fun:_dl_allocate_tls_storage fun:_dl_allocate_tls } { Handle pthread issue (possibly leaked) Memcheck:Leak fun:memalign fun:_dl_allocate_tls_storage fun:_dl_allocate_tls } ###{ ### ADDRESS_IN_RANGE/Invalid read of size 4 ### Memcheck:Addr4 ### fun:PyObject_Free ###} ### ###{ ### ADDRESS_IN_RANGE/Invalid read of size 4 ### Memcheck:Value4 ### fun:PyObject_Free ###} ### ###{ ### ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value ### Memcheck:Cond ### fun:PyObject_Free ###} ###{ ### ADDRESS_IN_RANGE/Invalid read of size 4 ### Memcheck:Addr4 ### fun:PyObject_Realloc ###} ### ###{ ### ADDRESS_IN_RANGE/Invalid read of size 4 ### Memcheck:Value4 ### fun:PyObject_Realloc ###} ### ###{ ### ADDRESS_IN_RANGE/Conditional jump or move depends on uninitialised value ### Memcheck:Cond ### fun:PyObject_Realloc ###} ### ### All the suppressions below are for errors that occur within libraries ### that Python uses. The problems to not appear to be related to Python's ### use of the libraries. ### { Generic ubuntu ld problems Memcheck:Addr8 obj:/lib/ld-2.4.so obj:/lib/ld-2.4.so obj:/lib/ld-2.4.so obj:/lib/ld-2.4.so } { Generic gentoo ld problems Memcheck:Cond obj:/lib/ld-2.3.4.so obj:/lib/ld-2.3.4.so obj:/lib/ld-2.3.4.so obj:/lib/ld-2.3.4.so } { DBM problems, see test_dbm Memcheck:Param write(buf) fun:write obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 fun:dbm_close } { DBM problems, see test_dbm Memcheck:Value8 fun:memmove obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 fun:dbm_store fun:dbm_ass_sub } { DBM problems, see test_dbm Memcheck:Cond obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 fun:dbm_store fun:dbm_ass_sub } { DBM problems, see test_dbm Memcheck:Cond fun:memmove obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 obj:/usr/lib/libdb1.so.2 fun:dbm_store fun:dbm_ass_sub } { GDBM problems, see test_gdbm Memcheck:Param write(buf) fun:write fun:gdbm_open } { ZLIB problems, see test_gzip Memcheck:Cond obj:/lib/libz.so.1.2.3.3 obj:/lib/libz.so.1.2.3.3 fun:deflate } { Avoid problems w/readline doing a putenv and leaking on exit Memcheck:Leak fun:malloc fun:xmalloc fun:sh_set_lines_and_columns fun:_rl_get_screen_size fun:_rl_init_terminal_io obj:/lib/libreadline.so.6.1 fun:rl_initialize } ### ### These occur from somewhere within the SSL, when running ### test_socket_sll. They are too general to leave on by default. ### ###{ ### somewhere in SSL stuff ### Memcheck:Cond ### fun:memset ###} ###{ ### somewhere in SSL stuff ### Memcheck:Value4 ### fun:memset ###} ### ###{ ### somewhere in SSL stuff ### Memcheck:Cond ### fun:MD5_Update ###} ### ###{ ### somewhere in SSL stuff ### Memcheck:Value4 ### fun:MD5_Update ###} # # All of these problems come from using test_socket_ssl # { from test_socket_ssl Memcheck:Cond fun:BN_bin2bn } { from test_socket_ssl Memcheck:Cond fun:BN_num_bits_word } { from test_socket_ssl Memcheck:Value4 fun:BN_num_bits_word } { from test_socket_ssl Memcheck:Cond fun:BN_mod_exp_mont_word } { from test_socket_ssl Memcheck:Cond fun:BN_mod_exp_mont } { from test_socket_ssl Memcheck:Param write(buf) fun:write obj:/usr/lib/libcrypto.so.0.9.8 } { from test_socket_ssl Memcheck:Cond fun:RSA_verify } { from test_socket_ssl Memcheck:Value4 fun:RSA_verify } { from test_socket_ssl Memcheck:Value4 fun:DES_set_key_unchecked } { from test_socket_ssl Memcheck:Value4 fun:DES_encrypt2 } { from test_socket_ssl Memcheck:Cond obj:/usr/lib/libssl.so.0.9.8 } { from test_socket_ssl Memcheck:Value4 obj:/usr/lib/libssl.so.0.9.8 } { from test_socket_ssl Memcheck:Cond fun:BUF_MEM_grow_clean } { from test_socket_ssl Memcheck:Cond fun:memcpy fun:ssl3_read_bytes } { from test_socket_ssl Memcheck:Cond fun:SHA1_Update } { from test_socket_ssl Memcheck:Value4 fun:SHA1_Update } python-defaults-2.7.12/debian/python.prerm.in0000664000000000000000000000015112111634304016030 0ustar #! /bin/sh set -e case "$1" in remove) rm -f /usr/share/python/pyversions.py[co] esac #DEBHELPER# python-defaults-2.7.12/debian/source.lintian-overrides0000664000000000000000000000067312154106401017723 0ustar # this source package provides these packages so it cannot depend on them python-defaults source: dbg-package-missing-depends python-all-dbg python-defaults source: dbg-package-missing-depends python-dbg python-defaults source: dbg-package-missing-depends libpython-all-dbg python-defaults source: dbg-package-missing-depends libpython-dbg # it's upstream software, just splitted out. python-defaults source: native-package-with-dash-version python-defaults-2.7.12/debian/idle.desktop0000664000000000000000000000033312154107660015354 0ustar [Desktop Entry] Name=IDLE Comment=Integrated Development Environment for Python Exec=/usr/bin/idle Icon=/usr/share/pixmaps/idle.xpm Terminal=false Type=Application Categories=Application;Development; StartupNotify=true python-defaults-2.7.12/debian/python-doc.docs0000664000000000000000000000002612057417145016005 0ustar pydist/README.PyDist* python-defaults-2.7.12/debian/control.in0000664000000000000000000002215512632015073015057 0ustar Source: python-defaults Section: python Priority: optional Maintainer: Matthias Klose Uploaders: Scott Kitterman , Piotr Ożarowski , Barry Warsaw Build-Depends: debhelper (>= 8~), @bd_i586@, lsb-release, python-all, @PVER@ (>= @PREVVER@), debiandoc-sgml, Standards-Version: 3.9.6 Homepage: http://www.python.org/ Vcs-Bzr: http://alioth.debian.org/anonscm/bzr/pkg-python/python-defaults-debian Vcs-Browser: http://alioth.debian.org/scm/loggerhead/pkg-python/python-defaults-debian/files Package: python Architecture: any Multi-Arch: allowed Priority: standard Pre-Depends: python-minimal (= ${binary:Version}) Depends: ${misc:Depends}, @PVER@ (>= @PREVVER@), libpython-stdlib (= ${binary:Version}) Suggests: python-doc (= ${binary:Version}), python-tk (>= @PREVVER@) Conflicts: python-central (<< 0.5.5) Breaks: update-manager-core (<< 0.200.5-2) Replaces: python-dev (<< 2.6.5-2) Provides: python-email, python-ctypes, python-wsgiref, python-importlib, python-profiler Description: interactive high-level object-oriented language (default version) Python, the high-level, interactive object oriented language, includes an extensive class library with lots of goodies for network programming, system administration, sounds and graphics. . This package is a dependency package, which depends on Debian's default Python version (currently v@VER@). Package: python-minimal Architecture: any Multi-Arch: allowed Priority: standard Depends: ${misc:Depends}, @PVER@-minimal (>= @PREVVER@), dpkg (>= 1.13.20) Recommends: python Conflicts: python-central (<< 0.5.5) Breaks: python (<= 2.7.3-1~), python-dev (<< 2.6), python-dbg (<< 2.6), python-all (<< 2.6), python-all-dev (<< 2.6), python-all-dbg (<< 2.6), python-examples (<< 2.6), idle (<< 2.6), python2.5-minimal (<< 2.5.5-7), python2.6-minimal (<< 2.6.5~rc2-2), python3.1-minimal (<< 3.1.2~rc1-2), python-support (<< 1.0.10ubuntu2) Replaces: python (<= 2.7.3-1~) Description: minimal subset of the Python language (default version) This package contains the interpreter and some essential modules. It's used in the boot process for some basic tasks. See /usr/share/doc/@PVER@-minimal/README.Debian for a list of the modules contained in this package. Package: python-examples Architecture: all Depends: ${misc:Depends}, python (>= ${binary:Version}), @PVER@-examples (>= @PREVVER@) Description: examples for the Python language (default version) Examples, Demos and Tools for Python. These are files included in the upstream Python distribution. . This package is a dependency package, which depends on Debian's default Python version (currently v@VER@). Package: python-dev Architecture: any Multi-Arch: allowed Depends: ${misc:Depends}, python (= ${binary:Version}), libpython-dev (= ${binary:Version}), @PVER@-dev (>= @PREVVER@) Description: header files and a static library for Python (default) Header files, a static library and development tools for building Python modules, extending the Python interpreter or embedding Python in applications. . This package is a dependency package, which depends on Debian's default Python version (currently v@VER@). Package: libpython-dev Architecture: any Multi-Arch: same Section: libdevel Depends: lib@PVER@-dev (>= @PREVVER@), ${misc:Depends} Description: header files and a static library for Python (default) Header files, a static library and development tools for building Python modules, extending the Python interpreter or embedding Python in applications. . This package is a dependency package, which depends on Debian's default Python version (currently v@VER@). Package: libpython-stdlib Architecture: any Multi-Arch: same Priority: standard Depends: libpython@VER@-stdlib (>= @PREVVER@), ${misc:Depends} Description: interactive high-level object-oriented language (default python version) Python, the high-level, interactive object oriented language, includes an extensive class library with lots of goodies for network programming, system administration, sounds and graphics. . This package is a dependency package, which depends on Debian's default Python version (currently v@VER@). Package: idle Architecture: all Depends: ${misc:Depends}, python (>= ${binary:Version}), python-tk, idle-@PVER@ Enhances: python Replaces: python (<< 2.7.3-1~) Breaks: python (<< 2.7.3-1~) Description: IDE for Python using Tkinter (default version) IDLE is an Integrated Development Environment for Python. IDLE is written using Tkinter and therefore quite platform-independent. . This package is a dependency package, which depends on Debian's default Python version (currently v@VER@) of IDLE. Package: python-doc Section: doc Architecture: all Depends: ${misc:Depends}, python@VER@-doc (>= @PREVVER@) Suggests: python-examples, python (= ${binary:Version}) Breaks: python (<< 2.3.5) Replaces: python (<< 2.3.5) Description: documentation for the high-level object-oriented language Python This is the official set of documentation for the interactive high-level object-oriented language Python (v@VER@). All documents are provided in HTML format, some in info format. The package consists of nine documents: . * Tutorial * Python Library Reference * Macintosh Module Reference * Python Language Reference * Extending and Embedding Python * Python/C API Reference * Installing Python Modules * Documenting Python * Distributing Python Modules . This package is a dependency package, which depends on Debian's default Python version (currently v@VER@). Package: python-dbg Architecture: any Multi-Arch: allowed Section: debug Priority: extra Depends: ${misc:Depends}, python (= ${binary:Version}), libpython-dbg (= ${binary:Version}), python@VER@-dbg (>= @PREVVER@) Description: debug build of the Python Interpreter (version @VER@) Python interpreter configured with --pydebug. Dynamically loaded modules are searched in /usr/lib/python@VER@/lib-dynload/debug first. Package: libpython-dbg Architecture: any Multi-Arch: same Section: debug Priority: extra Depends: lib@PVER@-dbg (>= @PREVVER@), ${misc:Depends} Description: debug build of the Python Interpreter (version @VER@) Python interpreter configured with --pydebug. Dynamically loaded modules are searched in /usr/lib/python@VER@/lib-dynload/debug first. Package: python-all Architecture: any Multi-Arch: allowed Depends: ${misc:Depends}, python (= ${binary:Version}), python2.7 (>= 2.7.2-3) Description: package depending on all supported Python runtime versions The package currently depends on python2.7, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python runtimes. Package: python-all-dev Architecture: any Multi-Arch: allowed Depends: ${misc:Depends}, python (= ${binary:Version}), python-all (= ${binary:Version}), libpython-all-dev (= ${binary:Version}), python-dev (= ${binary:Version}), python2.7-dev (>= 2.7-7) Description: package depending on all supported Python development packages The package currently depends on python2.7-dev, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python development packages. Package: python-all-dbg Architecture: any Multi-Arch: allowed Section: debug Priority: extra Depends: ${misc:Depends}, python (= ${binary:Version}), python-all (= ${binary:Version}), libpython-all-dbg (= ${binary:Version}), python-dbg (= ${binary:Version}), python2.7-dbg (>= 2.7-7) Description: package depending on all supported Python debugging packages The package currently depends on python2.7-dbg, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python debug packages. Package: libpython-all-dev Architecture: any Multi-Arch: same Section: libdevel Depends: libpython-dev (= ${binary:Version}), ${misc:Depends}, libpython2.7-dev Description: package depending on all supported Python development packages The package currently depends on libpython2.7-dev, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python development packages. Package: libpython-all-dbg Architecture: any Multi-Arch: same Section: debug Priority: extra Depends: libpython-dbg (= ${binary:Version}), ${misc:Depends}, libpython2.7-dbg Description: package depending on all supported Python debugging packages The package currently depends on libpython2.7-dbg, in the future, dependencies on jython (Python for a JVM) and ironpython (Python for Mono) may be added. . This package is a dependency package used as a build dependency for other packages to avoid hardcoded dependencies on specific Python debug packages. python-defaults-2.7.12/debian/python.mk0000664000000000000000000000415512057417145014730 0ustar # some macros useful for packaging python packages # to include it unconditionally: # include /usr/share/python/python.mk # # to include it conditionally, and have the packaging working with earlier releases # and backports: # -include /usr/share/python/python.mk # ifeq (,$(py_sitename)) # py_sitename = site-packages # py_libdir = /usr/lib/python$(subst python,,$(1))/site-packages # py_sitename_sh = $(py_sitename) # py_libdir_sh = $(py_libdir) # endif # py_sitename: name of the site-packages/dist-packages directory depending # on the python version. Call as: $(call py_sitename, ). # Don't use this in shell snippets inside loops. py_sitename = $(if $(filter $(subst python,,$(1)), 2.3 2.4 2.5),site,dist)-packages # py_libdir: absolute path to the default python library for third party # stuff. Call as: $(call py_libdir, ). # Don't use this in shell snippets inside loops. py_libdir = /usr/lib/python$(strip $(if $(findstring 3.,$(subst python,,$(1))),3,$(subst python,,$(1))))/$(py_sitename) # py_pkgname: package name corresponding to the python version. # Call as: $(call py_pkgname, , ). py_pkgname = $(if $(findstring 3.,$(2)),$(subst python-,python3-,$(1)),$(1)) # distutils' build directory py_builddir = $(shell python$(strip $(subst python,,$(1))) -c 'from distutils.command.build import build; from distutils.core import Distribution; b = build(Distribution()); b.finalize_options(); print(b.build_platlib)') # The same macros for use inside loops in shell snippets py_sitename_sh = $$(basename $$(_py_=$(strip $(1)); python$${_py_\#python*} -c 'from distutils import sysconfig; print(sysconfig.get_python_lib())')) py_libdir_sh = $$(_py_=$(strip $(1)); python$${_py_\#python*} -c 'from distutils import sysconfig; print(sysconfig.get_python_lib())') py_builddir_sh = $$(_py_=$(strip $(1)); python$${_py_\#python*} -c 'from distutils.command.build import build; from distutils.core import Distribution; b = build(Distribution()); b.finalize_options(); print(b.build_platlib)') # Arguments to pass to setup.py install py_setup_install_args = --install-layout=deb python-defaults-2.7.12/debian/idle.10000664000000000000000000000473412057417145014060 0ustar .TH IDLE 1 "21 September 2004" .SH NAME \fBIDLE\fP \- An Integrated DeveLopment Environment for Python .SH SYNTAX .B idle [ \fI-dins\fP ] [ \fI-t title\fP ] [ \fIfile\fP ...] .PP .B idle [ \fI-dins\fP ] [ \fI-t title\fP ] ( \fI-c cmd\fP | \fI-r file\fP ) [ \fIarg\fP ...] .PP .B idle [ \fI-dins\fP ] [ \fI-t title\fP ] - [ \fIarg\fP ...] .SH DESCRIPTION This manual page documents briefly the .BR idle command. This manual page was written for Debian because the original program does not have a manual page. For more information, refer to IDLE's help menu. .PP .B IDLE is an Integrated DeveLopment Environment for Python. IDLE is based on Tkinter, Python's bindings to the Tk widget set. Features are 100% pure Python, multi-windows with multiple undo and Python colorizing, a Python shell window subclass, a debugger. IDLE is cross-platform, i.e. it works on all platforms where Tk is installed. .LP .SH OPTIONS .TP .B \-h .PD Print this help message and exit. .TP .B \-n .PD Run IDLE without a subprocess (see Help/IDLE Help for details). .PP The following options will override the IDLE 'settings' configuration: .TP .B \-e .PD Open an edit window. .TP .B \-i .PD Open a shell window. .PP The following options imply \-i and will open a shell: .TP .B \-c cmd .PD Run the command in a shell, or .TP .B \-r file .PD Run script from file. .PP .TP .B \-d .PD Enable the debugger. .TP .B \-s .PD Run $IDLESTARTUP or $PYTHONSTARTUP before anything else. .TP .B \-t title .PD Set title of shell window. .PP A default edit window will be bypassed when \-c, \-r, or \- are used. .PP [arg]* and [file]* are passed to the command (\-c) or script (\-r) in sys.argv[1:]. .SH EXAMPLES .TP idle .PD Open an edit window or shell depending on IDLE's configuration. .TP idle foo.py foobar.py .PD Edit the files, also open a shell if configured to start with shell. .TP idle \-est "Baz" foo.py .PD Run $IDLESTARTUP or $PYTHONSTARTUP, edit foo.py, and open a shell window with the title "Baz". .TP idle \-c "import sys; print sys.argv" "foo" .PD Open a shell window and run the command, passing "\-c" in sys.argv[0] and "foo" in sys.argv[1]. .TP idle \-d \-s \-r foo.py "Hello World" .PD Open a shell window, run a startup script, enable the debugger, and run foo.py, passing "foo.py" in sys.argv[0] and "Hello World" in sys.argv[1]. .TP echo "import sys; print sys.argv" | idle - "foobar" .PD Open a shell window, run the script piped in, passing '' in sys.argv[0] and "foobar" in sys.argv[1]. .SH SEE ALSO python(1). .SH AUTHORS Various. python-defaults-2.7.12/debian/python-minimal.manpages0000664000000000000000000000002612057417145017531 0ustar pyclean.1 pycompile.1 python-defaults-2.7.12/debian/python-policy.sgml0000664000000000000000000011263012474363312016555 0ustar Debian Python Policy Neil Schemenauer nas@debian.org Matthias Klose doko@debian.org Gregor Hoffleit flight@debian.org Josselin Mouette joss@debian.org Joe Wreschnig piman@debian.org Loïc Minier lool@debian.org Scott Kitterman scott@kitterman.com Barry Warsaw barry@debian.org version 0.10.0.2 This document describes the packaging of Python within the Debian GNU/Linux distribution and the policy requirements for packaged Python programs and modules. Copyright © 1999—2014 Software in the Public Interest

This manual is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.

This is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

A copy of the GNU General Public License is available as /usr/share/common-licences/GPL in the Debian GNU/Linux distribution or on the World Wide Web at .

You can also obtain it by writing to the Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.

On the move to Python 3

Debian currently supports two Python stacks, one for Python 2 and one for Python 3. The long term goal for Debian is to reduce this to one stack, dropping the Python 2 stack at some time. states that no more major Python 2 releases are planned, although the last released major version 2.7 will see some extended support, documented in .

Packages in Debian should use Python 3 if Python 3 is supported. New packages should use Python 3 from the initial upload, new upstream versions for existing packages should use Python 3 if the new upstream version supports it.

Programs should use Python 3, and should not be packaged for Python 2 as well. Python 3 should be used for the packaging if the packaging scripts use Python.

Python libraries should be always packaged for Python 3 if supported. Python 2 libraries should be packaged, if applications found in the reverse dependencies are not yet supported by Python 3.

Existing Python 2 libraries should not be dropped before the last reverse dependency is removed.

Python Packaging Versions

At any given time, the binary package python will represent the current default Debian Python version. The binary package python3 will represent the current Debian Python 3 version. As far as is reasonable, python and python3 should be treated as separate runtime systems with minimal interdependencies. In some cases, Python policy explicitly references Python helper programs such as python-support and python-central. None of these references apply to Python 3. It is a design goal to fully specify required interfaces and functions in policy for Python 3 and to avoid enshrining specific implementation details in policy. Except as noted, policy for Python 3 is the same as Python with the addition of the version number as needed to distinguish them.

The default Debian Python version should always be the latest stable upstream release that can be fully integrated in the distribution. There may be newer supported or unsupported versions included in the distribution if they are not fully integrated for a particular release.

Apart from the default version, legacy versions of Python or beta versions of future releases may be included as well in the distribution, as long as they are needed by other packages, or as long as it seems reasonable to provide them. (Note: For the scope of this document, Python versions are synonymous to feature releases, i.e. Python 2.7 and 2.7.1 are sub-minor versions of the same Python version 2.7, but Python 2.6 and 2.7 are indeed different versions.)

For any version, the main binary package must be called pythonX.Y.

The set of currently supported python versions can be found in /usr/share/python/debian_defaults, the set of currently supported python3 versions can be found in /usr/share/python3/debian_defaults. These files are in Python ConfigParser format and defines four variables in its DEFAULT section: default-version which is the current default Python runtime, supported-versions which is the set of runtimes currently supported and for which modules should be built and byte-compiled, old-versions which is the list of runtimes which might still be on the system but for which should not be built anymore, and unsupported-versions which is the list of runtimes which should not be supported at all, that is modules should not be built or byte-compiled for these. The supported interface to this file is /usr/bin/pyversions. The Python 3 interface is through /usr/bin/py3versions.

unsupported-versions is a superset of (includes) old-versions and the default-version is always in supported-versions.

Newer versions might also appear in unsupported-versions before being moved to supported-versions.

Main packages

For every Python version provided in the distribution, the binary package pythonX.Y shall provide a complete distribution for deployment of Python scripts and applications. The package must ensure that the binary /usr/bin/pythonX.Y is provided.

Installation of pythonX.Y shall provide the modules of the upstream Python distribution with some exceptions.

Excluded are modules that cannot be included for licensing reasons (for example the profile module), for dependency tracking purposes (for example the GPL-licensed gdbm module) or that should not be included for packaging reasons (for example the tk module which depends on Xorg). Some tools and files for the development of Python modules are split off in a separate binary package pythonX.Y-dev. Documentation will be provided separately as well.

At any time, the python binary package must ensure that /usr/bin/python is provided as a symlink to the current pythonX.Y executable. The python binary package must also depend on the appropriate pythonX.Y to ensure this runtime is installed.

The version of the python binary package must be greater than or equal to X.Y and smaller than X.Y+1.

Because upstream has started providing it, there will be a symlink for /usr/bin/python2 for Wheezy and later releases. See for details. Packages must be careful to depend on a sufficient version of python if they make use of this symlink.

Minimal packages

For every Python version provided in the distribution, the binary package pythonX.Y-minimal might exist and should not be depended upon by other packages except the Python runtime packages themselves.

Python Interpreter Interpreter Name

Python scripts depending on the default Python version (see ) or not depending on a specific Python version should use python (without a version) as the interpreter name.

Python scripts that only work with a specific Python version must explicitly use the versioned interpreter name (pythonX.Y).

Interpreter Location

The preferred specification for the Python interpreter is /usr/bin/python or /usr/bin/pythonX.Y. This ensures that a Debian installation of python is used and all dependencies on additional python modules are met.

Maintainers should not override the Debian Python interpreter using /usr/bin/env python or /usr/bin/env pythonX.Y. This is not advisable as it bypasses Debian's dependency checking and makes the package vulnerable to incomplete local installations of python.

Module Path

By default, Python modules are searched in the directories listed in the PYTHONPATH environment variable and in the sys.path Python variable. Since python2.4 version 2.4.5-3, python2.5 version 2.5.2-7, python2.6 version 2.6.2-1, and in all python2.7 versions, sys.path does not include a /usr/lib/pythonXY.zip entry anymore. Directories with private Python modules must be absent from the sys.path. Public Python modules not handled by python-central or python-support must be installed in the system Python modules directory, /usr/lib/pythonX.Y/dist-packages for python2.6 and later, and /usr/lib/pythonX.Y/site-packages for python2.5 and earlier. Public Python 3 modules must be installed in /usr/lib/python3/dist-packages. Modules managed by python-support are installed in another directory which is added to the sys.path using the .pth mechanism. The .pth mechanism is documented in the Python documentation of the site module. A special directory is dedicated to public Python modules installed by the local administrator, /usr/lib/python3/dist-packages for all python3 versions, /usr/local/lib/python2.Y/dist-packages for python2.6 and later, and /usr/local/lib/python2.Y/site-packages for python2.5 and earlier. For a local installation by the administrator of python2.6 and later, a special directory is reserved to Python modules which should only be available to this Python, /usr/local/lib/python2.Y/site-packages (and /usr/local/lib/python3/site-packages for all python3 versions). Unfortunately, for python2.5 and earlier this directory is also visible to the system Python. Additional information on appending site-specific paths to the module search path is available in the official documentation of the site module.

When binary packages ship identical source code for multiple Python versions, for instance /usr/lib/python2.6/dist-packages/foo.py and /usr/lib/python2.5/site-packages/foo.py, these should point to a common file. Version specific directories for identical source code are not required for python3 and must not be used for this. Since python2.7 is the last python2 version and the only supported version in wheezy and later releases, a common location to share arch-independent files across Python versions is no longer needed. Historically the location for this was /usr/share/pyshared. For python2.7, use of /usr/lib/python2.7/dist-packages is sufficient. For python3, a special location is not required, use /usr/lib/python3/dist-packages

Hooks for updates to installed runtimes

The python binary package has special hooks to allow other packages to act upon updates to the installed runtimes. This mechanism is required to handle changes of the default Python runtime in some packages and to enable the Python packaging helpers. There are three supported hook types which come in the form of scripts which are invoked from the maintainer scripts of the Python runtime packages when specific installations, removals, or upgrades occur.

/usr/share/python/runtime.d/*.rtinstall: these are called when a runtime is installed or becomes supported. The first argument is "rtinstall", the second argument is the affected runtime (for example pythonX.Y) and the third and fourth argument are the old and new version of this packaged runtime if this runtime was already installed but unsupported.

/usr/share/python/runtime.d/*.rtremove: these are called when a runtime is removed or stops being supported. The first argument is "rtremove", and the second argument is the affected runtime (for example pythonX.Y).

/usr/share/python/runtime.d/*.rtupdate: these are called when the default runtime changes. The first argument is either "pre-rtupdate", called before changing the default runtime, or "rtupdate", called when changing the default runtime, or "post-rtupdate", called immediately afterwards. The second argument is the old default runtime (for example pythonX.Y), and the third argument is the new default runtime (for example pythonX.Z).

Documentation

Python documentation is split out in separate binary packages pythonX.Y-doc. The binary package python-doc will always provide the documentation for the default Debian Python version.

TODO: Policy for documentation of third party packages.

Packaged Modules

The goal of these policies is to reduce the work necessary for Python transitions. Python modules are internally very dependent on a specific Python version. However, we want to automate recompiling modules when possible, either during the upgrade itself (re-byte-compiling pyc and pyo files) or shortly thereafter with automated rebuilds (to handle C extensions). These policies encourage automated dependency generation and loose version bounds whenever possible. Types of Python Modules

There are two kinds of Python modules, "pure" Python modules, and extension modules. Pure Python modules are Python source code that generally works across many versions of Python. Extensions are C code compiled and linked against a specific version of the python runtime, and so can only be used by one version of Python. Some distributions link extensions to libpython, but this is not the case in Debian as symbols might as well be resolved by /usr/bin/pythonX.Y which is not linked to libpython.

Python packages are a way of structuring Python’s module namespace by using “dotted module names”. See for details on how packages are defined in Python terms (A package in the Python sense is unrelated to a Debian package). Python packages must be packaged into the same directory (as done by upstream). Splitting components of a package across directories changes the import order and may confuse documentation tools and IDEs.

There are two ways to distribute Python modules. Public modules are installed in a public directory as listed in . They are accessible to any program. Private modules are installed in a private directory such as /usr/share/package-name or /usr/lib/package-name. They are generally only accessible to a specific program or suite of programs included in the same package.

Wheels

defines a built-package format called "wheels", which is a zip format archive containing Python code and a "dist-info" metadata directory, in a single file named with the .whl suffix. As zip files, wheels containing pure-Python can be put on sys.path and modules in the wheel can be imported directly by Python's "import" statement. (Importing extension modules from wheels is not yet supported as of Python 3.4.)

Except as described below, packages must not build or provide wheels. They are redundant to the established way of providing Python libraries to Debian users, take no advantage of distro-based tools, and are less convenient to use. E.g. they must be explicitly added to sys.path, cannot be easily grepped, and stack traces through zips are more difficult to debug.

A very limited set of wheel packages are available in the archive, but these support the narrow purpose of enabling the pip tool, in a Debian policy compliant way. The set of packages providing wheels for this purpose are (by source package name): chardet, distlib, html5lib, python-colorama, python-pip, python-setuptools, python-urllib3, requests, and six.

Wheel packages supporting pyvenv and pip are named with the python- prefix, and the -whl suffix, e.g. python-chardet-whl. When these binary packages are installed, their .whl files must be placed in the /usr/share/python-wheels directory. Such wheels must be built with the --universal flag so as to generate wheels compatible with both Python 2 and Python 3.

Module Package Names

Public modules used by other packages must have their binary package name prefixed with python-. It is recommended to use this prefix for all packages with public modules as they may be used by other packages in the future. Python 3 modules must be in a separate binary package prefixed with python3- to preserve run time separation between python and python3. The binary package for module foo should preferably be named python-foo, if the module name allows, but this is not required if the binary package ships multiple modules. In the latter case the maintainer chooses the name of the module which represents the package the most. For subpackages such as foo.bar, the recommendation is to name the binary packages python-foo.bar and python3-foo.bar. Such a package should support the current Debian Python version, and more if possible (there are several tools to help implement this, see ). For example, if Python 2.5, 2.6, and 2.7 are supported, the Python statement import foo should import the module when the user is running any of /usr/bin/python2.5, /usr/bin/python2.6, and /usr/bin/python2.7. This requirement also applies to extension modules; binaries for all the supported Python versions should be included in a single package.

Specifying Supported Versions

The optional X-Python-Version (preferred) or XS-Python-Version field in the general paragraph (the first one, for the source package) of debian/control specifies the versions of Python (not versions of Python 3) supported by the source package. Similarly, X-Python3-Version is used to specify the versions of Python 3 supported by the package. When not specified, they default to all currently supported Python (or Python 3) versions. They are used by some packaging scripts to automatically generate appropriate Depends and Provides lines. The format of the field may be one of the following: X-Python-Version: >= X.Y X-Python-Version: >= A.B, << X.Y XS-Python-Version: A.B, X.Y XS-Python-Version: all The keyword "all" means that the package supports any Python version available but might be deprecated in the future since using version numbers is clearer than "all" and encodes more information. The keyword "all" is limited to Python versions and must be ignored for Python 3 versions. Lists of multiple individual versions (e.g. 2.4, 2.5, 2.6) work for XS-Python-Version and will continue to be supported, but are not recommended and are not supported by X-Python-Version or X-Python3-Version for Wheezy and later releases. The keyword "current" has been deprecated and used to mean that the package would only have to support a single version (even across default version changes). It must be ignored for Python 3 versions.

The use of XB-Python-Version in the binary package paragraphs of debian/control file has been deprecated and should be removed in the normal course of package updates. It never achieved sufficient deployment to support it's intended purpose of managing Python transitions. This can be adequately accomplished by examining package dependencies.

Dependencies

Packaged modules available for the default Python version (or many versions including the default) as described in must depend on "python (>= X.Y)". If they require other modules to work, they must depend on the corresponding python-foo. They must not depend on any pythonX.Y-foo.

Packaged modules available for one particular version of Python must depend on the corresponding pythonX.Y package instead. If they need other modules, they must depend on the corresponding pythonX.Y-foo packages, and must not depend on any python-foo.

Provides

Provides in binary packages of the form python-X.Y>foo must be specified if the package contains an extension for more than one python version and an other package with version specific dependencies on the package require it. Provides are only for extensions, not modules. Provides should only be rarely used for Python packages and never for Python 3.

Modules Byte-Compilation

If a binary package provides any binary-independent modules (foo.py files), the corresponding byte-compiled modules (foo.pyc files) and optimized modules (foo.pyo files) must not ship in the package. Instead, they should be generated in the package's postinst, and removed in the package's prerm. The package's prerm has to make sure that both foo.pyc and foo.pyo are removed.

A binary package should only byte-compile the files which belong to the package.

The file /etc/python/debian_config allows configuration how modules should be byte-compiled. The postinst scripts should respect these settings.

Pure Python modules in private installation directories that are byte-compiled with the default Python version must be forcefully byte-compiled again when the default Python version changes. Public Python extensions should be bin-NMUed. Private Python extensions should be subject to binary NMUs every time the default interpreter changes, unless the extension is updated through a .rtupdate script.

Python Programs Programs using the default python

Programs that can run with any version of Python must begin with #!/usr/bin/python or #!/usr/bin/env python (the former is strongly preferred). They must also specify a dependency on python, with a versioned dependency if necessary.

If the program needs the python module foo, it must depend on the real package providing this module, usually python-foo but this name might vary when the package ships multiple modules.

Programs Shipping Private Modules

A program using /usr/bin/python as interpreter can come up with private Python modules. These modules should be installed in /usr/share/module, or /usr/lib/module if the modules are architecture-dependent (e.g. extensions).

The rules explained in apply to those private modules: the byte-compiled modules must not be shipped with the binary package, they should be generated in the package's postinst, using the current default Python version, and removed in the prerm. Modules should be byte-compiled using the current default Python version.

Programs that have private compiled extensions must either handle multiple version support themselves, or declare a tight dependency on the current Python version (e.g. Depends: python (>= 2.6), python (<< 2.7). No tools currently exist to alleviate this situation.

Programs Using a Particular Python Version

A program which requires a specific version of Python must begin with #!/usr/bin/pythonX.Y (or #!/usr/bin/env pythonX.Y). It must also specify a dependency on pythonX.Y and on any pythonX.Y-foo package providing necessary modules. It should not depend on any python-foo package, unless it requires a specific version of the package (since virtual packages cannot be versioned). If this is the case, it should depend on both the virtual package and the main package (e.g. Depends: python2.7-foo, python-foo (>= 1.0)).

The notes on installation directories and byte-compilation for programs that support any version of Python also apply to programs supporting only a single Python version. Modules to be byte-compiled should use the same Python version as the package itself.

Programs Embedding Python Building Embedded Programs

Programs which embed a Python interpreter must declare a Build-Depends on pythonX.Y-dev, where pythonX.Y is the python version the program builds against. It should be the current default python version unless the program does not work correctly with this version.

Embedded Python Dependencies

Dependencies for programs linking against the shared Python library will be automatically created by dpkg-shlibdeps. The libpythonX.Y.so.Z library the program is built against is provided by the pythonX.Y package.

Interaction with Locally Installed Python Versions

As long as you don't install other versions of Python in your path, Debian's Python versions won't be affected by a new version.

If you install a different sub-release of the version of python you have got installed, you will need to be careful to install all the modules you use for that version of python too.

Build Dependencies

Build dependencies for Python dependent packages must be declared for every Python version that the package is built for. The python-all-dev should be used when building extensions for any or all Python versions. To build for a specific version or versions, Build-Depend on pythonX.Y-dev.

Some applications and pure Python modules may be able to build-depend only on python or python-all and not require the -dev packages. Packages that do not require the -dev packages must not build-depend on them.

Build-Depend on at least: Build-Depends: python2.7 Build-Depends: python2.6 (>= 2.6-1) Build-Depends: python (>= 2.6.6-9) Build-Depends: python-all Build-Depends: python2.7-dev Build-Depends: python2.6-dev (>= 2.6-1) Build-Depends: python-dev (>= 2.6.6-9) Build-Depends: python-all-dev Build-Depends: python3-all-dev (>= 3.2)

If you use either python-support or python-central you must additionally Build-Depend on those.

Packaging Tools

This section describes the various tools to help package Python programs and modules for Debian. Although none of these tools are mandatory, their use is strongly encouraged, as the above policy has been designed with them in mind (and vice versa). This appendix is just an overview. If you use these tools, you should read their full documentation.

distutils

The standard Python distutils module has been modified in Debian to change the default installation directory of public Python modules and to add a new flag to the "install" command to override the default, --install-layout=. To allow the use this flag, maintainers should ensure that at least version 2.6.2-1 will be used for python2.6, version 2.5.4-1 for python2.5, and version 2.4.6-2 for python2.4. This flag is parsed but ignored in python2.4 and python2.5. Public Python modules installed with a modified distutils default to /usr/local/lib/pythonX.Y/dist-packages for python2.6 and later. This directory is seen by the system-provided python2.6. When using a system-provided python2.4 or python2.5, the default is /usr/lib/pythonX.Y/site-packages which is seen by the system-provided python2.4 and python2.5 versions, but not by a system-provided python2.6 and later versions. When using a local Python installation, the default is /usr/local/lib/pythonX.Y/site-packages which is only seen by the local Python installation. Using the --install-layout=deb flag to the "install" command of setup.py with a system-provided python2.6 or later versions, Python modules will be installed to /usr/lib/pythonX.Y/dist-packages which is only seen by the system-provided python, not by a local installation. Using the --install-layout=deb flag to setup.py with a system-provided python2.4 or python2.5 does not affect the default installation directory.

python-support (deprecated)

python-support is deprecated. It is a system intended to provide a simple way to byte-compile pure Python modules and manage dependencies. It integrates with debhelper, manages byte-compilation, private modules, integrates with runtime update hooks, and will fill-in the ${python:Depends}, ${python:Versions}, and ${python:Provides} substvars. See the python-support documentation in /usr/share/doc/python-support for details.

python-central (removed)

python-central has been removed from Jessie and later releases. It provided another way to manage Python modules.

CDBS

The CDBS python-distutils.mk class helps packaging of setup.py based Python packages.

dh_python2 and dh_python3

dh_python2 and dh_python3 are debhelper extensions provided as part of Python and Python3 to make it easier to package Python modules and extensions. They calculate Python dependencies, add maintainer scripts to byte compile files, etc. Their use is not mandatory, but they are recommended by the Python maintainers. See man dh_python2 or man dh_python3 for details.

Upgrade Procedure

This section describes the procedure for the upgrade when the default python version is changed in the unstable distribution, requiring recompilation of many python-related packages.

Selected pre-releases and release candidates of new Python versions are uploaded to Experimental to support pre-transition work and testing.

Application and module maintainers make sourceful changes where needed to prepare for the new Python version when needed.

Have a long and heated discussion.

The Debian Python maintainer and module/application maintainers discuss the readiness for a new default Debian Python version and associated packaging/policy changes. Once there is some consensus, the Python maintainer announces the upgrade and uploads to Unstable.

Upload of the python core meta-packages python, python-dev, python-doc and several python-module, depending on the new pythonX.Y, pythonX.Y-dev and so on.

The release team schedules rebuilds for packages that may need it. Packages that require additional manual work get updated and uploaded.

python-defaults-2.7.12/debian/python.postinst.in0000664000000000000000000001132112057417145016602 0ustar #! /bin/sh set -e new_config_file() { cat > /etc/python/debian_config <<-EOF [DEFAULT] # how to byte-compile (comma separated: standard, optimize) byte-compile = standard EOF } case "$1" in configure) [ -d /etc/python ] || mkdir /etc/python [ -f /etc/python/debian_config ] || new_config_file # run the rtinstall script, when 2.5 became a supported version if [ -x /usr/bin/python2.5 ] && [ -n "$2" ] && dpkg --compare-versions $2 lt 2.4.4-3; then if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "Linking and byte-compiling packages for runtime python2.5..." fi version=$(dpkg -s python2.5-minimal | awk '/^Version:/ {print $2}') for hook in /usr/share/python/runtime.d/*.rtinstall; do [ -x $hook ] || continue $hook rtinstall python2.5 "$2" "$version" done fi # run the rtinstall script, when 2.6 became a supported version if [ -x /usr/bin/python2.6 ] && [ -n "$2" ] && dpkg --compare-versions $2 lt 2.5.4-6; then if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "Linking and byte-compiling packages for runtime python2.6..." fi version=$(dpkg -s python2.6-minimal | awk '/^Version:/ {print $2}') for hook in /usr/share/python/runtime.d/*.rtinstall; do [ -x $hook ] || continue $hook rtinstall python2.6 "$2" "$version" done fi # run the rtinstall script, when 2.7 became a supported version if [ -x /usr/bin/python2.7 ] && [ -n "$2" ] && dpkg --compare-versions $2 lt 2.6.6-13; then if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "Linking and byte-compiling packages for runtime python2.7..." fi version=$(dpkg -s python2.7-minimal | awk '/^Version:/ {print $2}') for hook in /usr/share/python/runtime.d/*.rtinstall; do [ -x $hook ] || continue $hook rtinstall python2.7 "$2" "$version" done fi if [ -n "$2" ] && dpkg --compare-versions $2 lt 2.7.2-7~; then oldv=$(echo $2 | sed 's/^\(...\).*/\1/') if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "running python rtupdate hooks for @PVER@..." fi for hook in /usr/share/python/runtime.d/*.rtupdate; do [ -x $hook ] || continue if ! $hook rtupdate python$oldv @PVER@; then hb=$(basename $hook .rtupdate) echo >&2 "error running python rtupdate hook $hb" errors=yes fi done [ -z "$errors" ] || exit 4 if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "running python post-rtupdate hooks for @PVER@..." fi for hook in /usr/share/python/runtime.d/*.rtupdate; do [ -x $hook ] || continue if ! $hook post-rtupdate python$oldv @PVER@; then hb=$(basename $hook .rtupdate) echo >&2 "error running python post-rtupdate hook $hb" errors=yes fi done [ -z "$errors" ] || exit 5 fi if [ -f /var/lib/python/python2.5_already_installed ] \ && [ ! -f /var/lib/python/python2.5_installed ] then if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "Linking and byte-compiling packages for runtime python2.5..." fi oldversion=$(cat /var/lib/python/python2.5_already_installed) newversion=$(dpkg -s python2.5-minimal | awk '/^Version:/ {print $2}') for hook in /usr/share/python/runtime.d/*.rtinstall; do [ -x $hook ] || continue $hook rtinstall python2.5 "$oldversion" "$newversion" done fi rm -f /var/lib/python/python2.5_already_installed if [ -f /var/lib/python/python2.6_already_installed ] \ && [ ! -f /var/lib/python/python2.6_installed ] then if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "Linking and byte-compiling packages for runtime python2.6..." fi oldversion=$(cat /var/lib/python/python2.6_already_installed) newversion=$(dpkg -s python2.6-minimal | awk '/^Version:/ {print $2}') for hook in /usr/share/python/runtime.d/*.rtinstall; do [ -x $hook ] || continue $hook rtinstall python2.6 "$oldversion" "$newversion" done fi rm -f /var/lib/python/python2.6_already_installed if [ -f /var/lib/python/python2.7_already_installed ] \ && [ ! -f /var/lib/python/python2.7_installed ] then if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "Linking and byte-compiling packages for runtime python2.7..." fi oldversion=$(cat /var/lib/python/python2.7_already_installed) newversion=$(dpkg -s python2.7-minimal | awk '/^Version:/ {print $2}') for hook in /usr/share/python/runtime.d/*.rtinstall; do [ -x $hook ] || continue $hook rtinstall python2.7 "$oldversion" "$newversion" done fi rm -f /var/lib/python/python2.7_already_installed rmdir --ignore-fail-on-non-empty /var/lib/python 2>/dev/null || true esac #DEBHELPER# python-defaults-2.7.12/debian/rules0000775000000000000000000003220713205532536014133 0ustar #!/usr/bin/make -f # Sample debian/rules that uses debhelper. GNU copyright 1997 by Joey Hess. export SHELL = /bin/bash # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 DEB_HOST_ARCH := $(shell dpkg-architecture -qDEB_HOST_ARCH) DEB_HOST_MULTIARCH := $(shell dpkg-architecture -qDEB_HOST_MULTIARCH) DEB_HOST_GNU_TYPE := $(shell dpkg-architecture -qDEB_HOST_GNU_TYPE) changelog_values := $(shell dpkg-parsechangelog \ | awk '/^(Version|Source):/ {print $$2}') PKGSOURCE := $(word 1, $(changelog_values)) PKGVERSION := $(word 2, $(changelog_values)) distribution := $(shell dpkg-vendor --query Vendor) distrelease := $(shell lsb_release -cs) export VER=2.7 export NVER=2.8 export PVER=python2.7 PREVVER := $(shell awk '/^python/ && NR > 1 {print substr($$2,2,length($$2)-2); exit}' debian/changelog) # first version with Multi-Arch: allowed PREVVER := 2.7.12-1~ # not yet allowed ma_allowed = yes ifeq (,$(filter $(distrelease),lenny etch squeeze wheezy lucid maverick natty oneiric precise quantal raring saucy trusty)) bd_i586 = dpkg-dev (>= 1.17.11), python2.7 (>= 2.7.12-1) endif PWD := $(shell pwd) d := debian/tmp scriptdir = usr/share/lib/python$(VER) scriptdir = usr/share/python$(VER) scriptdir = usr/lib/python$(VER) rst2html = rst2html with_doc = yes ifneq ($(with_doc),yes) NOPKGS = -Npython-doc endif build: stamp-build build-arch: stamp-build build-indep: stamp-build stamp-build: touch stamp-build stamp-doc-policy: debiandoc2text debian/python-policy.sgml mv -f python-policy.txt debian/ debiandoc2html -l en.UTF-8 debian/python-policy.sgml rm -rf debian/python-policy.html mv -f python-policy.html debian/ make -C pydist touch stamp-doc-policy stamp-doc: stamp-doc-policy touch stamp-doc control-file: sed -e "s/@PVER@/$(PVER)/g" \ -e "s/@NVER@/$(NVER)/g" \ -e "s/@VER@/$(VER)/g" \ -e "s/@PREVVER@/$(PREVVER)/g" \ -e "s/@bd_i586@/$(bd_i586)/g" \ debian/control.tmp ifeq ($(distribution),Ubuntu) ifneq (,$(findstring ubuntu, $(PKGVERSION))) m='Ubuntu Developers '; \ sed -i "/^Maintainer:/s/\(.*\)/Maintainer: $$m\nXSBC-Original-\1/" \ debian/control.tmp endif endif [ -e debian/control ] \ && cmp -s debian/control debian/control.tmp \ && rm -f debian/control.tmp && exit 0; \ mv debian/control.tmp debian/control faqs = index general programming library extending windows gui installed get-faq: # Note: This rule is broken due to web site reorg at python.org rm -rf faq mkdir faq cd faq && \ wget -nv $(foreach p,$(faqs),http://python.org/doc/faq/$(p).ht) sed 's,\<\([a-zA-Z0-9]*\.html\)\>,faq/\1,' faq/index.ht \ | awk '/^Translations$$/ {exit} {print}' > faq/FAQ.ht ( \ echo ''; \ echo 'This is a local copy of the online FAQ located at'; \ echo 'http://python.org/doc/faq.'; \ echo "The copy was fetched and generated in `date '+%B %Y'`."; \ ) >> faq/FAQ.ht rm -f faq/index.ht make-faq: set -e; \ cd faq && \ for p in *.ht; do \ p=`basename $$p .ht`; \ echo $(rst2html) $$p.ht $$p.html; \ awk 'NR > 2' $$p.ht > $$p.ht2; \ $(rst2html) $$p.ht2 $$p.html; \ rm -f $$p.ht2; \ done MANPAGES ?= dh_python2.1 pycompile.1 pyclean.1 %.1: %.rst rst2man $< > $@ # Manually run this rule if there is a need to update the dh_python2 man pages make-man: $(MANPAGES) cd pydist && \ rst2html README.PyDist > README.PyDist.html clean: control-file dh_testdir dh_testroot rm -f stamp-* rm -f patch-stamp* rm -f debian/python-policy.txt rm -rf debian/python-policy.html set -e;\ for f in debian/*.in; do \ f2=`echo $$f | sed "s,PVER,$(PVER),g;s/VER/$(VER)/g;s,\.in$$,,"`; \ if [ $$f2 != debian/control ]; then \ rm -f $$f2; \ fi; \ done rm -f debian/*.py[co] make clean dh_clean stamp-control: : # We have to prepare the various control files set -e;\ for f in debian/*.in; do \ f2=`echo $$f | sed "s,PVER,$(PVER),g;s/VER/$(VER)/g;s,\.in$$,,"`; \ if [ $$f2 != debian/control ]; then \ sed -e "s/@PVER@/$(PVER)/g;s/@VER@/$(VER)/g" \ -e "s/@PRIORITY@/$(PRIORITY)/g" \ -e "s,@SCRIPTDIR@,/$(scriptdir),g" \ <$$f >$$f2; \ fi; \ done install: build stamp-dh_python stamp-install stamp-install: stamp-build control-file stamp-control dh_testdir dh_testroot dh_installdirs usr/share/doc/python/faq dh_install set -e; \ cd faq && \ for p in *.ht; do \ p=`basename $$p .ht`; \ cp $$p.html ../debian/python/usr/share/doc/python/faq/; \ done mv debian/python/usr/share/doc/python/faq/FAQ.html \ debian/python/usr/share/doc/python/ touch stamp-install stamp-dh_python: dh_testdir dh_testroot dh_installdirs -make check_versions DESTDIR=debian/python PREFIX=/usr make install-dev DESTDIR=debian/python-minimal PREFIX=/usr make install-runtime # disabled by default, run manually if you want to update it # (requires apt-file and network connection) #make -C pydist dist_fallback touch $@ # Build architecture-independent files here. binary-indep: build install stamp-doc dh_testdir -i dh_testroot -i dh_installman -i ifeq ($(with_doc),yes) mkdir -p debian/python-doc/usr/share/doc/python ln -sf ../python$(VER)-doc/html \ debian/python-doc/usr/share/doc/python/html mkdir -p debian/python-doc/usr/share/doc/python-doc ln -sf ../python$(VER)-doc/html \ debian/python-doc/usr/share/doc/python-doc/html endif : # provide the idle and idle.1 defaults mkdir -p debian/idle/usr/bin install -m 755 debian/idle.py debian/idle/usr/bin/idle mkdir -p debian/idle/usr/share/man/man1 install -m 644 debian/idle.1 debian/idle/usr/share/man/man1/idle.1 mkdir -p debian/idle/usr/share/pixmaps ln -sf python.xpm debian/idle/usr/share/pixmaps/idle.xpm mkdir -p debian/idle/usr/share/applications cp -p debian/idle.desktop debian/idle/usr/share/applications/ # dh_installdebconf -i $(NOPKGS) dh_lintian -i dh_installdocs -i $(NOPKGS) --all debian/README.Debian dh_installchangelogs -i $(NOPKGS) for p in examples idle; do \ [ $$p = idle ] || p=python-$$p; \ rm -rf debian/$$p/usr/share/doc/$$p; \ ln -sf python debian/$$p/usr/share/doc/$$p; \ done dh_compress -i $(NOPKGS) dh_fixperms -i $(NOPKGS) dh_installdeb -i $(NOPKGS) dh_gencontrol -i $(NOPKGS) dh_md5sums -i $(NOPKGS) dh_builddeb -i $(NOPKGS) # Build architecture-dependent files here. binary-arch: build install stamp-doc dh_testdir -a dh_testroot -a dh_installman -a : # provide the python and python.1 defaults mkdir -p debian/python-minimal/usr/bin ln -sf python$(VER) debian/python-minimal/usr/bin/python ln -sf python$(VER) debian/python-minimal/usr/bin/python2 mkdir -p debian/python-minimal/usr/share/man/man1 ln -sf python$(VER).1.gz \ debian/python-minimal/usr/share/man/man1/python.1.gz ln -sf python$(VER).1.gz \ debian/python-minimal/usr/share/man/man1/python2.1.gz : # mkdir -p debian/python-minimal/usr/share/python cp -p debian/debian_defaults \ debian/python-minimal/usr/share/python/ install -m 755 debian/pyversions.py \ debian/python-minimal/usr/share/python/ install -m 644 debian/pyversions.1 \ debian/python-minimal/usr/share/man/man1/ dh_link -ppython-minimal /usr/share/python/pyversions.py /usr/bin/pyversions # install -m 755 debian/pycompile \ # debian/python-minimal/usr/bin/ # install -m 755 debian/pyclean \ # debian/python-minimal/usr/bin/ # mkdir debian/python-minimal/usr/share/python-central # cp -p debian/python.pycentral debian/python-minimal/usr/share/python-central/ mkdir -p debian/python/usr/bin ln -sf pydoc$(VER) debian/python/usr/bin/pydoc ln -sf pygettext$(VER) debian/python/usr/bin/pygettext ln -sf pdb$(VER) debian/python/usr/bin/pdb ln -sf 2to3-$(VER) debian/python/usr/bin/2to3 mkdir -p debian/python/usr/share/python install -m 644 debian/python.mk \ debian/python/usr/share/python/ mkdir -p debian/python/usr/share/man/man1 ln -sf pydoc$(VER).1.gz \ debian/python/usr/share/man/man1/pydoc.1.gz ln -sf pygettext$(VER).1.gz \ debian/python/usr/share/man/man1/pygettext.1.gz ln -sf pdb$(VER).1.gz \ debian/python/usr/share/man/man1/pdb.1.gz ln -sf 2to3-$(VER).1.gz \ debian/python/usr/share/man/man1/2to3.1.gz mkdir -p debian/python/usr/share/doc/python cp -a debian/python-policy.{html,sgml,txt} \ debian/python/usr/share/doc/python/ mkdir -p debian/python/usr/share/pixmaps ln -sf python$(VER).xpm debian/python/usr/share/pixmaps/python.xpm : # add symlinks to policy files mkdir -p debian/python/usr/share/doc/python$(VER) for ext in html sgml.gz txt.gz; do \ ln -sf ../python/python-policy.$$ext \ debian/python/usr/share/doc/python$(VER)/python-policy.$$ext; \ done mkdir -p debian/python/usr/share/apps/konsole cp -p debian/python.desktop debian/python/usr/share/apps/konsole/ : # provide the python-config default mkdir -p debian/python-dev/usr/bin ln -sf python$(VER)-config debian/python-dev/usr/bin/python-config ln -sf python$(VER)-config debian/python-dev/usr/bin/python2-config mkdir -p debian/python-dev/usr/share/man/man1 ln -sf python$(VER)-config.1.gz \ debian/python-dev/usr/share/man/man1/python-config.1.gz ln -sf python$(VER)-config.1.gz \ debian/python-dev/usr/share/man/man1/python2-config.1.gz : # provide pkgconfig defaults mkdir -p debian/python-dev/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig ln -sf python-$(VER).pc debian/python-dev/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/python.pc ln -sf python.pc debian/python-dev/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/python2.pc mkdir -p debian/python-dbg/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig ln -sf python-$(VER)-dbg.pc debian/python-dbg/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/python-dbg.pc ln -sf python-dbg.pc debian/python-dbg/usr/lib/$(DEB_HOST_MULTIARCH)/pkgconfig/python2-dbg.pc : # provide the python-dbg and python-dbg.1 defaults mkdir -p debian/python-dbg/usr/bin ln -sf python$(VER)-dbg debian/python-dbg/usr/bin/python-dbg ln -sf python$(VER)-dbg debian/python-dbg/usr/bin/python2-dbg ln -sf python$(VER)-dbg-config debian/python-dbg/usr/bin/python-dbg-config ln -sf python$(VER)-dbg-config debian/python-dbg/usr/bin/python2-dbg-config mkdir -p debian/python-dbg/usr/share/man/man1 ln -sf python$(VER)-dbg.1.gz \ debian/python-dbg/usr/share/man/man1/python-dbg.1.gz ln -sf python$(VER)-dbg.1.gz \ debian/python-dbg/usr/share/man/man1/python2-dbg.1.gz ln -sf python$(VER)-dbg-config.1.gz \ debian/python-dbg/usr/share/man/man1/python-dbg-config.1.gz ln -sf python$(VER)-dbg-config.1.gz \ debian/python-dbg/usr/share/man/man1/python2-dbg-config.1.gz mkdir -p debian/python-dbg/usr/share/doc/python ln -sf ../python$(VER)/SpecialBuilds.txt.gz \ debian/python-dbg/usr/share/doc/python/SpecialBuilds.txt.gz ln -sf ../python$(VER)/README.debug \ debian/python-dbg/usr/share/doc/python/README.debug mkdir -p debian/python/usr/lib/valgrind cp -p debian/valgrind-python.supp \ debian/python/usr/lib/valgrind/python.supp : # provide the DEB_HOST_GNU_TYPE/DEB_HOST_MULTIRACH python-config defaults mkdir -p debian/libpython-dev/usr/bin ln -sf $(DEB_HOST_MULTIARCH)-python$(VER)-config \ debian/libpython-dev/usr/bin/$(DEB_HOST_MULTIARCH)-python-config mkdir -p debian/libpython-dev/usr/share/man/man1 ln -sf $(DEB_HOST_MULTIARCH)-python$(VER)-config.1.gz \ debian/libpython-dev/usr/share/man/man1/$(DEB_HOST_MULTIARCH)-python-config.1.gz ifneq ($(DEB_HOST_MULTIARCH),$(DEB_HOST_GNU_TYPE)) ln -sf $(DEB_HOST_GNU_TYPE)-python$(VER)-config \ debian/libpython-dev/usr/bin/$(DEB_HOST_GNU_TYPE)-python-config ln -sf $(DEB_HOST_GNU_TYPE)-python$(VER)-config.1.gz \ debian/libpython-dev/usr/share/man/man1/$(DEB_HOST_GNU_TYPE)-python-config.1.gz endif mkdir -p debian/libpython-dbg/usr/bin ln -sf $(DEB_HOST_MULTIARCH)-python$(VER)-dbg-config \ debian/libpython-dbg/usr/bin/$(DEB_HOST_MULTIARCH)-python-dbg-config mkdir -p debian/libpython-dbg/usr/share/man/man1 ln -sf $(DEB_HOST_MULTIARCH)-python$(VER)-dbg-config.1.gz \ debian/libpython-dbg/usr/share/man/man1/$(DEB_HOST_MULTIARCH)-python-dbg-config.1.gz ifneq ($(DEB_HOST_MULTIARCH),$(DEB_HOST_GNU_TYPE)) ln -sf $(DEB_HOST_GNU_TYPE)-python$(VER)-dbg-config \ debian/libpython-dbg/usr/bin/$(DEB_HOST_GNU_TYPE)-python-dbg-config ln -sf $(DEB_HOST_GNU_TYPE)-python$(VER)-dbg-config.1.gz \ debian/libpython-dbg/usr/share/man/man1/$(DEB_HOST_GNU_TYPE)-python-dbg-config.1.gz endif dh_lintian -a dh_installdocs -a $(NOPKGS) --all debian/README.Debian dh_installchangelogs -a $(NOPKGS) for p in all all-dev all-dbg dbg dev; do \ [ $$p = idle ] || p=python-$$p; \ rm -rf debian/$$p/usr/share/doc/$$p; \ ln -sf python debian/$$p/usr/share/doc/$$p; \ done rm -rf debian/libpython-all-dev/usr/share/doc/libpython-all-dev ln -sf libpython-dev debian/libpython-all-dev/usr/share/doc/libpython-all-dev rm -rf debian/libpython-all-dbg/usr/share/doc/libpython-all-dbg ln -sf libpython-dbg debian/libpython-all-dbg/usr/share/doc/libpython-all-dbg dh_compress -a $(NOPKGS) dh_fixperms -a $(NOPKGS) dh_installdeb -a $(NOPKGS) dh_gencontrol -a $(NOPKGS) dh_md5sums -a $(NOPKGS) dh_builddeb -a $(NOPKGS) # Build architecture-dependent files here. binary-arch: build install # nothing to do binary: binary-indep binary-arch .PHONY: control-file configure build clean binary-indep binary-arch binary install # Local Variables: # mode: makefile # end: python-defaults-2.7.12/debian/python-minimal.postinst.in0000664000000000000000000000013012057417145020222 0ustar #! /bin/sh set -e python@VER@ -m compileall /usr/share/python/ >/dev/null #DEBHELPER# python-defaults-2.7.12/debian/python.install0000664000000000000000000000005012057417145015755 0ustar pydist/dist_fallback /usr/share/python/ python-defaults-2.7.12/debian/python.doc-base.python-policy0000664000000000000000000000116612057417145020612 0ustar Document: python-policy Title: Debian Python Policy (Proposal) Author: Neil Schemenauer, Matthias Klose, Gregor Hoffleit Abstract: This document describes the packaging of Python within the Debian GNU/Linux distribution and the policy requirements for packaged Python programs and modules. . The Debian Python Policy has still a draft status. Section: Debian Format: debiandoc-sgml Files: /usr/share/doc/python/python-policy.sgml.gz Format: text Files: /usr/share/doc/python/python-policy.txt.gz Format: HTML Index: /usr/share/doc/python/python-policy.html/index.html Files: /usr/share/doc/python/python-policy.html/*.html python-defaults-2.7.12/debian/python.preinst.in0000664000000000000000000000436112057417145016411 0ustar #! /bin/sh set -e # remove the python alternatives before installing our own python link update-alternatives --auto /usr/bin/python >/dev/null 2>&1 || true update-alternatives --remove python /usr/bin/python1.5 || true update-alternatives --remove python /usr/bin/python2.1 || true update-alternatives --remove python /usr/bin/python2.2 || true [ -L /usr/share/doc/python/html ] || rm -rf /usr/share/doc/python/html case "$1" in upgrade) if dpkg --compare-versions $2 lt 2.6.1-1~; then oldv=$(echo $2 | sed 's/^\(...\).*/\1/') if [ "$DEBIAN_FRONTEND" != noninteractive ]; then echo "running python pre-rtupdate hooks for @PVER@..." fi for hook in /usr/share/python/runtime.d/*.rtupdate; do [ -x $hook ] || continue if ! $hook pre-rtupdate python$oldv @PVER@; then hb=$(basename $hook .rtupdate) echo >&2 "error running python pre-rtupdate hook $hb" echo >&2 "running python failed-pre-rtupdate hook $hb" $hook failed-pre-rtupdate python$oldv @PVER@ errors=yes break fi done [ -z "$errors" ] || exit 3 fi # 2.4.4-5 is the first version, which adds python2.5 as supported # version; need to run an rtinstall python2.5 in the postinst. if dpkg --compare-versions $2 lt 2.4.4-5 && [ -x /usr/bin/python2.5 ]; then version=$(dpkg -s python2.5-minimal | awk '/^Version:/ {print $2}') mkdir -p /var/lib/python echo "$version" > /var/lib/python/python2.5_already_installed fi # 2.5.4-6 is the first version, which adds python2.6 as supported # version; need to run an rtinstall python2.6 in the postinst. if dpkg --compare-versions $2 lt 2.5.4-6 && [ -x /usr/bin/python2.6 ]; then version=$(dpkg -s python2.6-minimal | awk '/^Version:/ {print $2}') mkdir -p /var/lib/python echo "$version" > /var/lib/python/python2.6_already_installed fi # 2.6.6-13 is now the first version, which adds python2.7 as supported # version; need to run an rtinstall python2.7 in the postinst. if dpkg --compare-versions $2 lt 2.6.6-13 && [ -x /usr/bin/python2.7 ]; then version=$(dpkg -s python2.7-minimal | awk '/^Version:/ {print $2}') mkdir -p /var/lib/python echo "$version" > /var/lib/python/python2.7_already_installed fi esac #DEBHELPER# python-defaults-2.7.12/debian/changelog0000664000000000000000000014022613205532536014726 0ustar python-defaults (2.7.12-1~16.04) xenial-proposed; urgency=medium * SRU. * Bump version to 2.7.12. LP: #1591895. * pycompile, pyclean, pyversions: Use python2 as the shebang to guard against people fiddling around with the python symlink or having a python3 installed as python in /usr/local. LP: #1715062. -- Matthias Klose Thu, 23 Nov 2017 12:47:42 +0100 python-defaults (2.7.11-1) unstable; urgency=medium * Bump version to 2.7.11. * Stop shipping menu files. * Fix some lintian warnings. -- Matthias Klose Wed, 09 Dec 2015 13:07:35 +0100 python-defaults (2.7.9-1) unstable; urgency=medium * Bump version to 2.7.9. -- Matthias Klose Mon, 16 Mar 2015 23:32:04 +0100 python-defaults (2.7.8-4) unstable; urgency=medium [ Barry Warsaw ] * Update policy document to clarify the purpose and use of the wheel files. No actual change in policy is made. -- Scott Kitterman Mon, 02 Mar 2015 15:45:19 -0500 python-defaults (2.7.8-3) unstable; urgency=medium [ Michael Gilbert ] * Make python-minimal a pre-dependency for python (closes: #769106). -- Scott Kitterman Mon, 02 Feb 2015 16:12:38 -0500 python-defaults (2.7.8-2) unstable; urgency=medium [ Matthias Klose ] * Build-depend on python2.7 and dpkg-dev versions to consistently generate the i586-* symlinks. Closes: #758301. [ Piotr Ożarowski ] * dh_python2: add a warning abount missing dh-python in Build-Depends [ Scott Kitterman ] * Minor updates to python policy - Reflect disuse of pyshared directory in favor of /usr/lib/python2.7/ dist-packages since python2.7 is the last and only python version supported (Closes: #763451) - Update python-central information to reflect its removal from Jessie -- Scott Kitterman Fri, 24 Oct 2014 10:58:42 -0400 python-defaults (2.7.8-1) unstable; urgency=medium [ Barry Warsaw ] * Fix typo in policy doc re: wheel package exception list. * Add myself to Uploaders. [ Scott Kitterman ] * Fix error in pydist package relationship regex (Closes: #735163) - Thanks to Rafael Laboissiere for the patch * Switch from using lsb-release to dpkg-vendor to determine distro and drop lsb-release from build-depends (Closes: #751706) - Thanks to Peter Pentchev for the patch * Drop unused build-depends on libhtml-tree-perl * Clarify discussion of requirement to use python:Provides (Closes: #669346) * Add clarification of naming requirements for submocules (Closes: #701192) * Minor cleanups in debian/pyversions.py * Stop automatically regenerating static content (dh_python2 man pages and Python FAQ) and drop build-dep on python-docutils to ease bootstrapping (Closes: #754060) - Add direct build-dep on python-all to replace indirect build-dep * Bump version to 2.7.8 * Drop ancient Breaks on python-csv, python-bz2, and python-email -- Scott Kitterman Fri, 11 Jul 2014 17:10:37 -0400 python-defaults (2.7.6-2) unstable; urgency=medium [ Barry Warsaw ] * Add python policy for Python Wheels. -- Scott Kitterman Wed, 21 May 2014 00:04:16 -0400 python-defaults (2.7.6-1) unstable; urgency=medium * Bump version to 2.7.6. * dh_python2: no longer move files to /usr/share/pyshared, don't create /usr/lib/pyshared symlinks for extensions. * Use UTF-8 encoding for the python policy in HTML format. Closes: #689931. * Add a chapter for the python policy to prefer Python 3 over Python 2. -- Matthias Klose Mon, 12 May 2014 12:16:34 +0200 python-defaults (2.7.5-5) unstable; urgency=low [ Steve Langasek ] * Adjust debpython/depends.py to be multiarch-friendly. [ Piotr Ożarowski ] * Set "Multi-Arch: allowed" in python, python-dev, python-minimal, python-dbg, python-all, python-all-dev, python-all-dbg * Replace /usr/bin/dh_python2 with a Python script that invokes dh-python's dh_python2 if Build-Depends{,-Indep} contains dh-python -- Piotr Ożarowski Thu, 12 Sep 2013 21:25:01 +0200 python-defaults (2.7.5-4) unstable; urgency=low * Add libpython-all-dbg.postinst to convert the doc directory to a symlink on upgrade (Closes: #718736) -- Scott Kitterman Tue, 13 Aug 2013 00:23:58 -0400 python-defaults (2.7.5-3) unstable; urgency=low [ Matthias Klose ] * Fix libpython-all-dbg doc dir symlink. Closes: #712270. [ Piotr Ożarowski ] * Replace /usr/bin/dh_python2 with a shell script that invokes dh-python's dh_python2 if debian/control mentions dh-python * dh_python2: warnings about --install-layout=deb and translating dependencies are just an info now -- Piotr Ożarowski Fri, 02 Aug 2013 08:54:32 +0200 python-defaults (2.7.5-2) unstable; urgency=low * Add dependencies on the new libpython-{stdlib,all-dev,all-dbg} packages. -- Matthias Klose Thu, 13 Jun 2013 15:07:18 +0200 python-defaults (2.7.5-1) unstable; urgency=low [ Matthias Klose ] * Bump version to 2.7.5. * Drop python2.6 as a supported python version. * Bump standards version to 3.9.4. * Start building the libpython-stdlib, libpython-all-dev, libpython-all-dbg packages. * Drop Python 2.6 as a supported Python version. * Fix some lintian warnings. [ Scott Kitterman ] * When X(S)-Python-Version or debian/pyversions is not present, do not describe them as missing, just indicate they are not there -- Matthias Klose Thu, 06 Jun 2013 14:57:03 +0200 python-defaults (2.7.3-13) experimental; urgency=low * Always build the policy files. -- Matthias Klose Thu, 28 Feb 2013 16:46:08 +0100 python-defaults (2.7.3-12) experimental; urgency=low * Move python-docutils to build-depends (from build-depends-indep). -- Matthias Klose Thu, 28 Feb 2013 15:58:09 +0100 python-defaults (2.7.3-11) experimental; urgency=low * Add Multi-Arch: same packages libpython-all-{dev,dbg} (not yet built, python2.6 doesn't have support for multiarch). * python-dbg: Stop providing python-gdbm-dbg, python-tk-dbg. Closes: #700716. * Add a libpython-stdlib package (not yet built). -- Matthias Klose Thu, 28 Feb 2013 14:43:06 +0100 python-defaults (2.7.3-10) experimental; urgency=low * Build dependency packages as architecture dependent packages. * Make python, python-{minimal,dev,dbg} Multi-Arch: allowed. * Build Multi-Arch: any packages libpython-{dev,dbg} packages providing $(DEB_HOST_GNU_TYPE/DEB_HOST_MULTIARCH)-python-config symlinks. * Provide python2 symlinks. -- Matthias Klose Wed, 12 Dec 2012 00:25:00 +0100 python-defaults (2.7.3-5) unstable; urgency=low * Drop Python 2.6 as a supported Python version. -- Matthias Klose Mon, 06 May 2013 02:48:48 +0200 python-defaults (2.7.3-4) unstable; urgency=low [ Dmitry Shachnev ] * Revert previous prerm/postrm changes: - prerm is never called as `prerm purge`. - configuration files shouldn't be deleted on package remove. -- Scott Kitterman Fri, 08 Feb 2013 16:26:12 -0500 python-defaults (2.7.3-3) unstable; urgency=low [ Piotr Ożarowski ] * dh_python2: - no longer sensitive to trailing slash in private dir names (closes: #686358) - ignore /usr/bin/python3 shebangs in all packages, not just in python3-* ones - generates correct "python (<< 2.X)" dependencies for packages with private Python extensions (typo fixed) * pyversions.py: fix parsing DEBPYTHON_SUPPORTED env. variable (versions should be separated using comma, as in debian_defaults config file) [ Dmitry Shachnev ] * debian/python.{pre,post}rm.in: Handle purge command the same way as remove (thanks to Mitsuya Shibata for the bug report) -- Piotr Ożarowski Sun, 21 Oct 2012 22:40:55 +0200 python-defaults (2.7.3-2) unstable; urgency=low * dh_python2: ignore empty files while trying to normalize shebangs (Closes: #680793) * Fix lack of python-imaging in pydist/dist_fallback - Add python-imaging override to pydist/generate_fallback_list.py - pydist/dist_fallback: Regenerate to add python-imaging (which wasn't recognized before due to .pth file) along with a few automatic adjustments -- Piotr Ożarowski Thu, 26 Jul 2012 23:03:32 +0200 python-defaults (2.7.3-1) unstable; urgency=low [ Piotr Ożarowski ] * dh_python2: - remove even more \.so.* dangling symlinks, thanks to Stefano Rivera for providing a test case - rewrite shebangs by default (disable via --no-shebang-rewrite), examples: + "/usr/bin/env python*" → "/usr/bin/python*" + "/usr/local/bin/python foo" → "/usr/bin/python foo" + "/usr/bin/python2" → "/usr/bin/python" - new --shebang option to replace all shebangs in bin dirs (example: --shebang /usr/bin/python2.6) - no longer generates python2.X | python2.Y depenendies for public modules (Closes: 625740) - translate Python version numbers into Debian ones for those require.txt items that have a pydist file with (uscan like) rules or PEP386 flag (Closes: #653740) * Improve dh_python2 manpage a bit, add information about cleaning debug packages (Closes: #653741) * pyversions, dh_python2, pycompile: allow to override system's list of supported Python versions via DEBPYTHON_SUPPORTED and default Python version via DEBPYTHON_DEFAULT env. variables * Debhelper's python2 sequence now inserts dh_python2 before dh_installinit (closes: 670418) [ Scott Kitterman ] * Bump upstream version to match current unstable/wheezy python2.7 version -- Piotr Ożarowski Sat, 30 Jun 2012 20:23:59 +0200 python-defaults (2.7.3~rc2-1) unstable; urgency=low [ Scott Kitterman ] * Bump minimum debhelper version to 8 so all tests will run - dh_python2 tests 1 - 5 require dh 7 and test 6 needs dh 8 * Move idle.xpm symlink from python to idle and add Breaks/Replaces * Move /usr/bin/pyversions from python to python-minimal since that's where the actual script it's a symlink to lives, add Breaks/Replaces * Bump standards version to 3.9.3 without further change * Correct Python package names with hyphens in them being ignored (Closes: #657665) * Drop -n from /usr/bin/idle invocations in debian/idle.desktop and debian/idle.menu (Closes: #482156) * Update Python policy - Describe addition of /usr/bin/python2 due to upstream changes - Remove redundant text on Python provides and clarify when they should be used - Update description of functionality related to X-Python-Version for Wheezy - Update X/XS-Python-Versions to also include X-Python-Version examples - Add appropriage Breaks/Replaces * Bump upstream version to match current unstable/wheezy python2.7 version [ Piotr Ożarowski ] * dh_python2, pyversions: make comparison of X(S)-Python-Version field names case-insensitive (Closes: #676224) -- Scott Kitterman Tue, 05 Jun 2012 22:43:11 -0400 python-defaults (2.7.2-10) unstable; urgency=low [ Matthias Klose ] * dh_python2: For argparse eggs, generate dependencies of the form "python (>= 2.7) | python-argparse". Closes: #653644, #657119. * Regenerate pydist/dist_fallback. [ Piotr Ożarowski ] * pycompile: fix -O option * dh_python2: do not try to add python2.X dependency if private dir works with all Python versions -- Matthias Klose Tue, 24 Jan 2012 11:49:24 +0100 python-defaults (2.7.2-9) unstable; urgency=low * Generate correct dependencies if private directory supports one Python version only (closes: #644573) -- Piotr Ożarowski Sat, 08 Oct 2011 17:16:46 +0200 python-defaults (2.7.2-8) unstable; urgency=high * Fix update-manager Breaks (Closes: #644491) -- Scott Kitterman Thu, 06 Oct 2011 15:48:06 -0500 python-defaults (2.7.2-7) unstable; urgency=low * Adjust version numbers for upload to unstable. * python: Break update-manager (<= 0.200.5-1). -- Matthias Klose Tue, 27 Sep 2011 18:21:42 +0200 python-defaults (2.7.2-6) experimental; urgency=low [ Scott Kitterman ] * Fixed typo in python-policy (thanks to Jakub Wilk) [ Piotr Ożarowski ] * dh_python2: - handle private dir paths without leading slash - add python to Depends if unversioned python shebang is detected in private directory - dist_fallback: add /usr/share/python-support/package/ to paths searched for Egg metadata; add "wsgiref" and "python" fallbacks - do not try to remove .so.foo symlinks twice (if files were listed in an unfortunate order) -- Piotr Ożarowski Sat, 24 Sep 2011 16:36:29 +0200 python-defaults (2.7.2-5) experimental; urgency=low [ Piotr Ożarowski ] * dh_python2: - generates rtupdate scripts for private directories that compile files from given package only, add --compile-all to dh_python2's call if you want the old behaviour (i.e. compile also files (plugins?) provided by other packages, which do not use a helper/bytecompile them) - add --no-dbg-cleaning option (to disable removing files from debug packages) - fix handling "distname[features]" in debpython.pydist.guess_dependency (closes: 636255) * pyclean now accepts --package and private dir argument at the same time [ Scott Kitterman ] * debpyhton/pydist: Incorporate patch from Jonathan Lange to stop printing to stderr (LP: #812960) * Add Piotr Ożarowski back to Uploaders -- Scott Kitterman Mon, 08 Aug 2011 10:28:50 -0400 python-defaults (2.7.2-4) experimental; urgency=low [ Piotr Ożarowski ] * dh_python2: - no longer moves .so.foo files to pyshared dir (closes: 635316) - replaces .so symlinks with .so.foo files in dist-packages [ Scott Kitterman ] * Drop python2 symlink pending further discussion (closes: 634967) * Update recent Python policy changes based on feedback from Debian Python -- Scott Kitterman Wed, 27 Jul 2011 10:15:38 -0400 python-defaults (2.7.2-3) experimental; urgency=low * python: Provide python profiler. * Provide a python2 symlink according to PEP 394. * Bump standards version. * Fix some lintian warnings. * Add 2to3.1 manual page symlink. -- Matthias Klose Sun, 10 Jul 2011 20:57:27 +0200 python-defaults (2.7.2-2) experimental; urgency=low [ Piotr Ożarowski ] * dh_python2: - no longer generates maintainer scripts that invoke pycentral's pkgremove script, use --clean-pycentral if you want the old behaviour - egg-info directories are parsed even if cleaning the name was necessary (thanks to Arnaud Fontaine for the patch) - private directory names with apostrophes are escaped properly in maintainer script's -X arguments (thanks to Jakub Wilk for the patch) - deal with original symlinks more carefully (closes: 627969, thanks to Leonid Borisenko for the original patch) - add --ignore-shebangs option that will disable translating shebangs into Debian dependencies - add --ignore-namespace option that will disable handling Egg-info's namespace_packages.txt (AKA namespace feature) - PyDist: update dist_fallback file (with atypical Debian package names) - disable PyDist feature if dh sequencer is invoked --with pydeb (closes: 630502, thanks to Gediminas Paulauskas for the original patch) - warn if public Python extension is linked to libpython2.X, fail if it's linked to a wrong version - warn if both XS-Python-Version and X-Python-Version are defined - private dirs: if there is more than one Python version parsed from shebangs, byte-compile the dir with default Python version (or the one requested via X-Python-Version) instead od failing. Add dependency for each (supported) interpreter detected in shebangs - /usr/share/pyshared is not added to the package if empty (closes: 623909) - dh_python2's manpage updated (among other changes, no longer advertises python:Breaks - closes: 631397, describes .pyinstall and .pyremove files) - remove setuptools from requires.txt (it is replaced with python-pkg-resources Debian dependency) - "--namespace foo" no longer triggers .../dist-packages/bar/foo/__init__.py creation, use "--namespace bar.foo" instead [ Scott Kitterman ] * Python policy: - Add deprecation information about python-central and python-support - Clarify Python module and package descriptions -- Scott Kitterman Thu, 07 Jul 2011 01:06:08 -0400 python-defaults (2.7.2-1) experimental; urgency=low [ Piotr Ożarowski ] * dh_python2: generate more strict dependencies for packages with private extensions (closes: #625760) [ Scott Kitterman ] * Set python2.7 as default for testing in experimental - Update version references in patching file debian/control, control.in, debian_defaults, python.postinst.in, python.preinst.in, pyversions.py, and rules -- Scott Kitterman Tue, 31 May 2011 07:44:33 -0400 python-defaults (2.6.6-14) unstable; urgency=low [ Piotr Ożarowski ] * python.mk: add py_builddir macro. $(call py_builddir, 2.6) returns "build/lib.linux-x86_64-2.6" on amd64 * dh_python2, pycompile, pyclean: add "namespace" feature: dh_python2 parses Egg's namespace_packages.txt files (in addition to --namespace command line argument(s)) and drops empty __init__.py files from binary package. pycompile will regenerates them at install time and pyclean will remove them at uninstall time (if they're no longer used in installed packages * Remove myself from Uploaders [ Scott Kitterman ] * Upload to Unstable (adds Python 2.7 as a supported Python in Unstable) * Drop python2.5 as a supported Python version - Update debian/debian_defaults - Update debpython/version.py - Update debian/control.in * Update copyright years for dh_python2, pycompile, pyclean and debpython in debian/copyright -- Scott Kitterman Fri, 15 Apr 2011 00:04:07 -0400 python-defaults (2.6.6-13) experimental; urgency=low * Add python2.7 as a supported Python version. * python-all{,-dev,-dbg}: Depend on the 2.7 packages. * Run the rtinstall script, when 2.7 became a supported version (2.6.6-13) and python2.7 is installed. * Python-minimal Breaks python-support (<< 1.0.12) -- Scott Kitterman Mon, 21 Mar 2011 10:53:42 -0400 python-defaults (2.6.6-12) unstable; urgency=low [ Piotr Ożarowski ] * dh_python2: - use Depends: python (<< 2.X), python (>= 2.Y) rather than Breaks in packages with public modules (after a discussion on debian-devel mailing list) - do not try to check dangling symlinks's shebang (closes: 619005) [ Scott Kitterman ] * Start Python Policy updates for Wheezy: - Document current practice to not provide /usr/bin/python2 - Strengthen warning aginst using /usr/bin/env python - Update paths section for python2.7 and python3 - Deprecate XB-Python-Version - Clarify use of {python:Provides} - Clarify that build-dependencies on -dev packages should not be used except when required * Upload to unstable: - Drop python2.7 from supported versions, not ready for Python transition yet -- Scott Kitterman Mon, 21 Mar 2011 10:22:06 -0400 python-defaults (2.6.6-11) experimental; urgency=low * dh_python2 and pycompile: read /usr/share/python/debian_defaults to get default Python version and a list of supported Python versions * dh_python2: - fix parsing .pyinstall files (a space between file name and module name is now required) - replace a file with a symlink also if there's a matching one in pyshared directory already - add support for DH_OPTIONS env. variable - fix checking shebangs in private directories (executable bit wasn't checked correctly) - add test4 to test handling private directories - make egg-info files/dirs searches case insensitive (closes: #614910) * pycompile: - --exclude now works with private dirs - use /usr/bin/pythonX.Y rather than pythonX.Y (to avoid /usr/local interpreters) * rewrite dh_python2.1, pycompile.1 and pyclean.1 manpages in ReStructured Text, add quick guide for maintainers to dh_python2 manpage -- Piotr Ożarowski Mon, 28 Feb 2011 20:28:05 +0100 python-defaults (2.6.6-10) experimental; urgency=low * dh_python2: fix moving files from old debug locations (due to typo) * python-minimal now Breaks python-support << 1.0.12 (Python 2.7 support was added in 1.0.12) * pycompile: skip dangling symlinks -- Piotr Ożarowski Mon, 10 Jan 2011 23:05:47 +0100 python-defaults (2.6.6-9) experimental; urgency=low * dh_python2: fix a crash in packages with private extension (closes: 607555) - test3 added (to test architecture dependent packages) -- Piotr Ożarowski Sun, 19 Dec 2010 20:27:23 +0100 python-defaults (2.6.6-8) experimental; urgency=low * Fix typo in minimum required python version for packages generated with dh_python2 -- Piotr Ożarowski Sun, 19 Dec 2010 14:57:58 +0100 python-defaults (2.6.6-7) experimental; urgency=high * pycompile: - Don't over-optimize, check the timestamps of byte-code files. - Add options -f/--force, -O. - Copy stdout/stderr of py_compile processes in case of error. - Propagate the exit value of the py_compile processes. - Update manual page. * Bump depends to require the fixed pycompile for dh_python2 based package builds. * Don't touch the standard python library in rtupdate scripts. -- Matthias Klose Sun, 12 Dec 2010 17:46:13 +0100 python-defaults (2.6.6-6) experimental; urgency=low * dh_python2: - make the error message about missing extension more clear (and more verbose in --verbose mode) - install files listed in debian/pkg.pyinstall file as public modules for all requested Python versions (use dh_install's package.install files for private modules) - remove public modules listed in debian/pkg.pyremove (glob.glob pattern and version range can be used in both .pyinstall and .pyremove files) - create symlinks for files installed into /usr/share/pyshared/ if there are no other public modules available * pycompile: - `pycompile $DESTDIR/usr/lib/python*` will recognize public site-packages directories and use the right interpreter instead of raising KeyError - do not try to check if interpreter is present when version range is empty -- Piotr Ożarowski Wed, 01 Dec 2010 19:43:50 +0100 python-defaults (2.6.6-5) experimental; urgency=low * pycompile: if installed Python is requested via -V option, use it even if it's not in a list of supported Python versions (closes: 600529) -- Piotr Ożarowski Sun, 17 Oct 2010 23:22:22 +0200 python-defaults (2.6.6-4) experimental; urgency=low * Add python2.7 as a supported Python version. * python-all{,-dev,-dbg}: Depend on the 2.7 packages. * Run the rtinstall script, when 2.7 became a supported version (2.6.6-4) and python2.7 is installed. -- Matthias Klose Sat, 16 Oct 2010 11:58:31 +0200 python-defaults (2.6.6-3+squeeze5) unstable; urgency=low * dh_python2: fix moving files from old debug locations * pycompile: skip dangling symlinks to fix upgrade problem introduced in -3+squeeze3 (closes: 607988) -- Piotr Ożarowski Tue, 11 Jan 2011 22:14:56 +0100 python-defaults (2.6.6-3+squeeze4) unstable; urgency=medium * dh_python2: fix a crash in packages with private extension (closes: 607555) -- Piotr Ożarowski Sun, 19 Dec 2010 21:12:38 +0100 python-defaults (2.6.6-3+squeeze3) unstable; urgency=medium * pycompile: - Don't over-optimize, check the timestamps of byte-code files. - Add options -f/--force, -O. - Propagate the exit value of the py_compile processes. - Update manual page. * Bump depends to require the fixed pycompile for dh_python2 based package builds. * Don't touch the standard python library in rtupdate scripts. -- Matthias Klose Sun, 12 Dec 2010 22:23:03 +0100 python-defaults (2.6.6-3+squeeze2) unstable; urgency=low * pycompile: - `pycompile $DESTDIR/usr/lib/python*` will recognize public site-packages directories and use the right interpreter instead of raising KeyError - do not try to check if interpreter is present when version range is empty (closes: 605356) -- Piotr Ożarowski Tue, 30 Nov 2010 19:57:51 +0100 python-defaults (2.6.6-3+squeeze1) unstable; urgency=medium * pycompile: if installed Python is requested via -V option, use it even if it's not in a list of supported Python versions -- Piotr Ożarowski Mon, 18 Oct 2010 19:04:55 +0200 python-defaults (2.6.6-3) unstable; urgency=low * Upload to unstable * dh_python2: egg renaming fixed -- Piotr Ożarowski Wed, 22 Sep 2010 23:03:15 +0200 python-defaults (2.6.6-2) experimental; urgency=low [ Piotr Ożarowski ] * Add README.derivatives (source package) * dh_python2: - add dist_fallback file with a list of Python distribution name and Debian package name pairs (to be used as a fall back source for PyDist feature) - if dist_fallback and `dpkg -S` fails to find the right package name, fall back to package name recommended by Debian Python Policy (use debian/pydist-overrides file to override) - disable PyDist feature if dh_pydeb is in debian/rules * Use versioned interpreter name rather than "python" only in python-minimal.postinst (closes: 595826) [ Matthias Klose ] * python.mk (py_libdir): Return /usr/lib/python3/dist-packages for 3.x versions. * python.mk (py_pkgname): New macro to refer the package name depending on the python version. -- Piotr Ożarowski Sun, 12 Sep 2010 18:41:04 +0200 python-defaults (2.6.6-1) unstable; urgency=low [ Piotr Ożarowski ] * dh_python2: typo in --help output fixed (thanks to Adam D. Barratt) * Bump python-minimal's Breaks of python2.5-minimal to << 2.5.5-7 (due to missing runpy module) * Set the right minimum required python package version in packages with private modules [ Scott Kitterman ] * debian/python-policy.sgml and debian/pyversions.py fix typos (thanks to Adam D. Barratt) [ Matthias Klose ] * Bump version to 2.6.6. -- Piotr Ożarowski Tue, 31 Aug 2010 19:09:30 +0200 python-defaults (2.6.5-13) unstable; urgency=low [ Scott Kitterman ] * Python policy changes for X-Python-Version and X-Python3-Version - Minimum changes for Squeeze * In pyversions, do not silently ignore Python 3 versions * Add support for X-Python-Version to match X-Python3-Version [ Piotr Ożarowski ] * Fix documentation typo in pycompile/pycompile.1 * dh_python2: - pass shallow=False to cmpfiles to make sure only exactly the same files are moved to pyshared - add support for X-Python-Version -- Piotr Ożarowski Fri, 13 Aug 2010 22:39:37 +0200 python-defaults (2.6.5-12) unstable; urgency=low * pycompile: do not hang if interpreters are not started in the same order as they're used (LP: #613675) * Add manpage for dh_python2, pycompile and pyclean * Standards-Version bumped to 3.9.1 (no other changes required) -- Piotr Ożarowski Thu, 05 Aug 2010 19:15:52 -0400 python-defaults (2.6.5-11) unstable; urgency=medium * Add README.PyDist to python-doc package * pycompile: compile public module for the right Python version (really closes: 590224) * dh_python2: rename --depend to --depends, --recommend to --recommends and --suggest to --suggests -- Piotr Ożarowski Tue, 27 Jul 2010 21:25:54 +0200 python-defaults (2.6.5-10) unstable; urgency=medium * dh_python2: - add --depend, --recommend and --suggest command line options (use it if requires.txt doesn't contain dependency that package needs) - add {/usr,}/sbin to the list of directories with checked shebangs * pycompile: do not exit before all background byte compilation is finished (closes: 590224) -- Piotr Ożarowski Sun, 25 Jul 2010 12:34:56 +0200 python-defaults (2.6.5-9) unstable; urgency=low [ Piotr Ożarowski ] * pyclean, pycompile: use .communicate() instead of .wait() to avoid hanging `dpkg -L PACKAGE` in few situations * dh_python2: follow Distribute and replace all non-alphanumeric characters with underscore in distribution name [ Matthias Klose ] * Require python (>= 2.6.5-9~) in generated dependencies to use the fixed pycompile. -- Piotr Ożarowski Mon, 19 Jul 2010 20:27:50 +0200 python-defaults (2.6.5-8) unstable; urgency=low * Revert: - python-minimal: Provide symlink to binary and manpage for /usr/bin/python2. This interpreter name is not created in the upstream sources. python should be used instead. -- Matthias Klose Sat, 17 Jul 2010 13:10:06 +0200 python-defaults (2.6.5-7) unstable; urgency=low * pyversions.py: fall back to the list of supported Python versions if debian/pyversions doesn't exist (as in -5, closes: 588820, thanks to Vincent Legout) -- Piotr Ożarowski Mon, 12 Jul 2010 19:15:17 +0200 python-defaults (2.6.5-6) unstable; urgency=low [ Piotr Ożarowski ] * dh_python2: - invoke `pycentral pkgremove PACKAGE` in preinst if upgrading from python-central based packages - block python package transitions via ${python:Breaks} or ${python:Depends} (Breaks will be used if available) - recognize more requires.txt patterns in debpython.pydist * pyversions.py: - print error message if file cannot be opened (closes: 521508, thanks to Carl Chenet for the original patch) - print nice error message if computed set of supported versions is empty (closes: 583392) * debian/rules: do not ignore errors (two more `set -e`s added, closes: 397499) * python-doc now suggests python-examples (closes: #585774) * python package doesn't conflict with python2.1 and python2.3 anymore (2.1 and 2.3 are no longer in Debian) * Standards-Version bumped to 3.9.0: - some packages moved from Conflicts to versioned Breaks - Homepage field added [ Scott Kitterman ] * Merge changes back from Ubuntu package: - Tighten ${binary:Version} depends relationships to "=" - python: Add an unversioned `2to3' binary - python-minimal: Provide symlink to binary and manpage for /usr/bin/python2 (Closes: #566266) * Update hard coded fallbacks in debian/pyversions.py to add python2.6 to supported versions and to make it the default version -- Piotr Ożarowski Sun, 11 Jul 2010 17:08:19 +0200 python-defaults (2.6.5-5) unstable; urgency=medium * Use Python's compileall module instead of pycompile to byte-compile debpython module as logging module is not available in pythonX.Y-minimal package (Closes: 586743) -- Piotr Ożarowski Tue, 22 Jun 2010 10:46:48 +0200 python-defaults (2.6.5-4) unstable; urgency=low [ Piotr Ożarowski ] * dh_python2: - fix parsing "XS-Python-Version: X.Y" - ignore everything after ", >= 3" in XS-Python-Version * Add python-minimal.{postinst,prerm} files to handle .py files byte-compilation [ Scott Kitterman ] * Additonal Python 3 related policy changes: - Clarify that helper specific policy does not apply to Python 3 -- Piotr Ożarowski Mon, 21 Jun 2010 23:50:22 +0200 python-defaults (2.6.5-3) unstable; urgency=low * Remove '-V' option from pyclean call in runtime.d/public_modules.rtremove * Add ${misc:Depends} to Depends in all binary packages * Add Vcs-Browser field * Add some lintian overrides (for false positives) - bump minimum required debhelper version to 6.0.7 (due to dh_lintian) -- Piotr Ożarowski Fri, 18 Jun 2010 10:25:59 +0200 python-defaults (2.6.5-2) unstable; urgency=low [ Piotr Ożarowski ] * dh_python2: - create extension symlinks in /usr/lib/pyshared/pythonX.Y - add support for debian/pydist-overrides - add dh sequence file (use "--with python2" in debian/rules) - some bugs fixed - moved from python-dev to python package * Support for Python3 removed in dh_python2, pycompile and pyclean (moved to python3-defaults) * debian/copyright: Add a note about dh_python2, pycompile, pyclean and the debpython package. * Add myself to Uploaders [ Scott Kitterman ] * debian/pyversions.py: Exclude python3 versions from results - those are handled by py3versions in python3-defaults * Update debian/copyright from LICENSE in python2.6 (Closes: #446671) * Update debian/python-policy.sgml to cover py3versions, py(3)versions as the only defined interface for determining supported/default python versions in Debian, and run time separation of python and python3 as two distinct systems * In debian/python-policy.sgml specify the correct debian/control paragraphs for XS/XB-Python-Version (Closes: #567941) - Thanks to Loïc Minier for the patch [ Matthias Klose ] * Depend on python2.6 version including the fix for issue #8223. * Don't allow installation of a mix of defaults packages for different python versions. Closes: #583683. -- Matthias Klose Thu, 17 Jun 2010 23:47:08 +0200 python-defaults (2.6.5-1) experimental; urgency=low [ Matthias Klose ] * Bump version to 2.6.5. * Make python2.6 the default Python version. * Build a python-doc package. * python: Update the valgrind file to 2.6. [ Piotr Ozarowski ] * python-minimal: Install pycompile and pyclean binaries. * Add lsb-release to Build-Depends * Add dh_python2 stuff -- Matthias Klose Fri, 14 May 2010 18:50:21 +0200 python-defaults (2.5.4-9) unstable; urgency=low * python-all-dev: Fix typo in dependency list. Closes: #566278. -- Matthias Klose Fri, 22 Jan 2010 18:38:31 +0100 python-defaults (2.5.4-6) unstable; urgency=low * Add python2.6 as a supported Python version. * python-all{,-dev,-dbg}: Depend on the 2.6 packages. * Run the rtinstall script, when 2.5 became a supported version (2.4.4-3) and python2.5 is installed. * Run the rtinstall script, when 2.6 became a supported version (2.5.4-6) and python2.6 is installed. Closes: #565952. * Fix reference to list of modules in the python-minimal package. Closes: #558403. -- Matthias Klose Sun, 17 Jan 2010 01:38:21 +0100 python-defaults (2.5.4-5) unstable; urgency=low * Fix typos from policy update (Closes: #561091, #561093) * Drop python2.4 as a supported Python - Remove python2.4 depends and update descriptions for python-all, python-all-dev, and python-all-dbg - Drop python2.4 from supported versions and add to old and unsupported versions - Update pyversions.py to drop python2.4 from the supported list * Correct path to Konsole Python desktop file (Closes: #381659) -- Scott Kitterman Wed, 23 Dec 2009 19:59:15 -0500 python-defaults (2.5.4-4) unstable; urgency=low [ Scott Kitterman ] * Update Python Policy to match current packaging practice: - Major overall update. - Remove extraneous paragraph from Provides section. (Closes: #415213) - Remove obsolete mentions of dh_python. (Closes: #527009) - Fix policy typo. (Closes: #523226) - Add pointer to doc of the site module for site-specific paths. (Closes: #287197) - Correct package dependency rules (Closes: #379455) * Move debhelper from build-depends-indep to build-depends to satisfy clean requirements. * Drop unneeded build-depends-indep on python. * Bump standards version to 3.8.3. * Drop deprecated dh_desktop from debian/rules. * Move dbg packages to section debug. * Make python-all-dbg priority extra. * Remove redundant debian/FAQ.html. * Update (= ${Source-Version}) depends to (>= ${binary:Version}). * Correct Idle depends and description (Closes: #482163). * Update python version reference in README.Debian (Closes: #494068). * Update Debian menu section for idle. * Fix capitalization of Python in the python-dev descriptions. * Add myself to uploaders. [ Matthias Klose ] * python-{dev,dbg}-dev: Add bogus dependencies on python to work around lintian's broken usr-share-doc-symlink-without-dependency check. -- Scott Kitterman Mon, 14 Dec 2009 06:03:32 -0500 python-defaults (2.5.4-2) unstable; urgency=high * python-all*: Tighten the dependencies on the python-* packages. -- Matthias Klose Thu, 26 Feb 2009 12:44:47 +0000 python-defaults (2.5.4-1) unstable; urgency=medium * Depend on python2.5-2.5.4. * python: Install /usr/share/python/python.mk, helper functions for getting the python library dir and install args for distutils installs. * Accept initial blank line in debian/control when parsing version information. -- Matthias Klose Wed, 25 Feb 2009 02:19:09 +0000 python-defaults (2.5.2-3) unstable; urgency=low * python: Provide python-ctypes and python-wsgiref. -- Matthias Klose Sat, 01 Nov 2008 09:15:19 +0100 python-defaults (2.5.2-2) unstable; urgency=low * python: Provide python-plistlib. * python-minimal: Recommend python (suggested by Neil McGovern). -- Matthias Klose Sat, 26 Jul 2008 02:37:00 +0200 python-defaults (2.5.2-1) unstable; urgency=low * Maintainer upload; asking the Release Team to better coordinate things. Being in contact with two members of the release team for two or three weeks when to upload without getting in the way of other transitions, an unannounced upload of a third member of this team is at least surprising. * debian/python.postinst.in: Fix the bug introduced in the NMU, run the rtupdate hooks when upgrading from a version < 2.5.2-1. Closes: #476095. -- Matthias Klose Thu, 17 Apr 2008 20:32:59 +0200 python-defaults (2.5.2-0.1) unstable; urgency=low * NMU by the Release Team not to lose the sweet spot for the Python transition. * Make python2.5 the default Python version. -- Adeodato Simó Sun, 13 Apr 2008 11:29:32 +0200 python-defaults (2.4.4-6) unstable; urgency=low * python.postinst: Fix cleanup of temporary files. Closes: #424703, #424704. -- Matthias Klose Thu, 17 May 2007 08:17:16 +0200 python-defaults (2.4.4-5) unstable; urgency=low * Run the python2.5 rtinstall hooks, if python2.5 was already installed as an unsupported version. -- Matthias Klose Wed, 16 May 2007 21:19:51 +0200 python-defaults (2.4.4-4) unstable; urgency=low * New package python-all-dbg. -- Matthias Klose Fri, 04 May 2007 06:56:27 +0200 python-defaults (2.4.4-3) unstable; urgency=low * Add python2.5 as a supported python version. * Depend on python2.4 packages (>= 2.4.4-4), built for ldbl128 on alpha, powerpc, s390, sparc. * python-all*: Depend on python2.5 packages (>= 2.4.5-1), built for ldbl128 on alpha, powerpc, s390, sparc. * Merge pyversions.py changes from python-central. * Merge changes from Ubuntu: - Add a sanity check, that /usr/bin/python points to the default python version. Users tend to modify this symlink, which then breaks stuff in obscure ways. Ubuntu #75557, closes: #418002. - python-dbg: Provide python-gdbm-dbg, python-tk-dbg, link to README.debug, SpecialBuilds.txt.gz. - python-dev: Add an unversioned python-config binary (backport from python2.5 (appears in python2.4 2.4.4-4). - Robustify building the faq html pages. - Make the suggestions of various packages versioned. * Update the upstream FAQ. -- Matthias Klose Fri, 4 May 2007 06:05:12 +0200 python-defaults (2.4.4-2) unstable; urgency=medium * python-all{,-dev}: Drop dependencies on python2.3{,-dev}. -- Matthias Klose Sat, 16 Dec 2006 15:42:21 +0100 python-defaults (2.4.4-1) unstable; urgency=medium * Depend on the 2.4.4 versions of the packages. * Sync pyversions.py with python-central. * Move 2.3 to old-versions, from supported-versions. * Add 2.5 to unsupported-versions. -- Matthias Klose Sun, 29 Oct 2006 11:06:39 +0100 python-defaults (2.4.3-11) unstable; urgency=low * Add a conflict to python-central (<< 0.5.5). -- Matthias Klose Sun, 13 Aug 2006 19:32:59 +0000 python-defaults (2.4.3-10) unstable; urgency=low * Upload to unstable. Closes: #347440, #360851. * Let the preinst fail on the first failing pre-rtupdate hook, after running the corresponding failed-pre-rtupdate hook. * Reflect renaming of the docutils binaries. Closes: #377601. * Update the upstream FAQ. -- Matthias Klose Sat, 12 Aug 2006 20:28:30 +0200 python-defaults (2.4.3-9) experimental; urgency=low * Fix syntax error in python.preinst. Closes: #381673. -- Matthias Klose Sun, 6 Aug 2006 12:39:34 +0000 python-defaults (2.4.3-8) experimental; urgency=low * idle: Depend on python-tk, add desktop and menu files. -- Matthias Klose Sat, 5 Aug 2006 18:38:31 +0000 python-defaults (2.4.3-7) experimental; urgency=low * Update pyversions.py from 2.3.5-11. * Fix pyversions(1), -r takes exactly one parameter. * idle: Remove the dependency on idle-pythonX.Y, add start script and man page. -- Matthias Klose Sat, 5 Aug 2006 17:34:43 +0000 python-defaults (2.4.3-6) experimental; urgency=low * Remove python's dependency on python-central. Closes: #372658. * On upgrade of the runtime to a new major version, call the hooks (executable files) in /usr/share/python/runtime.d/*.rtupdate. - in python.preinst, call the script with parameters pre-rtupdate . run all hooks, then return exit with the correct exit status. - in python.postinst, call the script with parameters rtupdate . run all hooks, then return exit with the correct exit status. - in python.postinst, call the script with parameters post-rtupdate . run all hooks, then return exit with the correct exit status. * pyversions -r: If the XS-Python-Version field cannot be found in debian/control, fall back to debian/pyversions for the version information. Return with an error code, if the intersection of the versions in debian/pyversions and the supported python versions is empty. Fall back to the supported versions if no version information can be found. Based on a patch from Raphael Hertzog. * Reflect renaming of the docutils binaries. Closes: #377601. -- Matthias Klose Sat, 5 Aug 2006 17:54:43 +0200 python-defaults (2.4.3-5) experimental; urgency=low * Tighten dependencies between packages built from this source. A versioned dependency on python-all / python-all-dev is enough to depend on the same version of python / python-dev. * python: Conflict with python-central (<< 0.4.17). * python: Depend on a python2.4 built for the updated Python policy. * python: Conflict with a python2.3 using the old Python policy. -- Matthias Klose Fri, 16 Jun 2006 18:15:00 +0200 python-defaults (2.4.3-4) experimental; urgency=low * Include version 0.4.1.0 of the python policy. * Fix 'pyversions -i'. -- Matthias Klose Tue, 13 Jun 2006 09:44:22 +0200 python-defaults (2.4.3-3) experimental; urgency=low * Point to the draft of the reworked Python policy. * Fix 'pyversions -r current' (Raphael Hertzog). -- Matthias Klose Mon, 12 Jun 2006 13:40:52 +0200 python-defaults (2.4.3-02) experimental; urgency=low * Really do not build python-doc. -- Matthias Klose Sun, 11 Jun 2006 23:25:02 +0000 python-defaults (2.4.3-01) experimental; urgency=low * Do not build the python-doc package from this source. -- Matthias Klose Sun, 11 Jun 2006 23:59:17 +0200 python-defaults (2.4.3-0) experimental; urgency=low * Upload to experimental. * Do not build the python-tk and python-gdbm packages from this source. * Let the -all packages depend on the default packages (closes: #365219). * Add /usr/share/python/debian_defaults for some default values (i.e. the supported python versions). * Add /etc/python/debian_config for byte-compilation options. * Add a pyversions script to give information about python versions and parse the XS-Python-Version attribute. -- Matthias Klose Sun, 11 Jun 2006 12:57:03 +0000 python-defaults (2.4.2-1) unstable; urgency=low * Change the default python version to 2.4. * Depend on python-central. -- Matthias Klose Thu, 12 Jan 2006 01:16:10 +0000 python-defaults (2.3.5-4) unstable; urgency=low * Add a package python-minimal. This package still depends on python2.3, will depend on python2.4-minimal when changing the default python version. * Add two dependency packages python-all and python-all-dev. These packages are used as build dependencies to determine the set of python version and implementations, which should be / currently are supported. Currently it depends on python2.3 and python2.4. Future versions may add an updated version of jython and ironpython. * Update FAQ. -- Matthias Klose Thu, 12 Jan 2006 00:32:32 +0100 python-defaults (2.3.5-3) unstable; urgency=low * Add python-dbg package. * debian/control.in: idle enhances python. -- Matthias Klose Sun, 19 Jun 2005 13:49:16 +0200 python-defaults (2.3.5-2) unstable; urgency=low * Add valgrind support file /usr/lib/valgrind/python.supp (closes: #291128). * python-doc: Add an conflict/replace to older python packages. Closes: #297266. -- Matthias Klose Sat, 19 Mar 2005 22:49:29 +0100 python-defaults (2.3.5-1) unstable; urgency=low * Depend on python-2.3.5 packages. * Update FAQ. * python suggests python-profiler. -- Matthias Klose Sat, 12 Feb 2005 19:26:48 +0100 python-defaults (2.3.4-6) unstable; urgency=low * Add an 'Enhances: konsole' to the python package (closes: #286161). -- Matthias Klose Sun, 16 Jan 2005 12:53:58 +0100 python-defaults (2.3.4-5) unstable; urgency=low * Add conflict/replaces to ooold python-base package (closes: #279035). -- Matthias Klose Sun, 14 Nov 2004 11:44:14 +0100 python-defaults (2.3.4-4) unstable; urgency=low * Regenerate control file after adding python-docutils build dependency. Closes: #270177. -- Matthias Klose Mon, 6 Sep 2004 07:19:49 +0200 python-defaults (2.3.4-3sid) unstable; urgency=low * Add build dependency on python-docutils (closes: #266550). -- Matthias Klose Wed, 18 Aug 2004 12:30:37 +0200 python-defaults (2.3.4-3) testing-proposed-updates; urgency=low * Unmodified 2.3.4-3sid, destination sarge, fixing build failure. -- Matthias Klose Fri, 20 Aug 2004 18:24:25 +0200 python-defaults (2.3.4-2sid) unstable; urgency=low * Add pdb and pdb.1 symlinks. * Update FAQ. -- Matthias Klose Tue, 17 Aug 2004 16:17:06 +0200 python-defaults (2.3.4-1) unstable; urgency=low * Depend on python-2.3.4 packages. * Update FAQ. -- Matthias Klose Mon, 10 May 2004 06:58:24 +0200 python-defaults (2.3.3-7) unstable; urgency=low * Fix symlinks to proposed policy files (closes: #234874). -- Matthias Klose Thu, 26 Feb 2004 22:28:07 +0100 python-defaults (2.3.3-6) unstable; urgency=low * Build the default packages from a separate source package to ease migration between python versions. * Update to the proposed python-policy: byte-compile using -E. -- Matthias Klose Wed, 4 Feb 2004 23:16:35 +0100 python-defaults-2.7.12/pycompile.rst0000664000000000000000000000263312254623031014356 0ustar ========== pycompile ========== -------------------------------- byte compile Python source files -------------------------------- :Manual section: 1 :Author: Piotr Ożarowski, 2012-2013 SYNOPSIS ======== pycompile [-V [X.Y][-][A.B]] DIR_OR_FILE [-X REGEXPR] pycompile -p PACKAGE DESCRIPTION =========== Wrapper around Python standard library's py_compile module to byte-compile Python files. OPTIONS ======= --version show program's version number and exit -h, --help show this help message and exit -f, --force force rebuild of byte-code files even if timestamps are up-to-date -O byte-compile to .pyo files -q, --quiet be quiet -v, --verbose turn verbose mode on -p PACKAGE, --package=PACKAGE specify Debian package name whose files should be bytecompiled (combining with DIR_OR_FILE will additionally limit list of files) -V VRANGE force private modules to be bytecompiled with Python version from given range, regardless of the default Python version in the system. If there are no other options, bytecompile all public modules for installed Python versions that match given range. VERSION_RANGE examples: * ``2.5`` version 2.5 only * ``2.5-`` version 2.5 or newer * ``2.5-2.7`` version 2.5 or 2.6 * ``-3.0`` all supported 2.X versions -X REGEXPR, --exclude=REGEXPR exclude items that match given REGEXPR. You may use this option multiple times to build up a list of things to exclude python-defaults-2.7.12/pyclean.10000664000000000000000000000246212374331373013350 0ustar .\" Man page generated from reStructuredText. . .TH PYCLEAN 1 "" "" "" .SH NAME pyclean \- removes .pyc and .pyo files . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .SH SYNOPSIS .INDENT 0.0 .INDENT 3.5 pyclean [\-p PACKAGE | DIR_OR_FILE] .UNINDENT .UNINDENT .SH OPTIONS .INDENT 0.0 .TP .B \-\-version show program\(aqs version number and exit .TP .B \-h\fP,\fB \-\-help show this help message and exit .TP .B \-v\fP,\fB \-\-verbose turn verbose more one .TP .B \-q\fP,\fB \-\-quiet be quiet .TP .BI \-p \ PACKAGE\fP,\fB \ \-\-package\fB= PACKAGE specify Debian package name to clean (combining with DIR_OR_FILE will additionally limit list of files) .UNINDENT .SH AUTHOR Piotr Ożarowski, 2012-201 .\" Generated by docutils manpage writer. . python-defaults-2.7.12/pyclean0000775000000000000000000001003413205532536013204 0ustar #! /usr/bin/python2 # -*- coding: UTF-8 -*- vim: et ts=4 sw=4 # # Copyright © 2010-2012 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import logging import optparse import sys from os import environ, remove from os.path import exists sys.path.insert(1, '/usr/share/python/') from debpython import files as dpf from debpython.namespace import add_namespace_files # initialize script logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: ' '%(message)s') log = logging.getLogger(__name__) """TODO: move it to manpage Examples: pyclean -p python-mako # all .py[co] files from the package pyclean /usr/lib/python2.6/dist-packages # python2.6 """ def destroyer(): # ;-) """Removes every .py[co] file associated to received .py file.""" def find_files_to_remove(pyfile): for filename in ("%sc" % pyfile, "%so" % pyfile): if exists(filename): yield filename counter = 0 try: while True: pyfile = (yield) for filename in find_files_to_remove(pyfile): try: log.debug('removing %s', filename) remove(filename) counter += 1 except (IOError, OSError), e: log.error('cannot remove %s', filename) log.debug(e) except GeneratorExit: log.info("removed files: %s", counter) def main(): usage = '%prog [-p PACKAGE] [DIR_OR_FILE]' parser = optparse.OptionParser(usage, version='%prog 1.0') parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='turn verbose more one') parser.add_option('-q', '--quiet', action='store_false', dest='verbose', default=False, help='be quiet') parser.add_option('-p', '--package', help='specify Debian package name to clean') options, args = parser.parse_args() if options.verbose or environ.get('PYCLEAN_DEBUG') == '1': log.setLevel(logging.DEBUG) log.debug('argv: %s', sys.argv) log.debug('options: %s', options) log.debug('args: %s', args) else: log.setLevel(logging.WARNING) d = destroyer() d.next() # initialize coroutine if not options.package and not args: parser.print_usage() exit(1) if options.package: log.info('cleaning package %s', options.package) pfiles = dpf.from_package(options.package, extensions=('.py', '.so')) pfiles = add_namespace_files(pfiles, options.package, action=False) pfiles = set(dpf.filter_out_ext(pfiles, ('.so',))) if args: log.info('cleaning directories: %s', args) files = dpf.from_directory(args, extensions=('.py', '.so')) files = add_namespace_files(files, action=False) files = set(dpf.filter_out_ext(files, ('.so',))) if options.package: files = files & pfiles else: files = pfiles for filename in files: d.send(filename) if __name__ == '__main__': main() python-defaults-2.7.12/dh_python2.py0000775000000000000000000000204012254623031014246 0ustar #! /usr/bin/python from os.path import exists from subprocess import call from sys import argv from re import compile OLD = '/usr/share/python/dh_python2' NEW = '/usr/share/dh-python/dh_python2' has_dhpython = compile(r'(^|:|\s|,)dh-python($|\s|,|\()').search binary = OLD if exists(NEW) and exists('debian/control'): with open('debian/control', 'r') as fp: inside = False for line in fp: if not line: break line_lower = line.lower() if inside: if line.startswith((' ', "\t")): if has_dhpython(line): binary = NEW break continue elif line.startswith('#'): continue inside = False if line_lower.startswith(('build-depends:', 'build-depends-indep:')): if has_dhpython(line): binary = NEW break inside = True argv[0] = binary exit(call(argv)) python-defaults-2.7.12/python2.pm0000664000000000000000000000034712057417145013574 0ustar #! /usr/bin/perl # debhelper sequence file for dh_python2 use warnings; use strict; use Debian::Debhelper::Dh_Lib; insert_before("dh_installinit", "dh_python2"); remove_command("dh_pycentral"); remove_command("dh_pysupport"); 1 python-defaults-2.7.12/pycompile0000775000000000000000000002716713205532536013571 0ustar #! /usr/bin/python2 # -*- coding: utf-8 -*- vim: et ts=4 sw=4 # # Copyright © 2010-2012 Piotr Ożarowski # Copyright © 2010 Canonical Ltd # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. from __future__ import with_statement import logging import optparse import os import sys from os import environ, listdir from os.path import exists, isdir, islink, join from subprocess import PIPE, STDOUT, Popen sys.path.insert(1, '/usr/share/python/') from debpython.version import SUPPORTED, debsorted, vrepr, \ get_requested_versions, parse_vrange, getver from debpython import files as dpf from debpython.namespace import add_namespace_files from debpython.option import Option, compile_regexpr from debpython.pydist import PUBLIC_DIR_RE from debpython.tools import memoize # initialize script logging.basicConfig(format='%(levelname).1s: %(module)s:%(lineno)d: ' '%(message)s') log = logging.getLogger(__name__) STDINS = {} WORKERS = {} """TODO: move it to manpage Examples: pycompile -p python-mako # package's public files pycompile -p foo /usr/share/foo # package's private files pycompile -p foo -V 2.6- /usr/share/foo # private files, Python >= 2.6 pycompile -V 2.6 /usr/lib/python2.6/dist-packages # python2.6 only pycompile -V 2.6 /usr/lib/foo/bar.py # python2.6 only """ ### EXCLUDES ################################################### @memoize def get_exclude_patterns_from_dir(name='/usr/share/python/bcep/'): """Return patterns for files that shouldn't be bytecompiled.""" if not isdir(name): return [] result = [] for fn in listdir(name): with file(join(name, fn), 'r') as lines: for line in lines: type_, vrange, dname, pattern = line.split('|', 3) vrange = parse_vrange(vrange) versions = get_requested_versions(vrange, available=True) if not versions: # pattern doesn't match installed Python versions continue pattern = pattern.rstrip('\n') if type_ == 're': pattern = compile_regexpr(None, None, pattern) result.append((type_, versions, dname, pattern)) return result def get_exclude_patterns(directory='/', patterns=None, versions=None): """Return patterns for files that shouldn't be compiled in given dir.""" if versions is not None: # make sure it's a set (debsorted returns a list) versions = set(versions) if patterns: if versions is None: versions = set(SUPPORTED) patterns = [('re', versions, directory, i) for i in patterns] else: patterns = [] for type_, vers, dname, pattern in get_exclude_patterns_from_dir(): # skip patterns that do not match requested directory if not dname.startswith(directory[:len(dname)]): continue # skip patterns that do not match requested versions if versions and not versions & vers: continue patterns.append((type_, vers, dname, pattern)) return patterns def filter_files(files, e_patterns, compile_versions): """Generate (file, versions_to_compile) pairs.""" for fn in files: valid_versions = set(compile_versions) # all by default for type_, vers, dname, pattern in e_patterns: if type_ == 'dir' and fn.startswith(dname): valid_versions = valid_versions - vers elif type_ == 're' and pattern.match(fn): valid_versions = valid_versions - vers # move to the next file if all versions were removed if not valid_versions: break if valid_versions: public_dir = PUBLIC_DIR_RE.match(fn) if public_dir: yield fn, set([getver(public_dir.group(1))]) else: yield fn, valid_versions ### COMPILE #################################################### def py_compile(version, optimize, workers): if not isinstance(version, basestring): version = vrepr(version) cmd = "/usr/bin/python%s%s -m py_compile -" \ % (version, ' -O' if optimize else '') process = Popen(cmd, bufsize=1, shell=True, stdin=PIPE, stdout=PIPE, stderr=STDOUT, close_fds=True) workers[version] = process # keep the reference for .communicate() stdin = process.stdin while True: filename = (yield) stdin.write(filename + '\n') def compile(files, versions, force, optimize, e_patterns=None): global STDINS, WORKERS # start Python interpreters that will handle byte compilation for version in versions: if version not in STDINS: coroutine = py_compile(version, optimize, WORKERS) coroutine.next() STDINS[version] = coroutine # byte compile files for fn, versions_to_compile in filter_files(files, e_patterns, versions): cfn = fn + 'o' if optimize else 'c' if not exists(fn): # pycentral's hook should clean it later if islink(fn): log.warn('dangling symlink skipped: %s (%s)', fn, os.readlink(fn)) continue if exists(cfn) and not force: ftime = os.stat(fn).st_mtime try: ctime = os.stat(cfn).st_mtime except os.error: ctime = 0 if ctime > ftime: continue for version in versions_to_compile: try: pipe = STDINS[version] except KeyError: # `pycompile /usr/lib/` invoked, add missing worker pipe = py_compile(version, optimize, WORKERS) pipe.next() STDINS[version] = pipe pipe.send(fn) ################################################################ def main(): usage = '%prog [-V [X.Y][-][A.B]] DIR_OR_FILE [-X REGEXPR]\n' + \ ' %prog -p PACKAGE' parser = optparse.OptionParser(usage, version='%prog 1.0', option_class=Option) parser.add_option('-v', '--verbose', action='store_true', dest='verbose', help='turn verbose mode on') parser.add_option('-q', '--quiet', action='store_false', dest='verbose', default=False, help='be quiet') parser.add_option('-f', '--force', action='store_true', dest='force', default=False, help='force rebuild even if timestamps are up-to-date') parser.add_option('-O', action='store_true', dest='optimize', default=False, help="byte-compile to .pyo files") parser.add_option('-p', '--package', help='specify Debian package name whose files should be bytecompiled') parser.add_option('-V', type='version_range', dest='vrange', help="""force private modules to be bytecompiled with Python version from given range, regardless of the default Python version in the system. If there are no other options, bytecompile all public modules for installed Python versions that match given range. VERSION_RANGE examples: '2.5' (version 2.5 only), '2.5-' (version 2.5 or newer), '2.5-2.7' (version 2.5 or 2.6), '-3.0' (all supported 2.X versions)""") parser.add_option('-X', '--exclude', action='append', dest='regexpr', type='regexpr', help='exclude items that match given REGEXPR. You may use this option \ multiple times to build up a list of things to exclude.') (options, args) = parser.parse_args() if options.verbose or environ.get('PYCOMPILE_DEBUG') == '1': log.setLevel(logging.DEBUG) log.debug('argv: %s', sys.argv) log.debug('options: %s', options) log.debug('args: %s', args) else: log.setLevel(logging.WARN) if options.regexpr and not args: parser.error('--exclude option works with private directories ' 'only, please use /usr/share/python/bcep to specify ' 'public modules to skip') if options.vrange and options.vrange[0] == options.vrange[1] and\ options.vrange != (None, None) and\ exists("/usr/bin/python%d.%d" % options.vrange[0]): # specific version requested, use it even if it's not in SUPPORTED versions = set(options.vrange[:1]) else: versions = get_requested_versions(options.vrange, available=True) if not versions: log.error('Requested versions are not installed') exit(3) if options.package and args: # package's private directories # get requested Python version compile_versions = debsorted(versions)[:1] log.debug('compile versions: %s', versions) pkg_files = tuple(dpf.from_package(options.package)) for item in args: e_patterns = get_exclude_patterns(item, options.regexpr, \ compile_versions) if not exists(item): log.warn('No such file or directory: %s', item) else: log.debug('byte compiling %s using Python %s', item, compile_versions) files = dpf.filter_directory(pkg_files, item) compile(files, compile_versions, options.force, options.optimize, e_patterns) elif options.package: # package's public modules # no need to limit versions here, version is hardcoded in path or # via -V option e_patterns = get_exclude_patterns() files = dpf.from_package(options.package, extensions=('.py', '.so')) files = dpf.filter_public(files, versions) files = add_namespace_files(files, options.package, action=True) files = dpf.filter_out_ext(files, ('.so',)) compile(files, versions, options.force, options.optimize, e_patterns) elif args: # other directories/files versions = debsorted(versions)[:1] for item in args: e_patterns = get_exclude_patterns(item, options.regexpr, versions) files = dpf.from_directory(item, extensions=('.py', '.so')) files = add_namespace_files(files, action=True) files = dpf.filter_out_ext(files, ('.so',)) compile(files, versions, options.force, options.optimize, e_patterns) else: parser.print_usage() exit(1) # wait for all processes to finish rv = 0 for process in WORKERS.itervalues(): child_output, child_unused = process.communicate() if process.returncode not in (None, 0): # FIXME: find out the package the file belongs to sys.stderr.write(child_output) rv = process.returncode if rv != 0: rv += 100 exit(rv) if __name__ == '__main__': main() python-defaults-2.7.12/pydist/0000775000000000000000000000000012374331373013143 5ustar python-defaults-2.7.12/pydist/generate_fallback_list.py0000775000000000000000000000605212057417145020167 0ustar #! /usr/bin/python # -*- coding: UTF-8 -*- # Copyright © 2010 Piotr Ożarowski # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. import os import sys from subprocess import Popen, PIPE skip_sensible_names = True if '--skip-sensible-names' in sys.argv else False os.chdir(os.path.dirname(__file__)) if os.path.isdir('../debpython'): sys.path.append('..') else: sys.path.append('/usr/share/python/debpython/') from debpython.pydist import sensible_pname if not os.path.isdir('cache'): process = Popen('apt-file -s sources.list -c cache update', shell=True) process.communicate() if process.returncode != 0: sys.stderr.write('Cannot download APT data files') exit(1) # find .egg-info files/directories process = Popen('apt-file -s sources.list -c cache find -x ' '"/usr/((share/pyshared)|(lib/python2\.[0-9]/((site)|(dist))-packages)|(share/python-support/[^/]+))/[^/]*\.egg-info"', shell=True, stdout=PIPE) stdout, stderr = process.communicate() if process.returncode != 0: sys.stderr.write('Cannot find packages with Egg metadata') exit(2) processed = set() result = [] for line in stdout.splitlines(): pname, path = line.split(': ', 1) if pname == 'python-setuptools': continue egg_name = [i.split('-', 1)[0] for i in path.split('/')\ if i.endswith('.egg-info')][0] if egg_name.endswith('.egg'): egg_name = egg_name[:-4] if skip_sensible_names and sensible_pname(egg_name) == pname: continue if egg_name not in processed: processed.add(egg_name) result.append("%s %s\n" % (egg_name, pname)) #result.append("%s %s\t%s\n" % (egg_name, pname, path)) result.sort() fp = open('dist_fallback', 'w') fp.write('python python\n') fp.write('setuptools python-pkg-resources\n') fp.write('wsgiref python (>= 2.5) | python-wsgiref\n') fp.write('argparse python (>= 2.7) | python-argparse\n') # wasn't recognized due to .pth file (egg-info is in PIL/ and not in *-packages/) fp.write('pil python-imaging\n') fp.writelines(result) python-defaults-2.7.12/pydist/dist_fallback0000664000000000000000000004056112057417145015656 0ustar python python setuptools python-pkg-resources wsgiref python (>= 2.5) | python-wsgiref argparse python (>= 2.7) | python-argparse pil python-imaging AddOns python-peak.util BatchModify trac-batchmodify BitTornado bittornado BitTorrent bittorrent Bitten trac-bitten-slave BytecodeAssembler python-peak.util BzrPipeline bzr-pipeline BzrTools bzrtools Calendar_and_Contacts_Server calendarserver CedarBackup2 cedar-backup2 CherryPy python-cherrypy3 CherryTree cherrytree ClusterShell clustershell Codeville codeville ControlAula controlaula CoverageTestRunner python-coverage-test-runner DITrack ditrack DebTorrent debtorrent DecoratorTools python-peak.util.decorators DiaVisViewPlugin trac-diavisview Djapian python-django-djapian Doconce doconce Dosage dosage DouF00 douf00 Editra editra Extremes python-peak.util Fabric fabric FeinCMS python-django-feincms Flask_WTF python-flaskext.wtf GaussSum gausssum GeoIP_Python python-geoip GitPython python-git HarvestMan harvestman ISO8583_Module python-iso8583 Ibid ibid JCC jcc Loom bzr-loom MAT mat Magic_file_extensions python-magic Mirage mirage Mnemosyne mnemosyne Model_Builder model-builder MySQL_python python-mysqldb Nautilus_scripts_manager nautilus-scripts-manager Nulog nulog OdtExportPlugin trac-odtexport PEAK_Rules python-peak.rules PIDA pida Photon photon Plywood plywood Postr postr PreludeEasy python-prelude PsychoPy psychopy Pwman3 pwman3 PyAIML python-aiml PyBluez python-bluez PyCAPTCHA python-captcha PyCoCuMa pycocuma PyFFTW3 python-fftw PyHamcrest python-hamcrest PyMca pymca PyMetrics pymetrics PyNAST pynast PyOpenGL python-opengl PyProtocols python-protocols PyRoom pyroom PySFML python-sfml PyStemmer python-stemmer PyWavelets python-pywt PyWebDAV python-webdav PyYAML python-yaml Py_ python-py++ Pygmy pygmy Pymacs pymacs Pyste libboost-python1.49-dev PythonDaap python-daap QuantLib_Python quantlib-python Quixote python-quixote1 Ren_Py python-renpy Roadmap_Plugin trac-roadmap RunSnakeRun runsnakerun ScientificPython python-scientific Shinken shinken-core Sonata sonata South python-django-south SymbolType python-peak.util Symbolic python-swiginac TcosConfigurator tcos-configurator The_FreeSmartphone_Framework_Daemon fso-frameworkd TileCache tilecache TileStache tilestache Trac trac TracAccountManager trac-accountmanager TracAnnouncer trac-announcer TracAuthOpenId trac-authopenid TracBzr trac-bzr TracCustomFieldAdmin trac-customfieldadmin TracDateField trac-datefieldplugin TracGit trac-git TracHTTPAuth trac-httpauth TracMasterTickets trac-mastertickets TracMercurial trac-mercurial TracPrivateTickets trac-privatetickets TracSpamFilter trac-spamfilter TracSubTicketsPlugin trac-subtickets TracTags trac-tags TracVirtualTicketPermissions trac-virtualticketpermissions TracWikiPrintPlugin trac-wikiprint TracWysiwyg trac-wysiwyg TracXMLRPC trac-xmlrpc Trac_jsGantt trac-jsgantt Turtle_Art turtleart UNKNOWN python-pdfrw UnknownHorizons unknown-horizons VirtualMailManager vmm WikiTableMacro trac-wikitablemacro Wikkid wikkid WordPress_Library python-wordpresslib X_Tile x-tile ZODB3 python-zodb _tifffile tifffile activity_log_manager activity-log-manager adns_python python-adns agtl agtl alembic alembic allmydata_tahoe tahoe-lafs apache_libcloud python-libcloud apparmor apparmor-utils apt_clone apt-clone apt_p2p apt-p2p apt_xapian_index apt-xapian-index aptfs aptfs aptoncd aptoncd arandr arandr archivemail archivemail archmage archmage arista arista atheist atheist autokey autokey-common beautifulsoup4 python-bs4 bicyclerepair bicyclerepair bley bley bookletimposer bookletimposer bpython bpython buildbot buildbot buildbot_slave buildbot-slave burn burn bzr python-bzrlib bzr_builddeb bzr-builddeb bzr_cia cia-clients bzr_cvsps_import bzr-cvsps-import bzr_dbus bzr-dbus bzr_email bzr-email bzr_etckeeper etckeeper bzr_fastimport bzr-fastimport bzr_git bzr-git bzr_grep bzr-grep bzr_gtk bzr-gtk bzr_rewrite bzr-rewrite bzr_search bzr-search bzr_stats bzr-stats bzr_svn bzr-svn bzr_upload bzr-upload bzr_xmloutput bzr-xmloutput cappuccino cappuccino carbon graphite-carbon cardstories cardstories cfget cfget chirp chirp chm2pdf chm2pdf cm config-manager cmdtest cmdtest cpuset cpuset cvs2svn cvs2svn d_feet d-feet d_rats d-rats datapm datapm dblatex dblatex dctrl2xml dctrl2xml debpartial_mirror debpartial-mirror deluge deluge-common devscripts devscripts dicompyler dicompyler dissy dissy djagios djagios django_ajax_selects django-ajax-selects django_filter django-filter django_openid_auth python-django-auth-openid django_tables2 django-tables django_tastypie python-tastypie djextdirect python-django-extdirect dkimpy python-dkim dot2tex dot2tex driconf driconf dtrx dtrx duplicity duplicity dvcs_autosync dvcs-autosync eficas eficas elisa python-moovida elisa_plugin_amazon moovida-plugins-bad elisa_plugin_amp moovida-plugins-bad elisa_plugin_avahi moovida-plugins-bad elisa_plugin_base moovida-plugins-good elisa_plugin_coherence moovida-plugins-bad elisa_plugin_daap moovida-plugins-bad elisa_plugin_database moovida-plugins-bad elisa_plugin_discogs moovida-plugins-bad elisa_plugin_dvd moovida-plugins-bad elisa_plugin_elisa_updater moovida-plugins-bad elisa_plugin_filtered_shares moovida-plugins-bad elisa_plugin_flickr moovida-plugins-ugly elisa_plugin_gnome moovida-plugins-good elisa_plugin_gstreamer moovida-plugins-bad elisa_plugin_hal moovida-plugins-good elisa_plugin_http_client moovida-plugins-bad elisa_plugin_ipod moovida-plugins-bad elisa_plugin_lastfm moovida-plugins-bad elisa_plugin_lirc moovida-plugins-ugly elisa_plugin_osso moovida-plugins-bad elisa_plugin_pigment moovida-plugins-bad elisa_plugin_poblesec moovida-plugins-bad elisa_plugin_rss moovida-plugins-bad elisa_plugin_search moovida-plugins-bad elisa_plugin_shoutcast moovida-plugins-ugly elisa_plugin_smbwin32 moovida-plugins-bad elisa_plugin_themoviedb moovida-plugins-bad elisa_plugin_thetvdb moovida-plugins-bad elisa_plugin_winremote moovida-plugins-bad elisa_plugin_winscreensaver moovida-plugins-good elisa_plugin_wmd moovida-plugins-bad elisa_plugin_youtube moovida-plugins-ugly epigrass epigrass epoptes epoptes espeak_gui espeak-gui euca2ools euca2ools explorer bzr-explorer flashbake flashbake flickrfs flickrfs fontypython fontypython frescobaldi frescobaldi fts fts fts_clacks fts-clacks fts_fai fts-fai-ldap fts_ltsp fts-ltsp-ldap fts_opsi fts-opsi funkload funkload fuse_python python-fuse fusil fusil fuss_launcher fuss-launcher galternatives galternatives gameclock gameclock gaphor gaphor gastablesgui gastables gbp git-buildpackage gdevilspie gdevilspie gdmodule python-gd genbackupdata genbackupdata getmail getmail4 geximon geximon git_review git-review github_cli github-cli giws giws gjots2 gjots2 glipper glipper globs globs glue glue-sprite gmobilemedia gmobilemedia gnome_activity_journal gnome-activity-journal gnome_app_install gnome-codec-install gnomecatalog gnomecatalog gnuplot_py python-gnuplot go2 go2 gozerbot gozerbot gozerplugs gozerbot-plugins gpodder gpodder gquilt gquilt graphviz trac-graphviz gunicorn gunicorn gvb gvb gwrite gwrite gyp gyp hgnested mercurial-nested hgsvn hgsvn hitchhhiker hitchhiker hotwire hotwire httpcode httpcode httpie httpie hyde hyde ibus_tegaki ibus-tegaki icalview trac-icalviewplugin identicurse identicurse imposm.parser python-imposm-parser iotop iotop ipython ipython isoquery isoquery jack jack jsb jsonbot juju juju kedpm kedpm keepnote keepnote key_mon key-mon keymapper keymapper kiki kiki lastfmsubmitd lastfmsubmitd lazygal lazygal legit legit libtpclient_py python-tp-client libtpproto_py python-tp-netlib lio lio-utils llnl_babel python-sidl llnl_babel_sidl_sidlx python-sidl loggerhead loggerhead londonlaw londonlaw lptools lptools lshell lshell ludev_t ludevit lybniz lybniz mayavi mayavi2 mcomix mcomix mecab_python python-mecab mercurial mercurial-common mic mic2 mimms mimms mingc python-ming mini_dinstall mini-dinstall miro miro mitmproxy mitmproxy mod_python libapache2-mod-python moin python-moinmoin moosic moosic mozilla_devscripts mozilla-devscripts mpDris mpdris museek_python_bindings python-museek musiclibrarian musiclibrarian mysql_utilities mysql-utilities nautilus_pastebin nautilus-pastebin neso tryton-neso netsnmp_python libsnmp-python nfoview nfoview nglister nglister nml nml nsscache nsscache nxt_python python-nxt obMenu obmenu obnam obnam oboinus oboinus offlineimap offlineimap oidua oidua ooo2dbk ooo2dbk ooolib_python python-ooolib openbmap_logger openbmap-logger openoffice_python python-openoffice openshot openshot openstack.common python-openstack-common osc osc pYsearch python-yahoo pbundler pbundler pdfposter pdfposter pdfshuffler pdfshuffler pep8 pep8 perroquet perroquet pgxnclient pgxnclient photofilmstrip photofilmstrip pithos pithos pkpgcounter pkpgcounter playitslowly playitslowly pondus pondus prelude_correlator prelude-correlator prelude_notify prelude-notify preprocess preprocess presage_dbus_service presage-dbus prewikka prewikka prioritized_methods python-peak.rules proteus tryton-proteus prover9_mace4 prover9-mace4 pssh pssh ptex2tex ptex2tex puddletag puddletag purity_ng purity-ng pyExcelerator python-excelerator pyFAI pyfai pyLibravatar python-libravatar pyOpenSSL python-openssl pyPortMidi python-pypm py_Asterisk python-asterisk py_pypcap python-pypcap py_rrdtool python-rrdtool py_sendfile python-sendfile pyacidobasic python-acidobasic pyacoustid python-acoustid pyalsaaudio python-alsaaudio pybloom python-bloomfilter pybridge pybridge pybtex pybtex pybugz bugz pychecker pychecker pychess pychess pychm python-chm pycrypto python-crypto pydicom python-dicom pydns python-dns pyenchant python-enchant pyepr python-epr pyfacebook python-facebook pyflakes pyflakes pygdchart python-gdchart2 pygopherd pygopherd pygpgme python-gpgme pygpiv python-gpiv pygrib python-grib pyliblo python-liblo pyliblzma python-lzma pylibpcap python-libpcap pylint pylint pylogsparser python-logsparser pymecavideo python-mecavideo pymilter python-milter pymol pymol pymucipher python-museek pymvpa python-mvpa pymvpa2 python-mvpa2 pyneighborhood pyneighborhood pynids python-nids pynifti python-nifti pyogg python-ogg pyp pyp pyparallel python-parallel pyppd pyppd pyprompter pyprompter pyremctl python-remctl pyrit pyrit pyrite_publisher pyrite-publisher pysane python-imaging-sane pysatellites python-satellites pyserial python-serial pysnmp python-pysnmp4 pysnmp_apps python-pysnmp4-apps pysnmp_mibs python-pysnmp4-mibs pysparse python-sparse pyspf python-spf pyspi python-at-spi pysqlite python-pysqlite1.1 pystatgrab python-statgrab pysubnettree python-subnettree pysurfer python-surfer pytagsfs pytagsfs pytcpwrap python-tcpwrap python2_biggles python-pybiggles python_djvulibre python-djvu python_e_dbus python-edbus python_graph_core python-pygraph python_graph_dot python-pygraph python_libgearman python-gearman.libgearman python_libpisock python-pisock python_logging_extra python-loggingx python_memcached python-memcache python_policyd_spf postfix-policyd-spf-python python_yapps yapps2 pythontracer pythontracer pytidylib python-tidylib pytimechart pytimechart pytrainer pytrainer pytz python-tz pyusb python-usb pyweblib python-weblib pyxdg python-xdg pyzmq python-zmq pyzor pyzor qbzr qbzr qct qct qmtest qmtest qpid_python python-qpid qpid_qmf python-qpid-extras-qmf qpid_tools qpid-tools quisk quisk quodlibet exfalso qweborf qweborf rabbitvcs rabbitvcs-core radiotray radiotray ranger ranger rapid_spring rapid-spring rawdog rawdog rdiff_backup rdiff-backup rebuildd rebuildd recaptcha_client python-recaptcha relational_gui relational relational_pyside relational relational_readline relational-cli remuco remuco-base repoze.what.plugins.sql python-repoze.what-plugins repoze.what.plugins.xml python-repoze.what-plugins repoze.what_pylons python-repoze.what-plugins repoze.what_quickstart python-repoze.what-plugins repoze.who.plugins.ldap python-repoze.who-plugins repoze.who.plugins.openid python-repoze.who-plugins repoze.who.plugins.sa python-repoze.who-plugins repoze.who_friendlyform python-repoze.who-plugins repoze.who_testutil python-repoze.who-plugins roundup roundup rpl rpl rst2pdf rst2pdf rubber rubber salt salt-common scikit_learn python-sklearn scikits_image python-skimage screenlets screenlets seivot seivot sensitivetickets trac-sensitivetickets servefile servefile shedskin shedskin slapos.core slapos-client slimit slimit smart python-smartpm snimpy snimpy spambayes spambayes spectacle spectacle specto specto sphinxcontrib_actdiag python-sphinxcontrib.actdiag sphinxcontrib_blockdiag python-sphinxcontrib.blockdiag sphinxcontrib_issuetracker python-sphinxcontrib.issuetracker sphinxcontrib_nwdiag python-sphinxcontrib.nwdiag sphinxcontrib_seqdiag python-sphinxcontrib.seqdiag sphinxcontrib_spelling python-sphinxcontrib.spelling spyder python-spyderlib sqlalchemy_migrate python-migrate startupmanager startupmanager stgit stgit summain summain supervisor supervisor supybot supybot svnmailer svnmailer synaptiks kde-config-touchpad tailor tailor targetcli targetcli tcm lio-utils tcosconfig tcosconfig tegaki_pygtk python-tegaki-gtk tegaki_python python-tegaki tegaki_tools python-tegakitools tegaki_train tegaki-train tgext.crud python-tgext.admin tilelite tilelite tinyeartrainer tinyeartrainer tortoisehg tortoisehg transifex_client transifex-client translate_toolkit translate-toolkit trash_cli trash-cli trimage trimage tritium tritium tryton tryton-client trytond tryton-server trytond_account tryton-modules-account trytond_account_be tryton-modules-account-be trytond_account_de_skr03 tryton-modules-account-de-skr03 trytond_account_invoice tryton-modules-account-invoice trytond_account_invoice_history tryton-modules-account-invoice-history trytond_account_invoice_line_standalone tryton-modules-account-invoice-line-standalone trytond_account_product tryton-modules-account-product trytond_account_statement tryton-modules-account-statement trytond_analytic_account tryton-modules-analytic-account trytond_analytic_invoice tryton-modules-analytic-invoice trytond_analytic_purchase tryton-modules-analytic-purchase trytond_analytic_sale tryton-modules-analytic-sale trytond_calendar tryton-modules-calendar trytond_calendar_classification tryton-modules-calendar-classification trytond_calendar_scheduling tryton-modules-calendar-scheduling trytond_calendar_todo tryton-modules-calendar-todo trytond_company tryton-modules-company trytond_company_work_time tryton-modules-company-work-time trytond_country tryton-modules-country trytond_currency tryton-modules-currency trytond_dashboard tryton-modules-dashboard trytond_google_maps tryton-modules-google-maps trytond_ldap_authentication tryton-modules-ldap-authentication trytond_ldap_connection tryton-modules-ldap-connection trytond_party tryton-modules-party trytond_party_siret tryton-modules-party-siret trytond_party_vcarddav tryton-modules-party-vcarddav trytond_product tryton-modules-product trytond_product_cost_fifo tryton-modules-product-cost-fifo trytond_product_cost_history tryton-modules-product-cost-history trytond_product_price_list tryton-modules-product-price-list trytond_project tryton-modules-project trytond_project_plan tryton-modules-project-plan trytond_project_revenue tryton-modules-project-revenue trytond_purchase tryton-modules-purchase trytond_purchase_invoice_line_standalone tryton-modules-purchase-invoice-line-standalone trytond_sale tryton-modules-sale trytond_sale_opportunity tryton-modules-sale-opportunity trytond_sale_price_list tryton-modules-sale-price-list trytond_stock tryton-modules-stock trytond_stock_forecast tryton-modules-stock-forecast trytond_stock_inventory_location tryton-modules-stock-inventory-location trytond_stock_location_sequence tryton-modules-stock-location-sequence trytond_stock_product_location tryton-modules-stock-product-location trytond_stock_supply tryton-modules-stock-supply trytond_stock_supply_day tryton-modules-stock-supply-day trytond_timesheet tryton-modules-timesheet ttb ttb turpial turpial tw.forms python-toscawidgets txLibravatar python-twisted-libravatar ubuntu_dev_tools ubuntu-dev-tools ufw ufw unattended_upgrades unattended-upgrades unittest_xml_reporting python-xmlrunner urlscan urlscan vamos undertaker vboxapi virtualbox virtaal virtaal virtinst virtinst virtualbricks virtualbricks virtualenvwrapper virtualenvwrapper wammu wammu web.py python-webpy weboob python-weboob-core whyteboard whyteboard wikipediafs wikipediafs winpdb winpdb wxPython_common python-wxgtk2.8 wxgeometrie wxgeometrie xgflib xgridfit xml_marshaller python-xmlmarshaller xmldiff xmldiff xmms2tray xmms2tray yagtd yagtd yokadi yokadi yum_metadata_parser python-sqlitecachec zenmap zenmap zeroinstall_injector zeroinstall-injector zim zim zinnia_python python-zinnia python-defaults-2.7.12/pydist/Makefile0000664000000000000000000000024512374331373014604 0ustar #!/usr/bin/make -f clean: rm -rf cache #rm -f dist_fallback dist_fallback: sources.list python ./generate_fallback_list.py --skip-sensible-names .PHONY: clean python-defaults-2.7.12/pydist/sources.list0000664000000000000000000000014412057417145015522 0ustar deb http://ftp.debian.org/debian/ unstable main deb-src http://ftp.debian.org/debian/ unstable main python-defaults-2.7.12/pydist/README.PyDist0000664000000000000000000000355412057417145015245 0ustar ============ PyDist files ============ DISTNAME [VRANGE] [DEPENDENCY][; [PEP386] [RULES]] ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ PyDist files help tools like dh_python2 to translate Python dependencies (from setup.py's install_requires or egg's requires.txt file) to Debian dependencies. Required fields: ~~~~~~~~~~~~~~~~ DISTNAME ```````` Python distribution name (you can find it at the beginning of .egg-info file/directory name that your package provides). Examples: * SQLAlchemy * Jinja2 * numpy Optional fields: ~~~~~~~~~~~~~~~~ VRANGE `````` Python version or version range the line applies to. Examples: * 2.6 (Python 2.6 only) * 2.5- (Python 2.5 and newer) * 2.5-2.7 (Python 2.5 or 2.6) * -2.7 (Python 2.6 or older) DEPENDENCY `````````` Debian dependency, multiple packages or versions are allowed. If not set, given Python distribution name will be ignored. Examples: * python-mako * python-jinja2 | python (>= 2.6) * python-sqlalchemy (>= 0.5), python-sqlalchemy (<< 0.6) PEP386 `````` Standards flag: upstream uses versioning schema described in PEP 386. RULES ````` Rules needed to translate upstream version to Debian one. If PEP386 is set, its rules will be applied later. Multiple rules are allowed, separate them with a space. Examples: * s/^/2:/ * s/alpha/~alpha/ s/^/1:/ Notes: ~~~~~~ You can use multiple lines if binary package provides more than one Python distribution or if you want to specify different dependencies for each Python version or version range. If you use dh_python2, it will install debian/binary_package_name.pydist file to /usr/share/python/dist/binary_package_name automatically. Complete examples: ~~~~~~~~~~~~~~~~~~ * SQLAlchemy python-sqlalchemy (>= 0.5), python-sqlalchemy (<< 0.6) * Mako python-mako; PEP386 * foo -2.5 python-oldfoo; s/^/3:/ * foo 2.5- python-foo; PEP386 * Bar 2.6- .. vim: ft=rst python-defaults-2.7.12/pydist/README.PyDist.html0000664000000000000000000002404612374331373016207 0ustar PyDist files

PyDist files

DISTNAME [VRANGE] [DEPENDENCY][; [PEP386] [RULES]]

PyDist files help tools like dh_python2 to translate Python dependencies (from setup.py's install_requires or egg's requires.txt file) to Debian dependencies.

Required fields:

DISTNAME

Python distribution name (you can find it at the beginning of .egg-info file/directory name that your package provides).

Examples:
  • SQLAlchemy
  • Jinja2
  • numpy

Optional fields:

VRANGE

Python version or version range the line applies to.

Examples:
  • 2.6 (Python 2.6 only)
  • 2.5- (Python 2.5 and newer)
  • 2.5-2.7 (Python 2.5 or 2.6)
  • -2.7 (Python 2.6 or older)

DEPENDENCY

Debian dependency, multiple packages or versions are allowed. If not set, given Python distribution name will be ignored.

Examples:
  • python-mako
  • python-jinja2 | python (>= 2.6)
  • python-sqlalchemy (>= 0.5), python-sqlalchemy (<< 0.6)

PEP386

Standards flag: upstream uses versioning schema described in PEP 386.

RULES

Rules needed to translate upstream version to Debian one. If PEP386 is set, its rules will be applied later. Multiple rules are allowed, separate them with a space.

Examples:
  • s/^/2:/
  • s/alpha/~alpha/ s/^/1:/

Notes:

You can use multiple lines if binary package provides more than one Python distribution or if you want to specify different dependencies for each Python version or version range.

If you use dh_python2, it will install debian/binary_package_name.pydist file to /usr/share/python/dist/binary_package_name automatically.

Complete examples:

  • SQLAlchemy python-sqlalchemy (>= 0.5), python-sqlalchemy (<< 0.6)
  • Mako python-mako; PEP386
  • foo -2.5 python-oldfoo; s/^/3:/
  • foo 2.5- python-foo; PEP386
  • Bar 2.6-