--- python-django-1.1.1.orig/debian/NEWS +++ python-django-1.1.1/debian/NEWS @@ -0,0 +1,63 @@ +python-django (1.0~beta2-3) unstable; urgency=low + + The transition from Django 0.96.2 to Django 1.0 means that your Django software + will probably have to be updated. A comprehensive list of changes since Django + 0.96 is available at the Django Wiki[1]. If you are upgrading from 0.95 + (Sarge), you should refer to this page[2] as well. + + The Debian package now also includes the full Django documentation in HTML + format[3] + + The following incomplete list of major changes is taken from the release notes + of 1.0alpha1[4], 1.0alpha2[5], 1.0beta1[6] ad 1.0beta2[7]. For more changes + see those release notes or [1]. + + Refactored admin application (newforms-admin) + The Django administrative interface (django.contrib.admin) has been + completely refactored; admin definitions are now completely decoupled from + model definitions (no more class Admin declaration in models!), rewritten + to use Django’s new form-handling library (introduced in the 0.96 release + as django.newforms, and now available as simply django.forms) and redesigned + with extensibility and customization in mind. Full documentation for the + admin application is available online in the official Django + documentation[8]. + + INSERT/UPDATE distinction + Although Django’s default behavior of having a model’s save() method + automatically determine whether to perform an INSERT or an UPDATE at + the SQL level is suitable for the majority of cases, there are occasional + situations where forcing one or the other is useful. As a result, models + can now support an additional parameter to save() which can force a specific + operation. Consult the database API documentation[9] for details and important + notes about appropriate use of this parameter. + + Split CacheMiddleware + Django’s CacheMiddleware has been split into three classes: CacheMiddleware + itself still exists and retains all of its previous functionality, but it + is now built from two separate middleware classes which handle the two parts + of caching (inserting into and reading from the cache) separately, offering + additional flexibility for situations where combining these functions into a + single middleware posed problems. Full details, including updated notes on + appropriate use, are in the caching documentation[10]. + + Refactored django.contrib.comments + As part of a Google Summer of Code project, Thejaswi Puthraya carried out + a major rewrite and refactoring of Django’s bundled comment system, greatly + increasing its flexibility and customizability. Full documentation[11] is + available, as well as an upgrade guide[12] if you were using the previous + incarnation of the comments application. + + [1] http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges + [2] http://code.djangoproject.com/wiki/OlderBackwardsIncompatibleChanges + [3] /usr/share/doc/python-django/html/index.html + [4] http://docs.djangoproject.com/en/dev/releases/1.0-alpha-1/#releases-1-0-alpha-1 + [5] http://docs.djangoproject.com/en/dev/releases/1.0-alpha-2/#releases-1-0-alpha-2 + [6] http://docs.djangoproject.com/en/dev/releases/1.0-beta/#releases-1-0-beta + [7] http://docs.djangoproject.com/en/dev/releases/1.0-beta-2/ + [8] /usr/share/doc/python-django/html/ref/contrib/admin.html + [9] /usr/share/doc/python-django/html/ref/models/index.html + [10] /usr/share/doc/python-django/html/topics/cache.html + [11] /usr/share/doc/python-django/html/ref/contrib/comments/index.html + [12] /usr/share/doc/python-django/html/ref/contrib/comments/upgrade.htm + + -- David Spreen Fri, 28 Aug 2008 09:10:16 -0700 --- python-django-1.1.1.orig/debian/pyversions +++ python-django-1.1.1/debian/pyversions @@ -0,0 +1 @@ +2.3- --- python-django-1.1.1.orig/debian/python-django-doc.examples +++ python-django-1.1.1/debian/python-django-doc.examples @@ -0,0 +1 @@ +examples/* --- python-django-1.1.1.orig/debian/changelog +++ python-django-1.1.1/debian/changelog @@ -0,0 +1,445 @@ +python-django (1.1.1-2) unstable; urgency=low + + * Remove embedded "decimal" code copy and use system version instead. The + "doctest" code copy cannot be removed as parts of Django depend on modified + behaviour. (Closes: #555419) + * Fix FTBFS in November by applying patch from upstream bug #12125. + (Closes: #555931) + * Fix FTBFS under Python 2.6.3 by applying patch from upstream bug #11993. + (Closes: #555969) + + -- Chris Lamb Tue, 01 Dec 2009 23:46:22 +0000 + +python-django (1.1.1-1) unstable; urgency=high + + * New upstream security release - fixes pathological regular expression + backtracking performance in URL and email fields which can be used as part + of a denial of service attack. + * Set Maintainer: to myself with thanks to Brett Parker. + * Bump versioned build dependency on quilt to help backporters. + (Closes: #547955) + + -- Chris Lamb Sat, 10 Oct 2009 10:17:52 +0100 + +python-django (1.1-4) unstable; urgency=low + + * Sourceful upload to drop dependency on Python 2.4. + + -- Chris Lamb Mon, 24 Aug 2009 08:16:11 +0100 + +python-django (1.1-3) unstable; urgency=low + + * Disable regression tests that require an internet connection. Patch by + Krzysztof Klimonda . (Closes: #542996) + * Bump Standards-Version to 3.8.3. + + -- Chris Lamb Sun, 23 Aug 2009 18:13:18 +0100 + +python-django (1.1-2) unstable; urgency=low + + * Run testsuite on build. + * Use "--with quilt" over specifying $(QUILT_STAMPFN)/unpatch dependencies. + * Override clean target correctly. + + -- Chris Lamb Fri, 14 Aug 2009 08:06:29 +0100 + +python-django (1.1-1) unstable; urgency=low + + * New upstream release. + * Merge from experimental: + - Ship FastCGI initscript and /etc/default file in python-django's examples + directory (Closes: #538863) + - Drop "05_10539-sphinx06-compatibility.diff"; it has been applied + upstream. + - Bump Standards-Version to 3.8.2. + + -- Chris Lamb Wed, 29 Jul 2009 11:26:28 +0200 + +python-django (1.0.2-7) unstable; urgency=low + + * Fix compatibility with Python 2.6 and Python transitions in general. + Thanks to Krzysztof Klimonda . + + -- Chris Lamb Sat, 16 May 2009 00:09:47 +0100 + +python-django (1.0.2-6) unstable; urgency=low + + * Backport patch from to fix + FTBFS when using python-sphinx >= 0.6. (Closes: #527492) + + -- Chris Lamb Sun, 10 May 2009 22:11:09 +0100 + +python-django (1.0.2-5) unstable; urgency=low + + * Fix issue where newly created projects do not have their manage.py file + executable. + + -- Chris Lamb Thu, 26 Mar 2009 23:42:14 +0000 + +python-django (1.0.2-4) unstable; urgency=low + + * Programatically replace most references to "django-admin.py" with + "django-admin" in the generated documentation. (Closes: #519937) + * Bump Standards-Version to 3.8.1; no changes. + + -- Chris Lamb Tue, 24 Mar 2009 00:50:26 +0000 + +python-django (1.0.2-3) unstable; urgency=low + + * Split documentation into a separate python-django-doc package due to size + (approximately 6Mb). + + -- Chris Lamb Tue, 10 Mar 2009 21:13:57 +0000 + +python-django (1.0.2-2) unstable; urgency=low + + * Don't rely on the internal layout of python-support. (Closes: #517052) + * Move to debhelper-based packaging for operational clarity: + - Remove bashisms from binary-post-install. + - Use quilt instead of simple-patchsys.mk and adjust existing patches so + that we can apply with -p1 for the "quilt" source package type. + * Adjust Build-Depends: + - Bump debhelper requirement 7.0.50 for override_* feature. + - Drop cdbs, python-dev and python-setuptools requirement. + - Just Build-Depend on `python', not `python-dev'. + - Drop versions on Build-Depends where they are satisfied in current + oldstable (ie. etch). + * debian/control: + - Add python-sqlite to Suggests. + - Remove repeated 'Priority' line in binary package stanza. + - Update crufty long and short descriptions. + - Add ${misc:Depends} in binary stanza for debhelper-using package. + + -- Chris Lamb Sun, 08 Mar 2009 06:01:59 +0000 + +python-django (1.0.2-1) unstable; urgency=low + + [ Chris Lamb ] + * New upstream bugfix release. Closes: #505783 + * Add myself to Uploaders with ACK from Brett. + + [ David Spreen ] + * Remove python-pysqlite2 from Recommends because Python 2.5 includes + sqlite library used by Django. Closes: 497886 + + [ Sandro Tosi ] + * debian/control + - switch Vcs-Browser field to viewsvn + + -- Chris Lamb Wed, 19 Nov 2008 21:31:00 +0000 + +python-django (1.0-1) unstable; urgency=low + + [ David Spreen ] + * New _stable_ upstream release. + + [ Raphael Hertzog ] + * This version fixes the latest security issue: + http://www.djangoproject.com/weblog/2008/sep/02/security/ + Closes: #497765 + * Don't include source files of documentation in the binary package, + keep only the HTML version. + * Updated README.Debian with information about the switch from 0.96 to + 1.0. + * Remove execute right on /etc/bash_completion.d/django_bash_completion + * Add debian/patches/04_hyphen-manpage.diff to fix a lintian message + (hyphen-used-as-minus-sign usr/share/man/man1/django-admin.1.gz:156). + * Don't compress javascript files. + * Add libjs-jquery to Recommends since it's used by the HTML + documentation. + + -- Raphael Hertzog Thu, 04 Sep 2008 08:33:32 +0200 + +python-django (1.0~beta2+ds-1) unstable; urgency=low + + * Bumping up upstream version to push sources into unstable. + (Thanks to Raphael Hertzog). + + -- David Spreen Sat, 30 Aug 2008 20:56:09 -0700 + +python-django (1.0~beta2-3) unstable; urgency=low + + [ David Spreen ] + * Updated the copyright information to include copyright and + licenses for individual contributions. + * Added the documentation to the main python-django package: + * debian/python-django.install + - Added installation of html documentation. + * debian/python-django.doc-base + - Added. + * debian/control + - Added Build-Depends-Indep on python-sphinx and libjs-jquery. + * debian/rules + - Readded code to build documentation. + - Readded code to link to libjs-jquery. + * debian/NEWS + - Fixed format. + - Added more comprehensive list of changes and references to + local documentation as well as the wiki pages for + backwards-incompatible changes. + * debian/python-django.docs + - Removed docs/*.txt since those are templates for the + generated docs now included with doc-base. + + -- David Spreen Fri, 29 Aug 2008 09:20:45 -0700 + +python-django (1.0~beta2-2) unstable; urgency=low + + [ David Spreen ] + * Removed all -doc related files temporarily to push beta2 into + unstable for extensive testing. The -doc package will be + readded once this package is in unstable as recommended in + http://lists.debian.org/debian-release/2008/08/msg01475.html. + * debian/python-django-doc.install + - Removed. + * debian/python-django-doc.doc-base + - Removed. + * debian/python-django-doc.examples + - Moved to python-django.examples. + * debian/rules + - Removed python-doc related build and post-installation. + * debian/control + - Removed binary package python-django-doc. + - Removed Build-Depends-Indep on python-sphinx and libjs-jquery. + * debian/python-django.install: + - Removed multiple package related issues. + + -- David Spreen Thu, 28 Aug 2008 20:15:21 -0700 + +python-django (1.0~beta2-1) experimental; urgency=low + + [ David Spreen ] + * The `hooray for the documentation' release! + * New upstream beta release. + * debian/control + - Updated standards version. + - Added python-sphinx and libjs-jquery. + - Added python-django-doc package depending on libjs-jquery. + * debian/docs + - Moved to debian/python-django.docs. + * debian/install + - Moved to debian/python-django.install. + * debian/manpages + - Moved to debian/python-django.manpages. + * debian/examples + - Moved to debian/python-django-doc.examples + * debian/README.Debian + - Moved to debian/python-django.README.Debian + * debian/python-django-doc.doc-base: + - Added doc-base file for the documentation. + * debian/python-django-doc.install: + - Added install file for sphinx generated documentation. + * debian/rules: + - Added code to generate documentation with sphinx and + replace convenience file of jquery.js with the respective + symlink to libjs-jquery. + + -- David Spreen Thu, 28 Aug 2008 10:22:29 -0700 + +python-django (1.0~beta1-1) experimental; urgency=low + + [ David Spreen ] + * New upstream beta release. Closes: #492956 + * debian/control: Added myself to Uploaders field. + * debian/watch: Added mangling for filename and version. Old watch file would + name the download 'tarball'. Also added mangling to handle alpha and beta + versioning. + * Drop debian/patches/01_add_shebang.diff as this has been fixed upstream. + * Drop debian/patches/02_bash_completion.diff as this has been committed + upstream http://code.djangoproject.com/ticket/7268. + * debian/control: Added python-flup to the Suggest field. Closes: #488123 + * debian/patches/03_manpage.diff: Adapted patch to new upstream version. + + [ Jan Dittberner ] + * add debian/watch file. + + -- David Spreen Fri, 15 Aug 2008 16:05:07 -0700 + +python-django (0.97~svn7534-1) experimental; urgency=low + + * New upstream snapshot. Closes: #409565, #481051 + - Include an XSS security fix (CVE-2008-2302). Closes: #481164 + * Drop debian/patches/04_pg_version_fix.diff as another fix + has been committed upstream (see http://code.djangoproject.com/ticket/6433 + and http://code.djangoproject.com/changeset/7415). + * Add some headers to the remaining patches. + + -- Raphael Hertzog Mon, 19 May 2008 23:41:50 +0200 + +python-django (0.97~svn7189-1) experimental; urgency=low + + * New upstream snapshot including bash completion fix + Closes: #450913 + + -- Brett Parker Sun, 02 Mar 2008 12:59:03 +0000 + +python-django (0.97~svn7047-2) experimental; urgency=low + + [ Brett Parker ] + * Patch for postgresql version issue with 8.3 beta/rc releases + Closes: #462058 + + [ Raphael Hertzog ] + * Updated Standards-Version to 3.7.3. + * Adjusted build-dependency on python-setuptools to strip the -1 part. + + -- Brett Parker Wed, 6 Feb 2008 15:15:37 +0000 + +python-django (0.97~svn7047-1) experimental; urgency=low + + * New upstream snapshot (rev 7047) + - tarball prepared by Gabriel Falcão Gonçalves de Moura + + + -- Gustavo Noronha Silva Tue, 29 Jan 2008 10:54:47 -0200 + +python-django (0.97~svn6996-1) experimental; urgency=low + + * New upstream snapshot + * debian/control: + - added myself to Uploaders + + -- Gustavo Noronha Silva Sat, 05 Jan 2008 20:53:23 -0200 + +python-django (0.97~svn6668-2) UNRELEASED; urgency=low + + [ Raphael Hertzog ] + * Install examples with dh_installexamples instead of dh_installdocs + (change done by Ubuntu) as empty files are kept. + + [ Sandro Tosi ] + * debian/control + - uniforming Vcs-Browser field + + -- Raphael Hertzog Mon, 17 Dec 2007 09:09:16 +0100 + +python-django (0.97~svn6668-1) experimental; urgency=low + + * New SVN snapshot (rev 6668) + - Auth system delegations + - Apps can now have thier own management commands + - Fix for CVE-2007-5712 remote denial of service + Closes: #448838 + * Fix missing upstream info in changelog + Closes: #450659 + + -- Brett Parker Sun, 11 Nov 2007 10:15:55 +0000 + +python-django (0.96+svn6373-1) experimental; urgency=low + + [ Raphael Hertzog ] + * New SVN snapshot (rev 6373, a few days after the last Django sprint). + * Note: The version 0.96+svn6034-1 never got uploaded. + * Rename XS-Vcs* fields to Vcs-* since they are now supported by dpkg. + + [ Piotr Ożarowski ] + * XS-Vcs-Browser and Homepage fields added + + -- Raphael Hertzog Thu, 04 Oct 2007 14:59:01 +0200 + +python-django (0.96+svn6034-1) experimental; urgency=low + + [ Brett Parker] + * New SVN snapshot (rev 6034). + * validate and runserver commands now display the number of errors + (returning back to previous functionality). + * Small documentation fixes + * assertRedirects handling for paths with get data + * start{project,app} no make sure files created are writable + * Add man page for django-admin to the debian package + + -- Brett Parker Sat, 8 Sep 2007 10:37:00 +0100 + +python-django (0.96+svn6020-1) experimental; urgency=low + + * New SVN snapshot (rev 6020). + + -- Raphael Hertzog Sun, 26 Aug 2007 18:16:08 +0200 + +python-django (0.96+svn5779-1) experimental; urgency=low + + * SVN snapshot (rev 5779) packaged to experimental as many interesting + Django applications rely on newer unreleased features. + + -- Raphael Hertzog Tue, 31 Jul 2007 13:40:18 +0200 + +python-django (0.96-1) unstable; urgency=low + + [ Brett Parker ] + * New upstream release - introduces some backwards incompatible changes, see + README.Debian or the backwards incompatible changes page at + http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges + * Add documentation from upstream to /usr/share/doc/python-django + Closes: #411249 + * Install the bash completion file from extras in to + /etc/bash_completion.d/django_bash_completion + Closes: #414399 + * Egg support dropped as it's been dropped by upstream. + + -- Brett Parker Sun, 25 Mar 2007 19:18:39 +0100 + +python-django (0.95.1-1) unstable; urgency=low + + [ Brett Parker ] + * New upstream minor release for security bugs: + - http://www.djangoproject.com/weblog/2007/jan/21/0951/ + - Fixes a small security vulnerability in the script Django's + internationalization system uses to compile translation files + (changeset 4360 in the "0.95-bugfixes" branch). + - fix for a bug in Django's authentication middleware which could cause + apparent "caching" of a logged-in user (changeset 4361). + - patch which disables debugging mode in the flup FastCGI package Django + uses to launch its FastCGI server, which prevents tracebacks from + bubbling up during production use (changeset 4363). + Closes: #407786, #407607 + * Sets Recommends to python-psycopg and moves other database engines to + the Suggests field. + + [ Raphael Hertzog ] + * Use python-pysqlite2 as default database engine in Recommends. Others are + in Suggests. Closes: #403761 + * Add python-psycopg2 in Suggests. Closes: #407489 + + -- Raphael Hertzog Sun, 21 Jan 2007 17:45:50 +0100 + +python-django (0.95-3) unstable; urgency=low + + * Integrate 2 upstream changesets: + - http://code.djangoproject.com/changeset/3754 as + debian/patches/04_sec_fix_auth.diff + Fixes a possible case of mis-authentication due to bad caching. + Closes: #407521 + - http://code.djangoproject.com/changeset/3592 as + debian/patches/03_sec_fix_compile-messages.diff + Fixes an (unlikely) arbitrary command execution if the user is blindly + running compile-messages.py on a untrusted set of *.po files. + Closes: #407519 + + -- Raphael Hertzog Sat, 16 Dec 2006 15:13:29 +0100 + +python-django (0.95-2) unstable; urgency=low + + [ Piotr Ozarowski ] + * Added XS-Vcs-Svn field + + [ Brett Parker ] + * Made manage.py get a shebang with the version of python + used when running django-admin (closes: #401616) + * Created a convenience /usr/lib/python-django/bin symlink. + + [ Raphael Hertzog ] + * Adapted Brett's work to better fit my views of the packaging. + + -- Raphael Hertzog Sat, 16 Dec 2006 11:03:20 +0100 + +python-django (0.95-1) unstable; urgency=low + + [ Brett Parker ] + * 0.95 release - initial packaging + + [ Raphael Hertzog ] + * Fix recommends: s/python-sqlite/python-pysqlite2/ + * Add debian/pyversions to ensure that we have at least python 2.3 (and to + work around bug #391689 of python-support). + + -- Raphael Hertzog Mon, 9 Oct 2006 12:10:27 +0200 --- python-django-1.1.1.orig/debian/python-django.examples +++ python-django-1.1.1/debian/python-django.examples @@ -0,0 +1 @@ +debian/contrib/* --- python-django-1.1.1.orig/debian/compat +++ python-django-1.1.1/debian/compat @@ -0,0 +1 @@ +7 --- python-django-1.1.1.orig/debian/rules +++ python-django-1.1.1/debian/rules @@ -0,0 +1,57 @@ +#!/usr/bin/make -f + +include /usr/share/python/python.mk + +PREFIX = debian/python-django +DJANGO_DIR = $(PREFIX)/$(call py_libdir_sh,`pyversions -d`)/django + +%: + dh --with quilt $@ + +override_dh_auto_clean: + rm -rf docs.debian testproject + dh_auto_clean + +override_dh_auto_build: + dh_auto_build + + # Build the HTML documentation. + # We programmatically replace most instances of django-admin.py with + # django-admin and remove the source files from the target _build. + cp -r docs docs.debian + find docs.debian -type f -print0 | xargs -0r perl -pi -e 's|(? +Uploaders: Debian Python Modules Team , Raphaël Hertzog +Standards-Version: 3.8.3 +Build-Depends: debhelper (>= 7.0.50), python-support, quilt (>= 0.46-7~), python (>= 2.5) | python-sqlite +Build-Depends-Indep: python-sphinx, libjs-jquery +Homepage: http://www.djangoproject.com/ +Vcs-Svn: svn://svn.debian.org/python-modules/packages/python-django/trunk/ +Vcs-Browser: http://svn.debian.org/viewsvn/python-modules/packages/python-django/trunk/ + +Package: python-django +Architecture: all +Depends: ${misc:Depends}, ${python:Depends} +Suggests: python-psycopg2, python-psycopg, python-mysqldb, python-flup, python-sqlite +Description: High-level Python web development framework + Django is a high-level web application framework that loosely follows the + model-view-controller design pattern. + . + Python's equivalent to Ruby on Rails, Django lets you build complex + data-driven websites quickly and easily - Django focuses on automating as much + as possible and adhering to the "Don't Repeat Yourself" (DRY) principle. + . + Django additionally emphasizes reusability and "pluggability" of components; + many generic third-party "applications" are available to enhance projects or + to simply to reduce development time even further. + . + Notable features include: + * An object-relational mapper (ORM) + * Automatic admin interface + * Elegant URL dispatcher + * Form serialization and validation system + * Templating system + * Lightweight, standalone web server for development and testing + * Internationalization support + * Testing framework and client + +Package: python-django-doc +Section: doc +Architecture: all +Depends: ${misc:Depends} +Recommends: libjs-jquery +Description: High-level Python web development framework (documentation) + Django is a high-level web application framework that loosely follows the + model-view-controller design pattern. + . + Python's equivalent to Ruby on Rails, Django lets you build complex + data-driven websites quickly and easily - Django focuses on automating as much + as possible and adhering to the "Don't Repeat Yourself" (DRY) principle. + . + Django additionally emphasizes reusability and "pluggability" of components; + many generic third-party "applications" are available to enhance projects or + to simply to reduce development time even further. + . + This package contains the HTML documentation and example projects. --- python-django-1.1.1.orig/debian/python-django.install +++ python-django-1.1.1/debian/python-django.install @@ -0,0 +1,2 @@ +usr/ +extras/django_bash_completion etc/bash_completion.d/ --- python-django-1.1.1.orig/debian/python-django-doc.doc-base +++ python-django-1.1.1/debian/python-django-doc.doc-base @@ -0,0 +1,20 @@ +Document: python-django-doc +Title: Python Django Documentation +Author: Django Software Foundation +Abstract: This documentation gives an introduction + to Django and its contributed packages like its automatic + admin and the user authentication applications. +Section: Programming/Python + +Format: HTML +Index: /usr/share/doc/python-django-doc/html/index.html +Files: /usr/share/doc/python-django-doc/html/*.html + /usr/share/doc/python-django-doc/html/faq/*.html + /usr/share/doc/python-django-doc/html/howto/*.html + /usr/share/doc/python-django-doc/html/internals/*.html + /usr/share/doc/python-django-doc/html/intro/*.html + /usr/share/doc/python-django-doc/html/misc/*.html + /usr/share/doc/python-django-doc/html/obsolete/*.html + /usr/share/doc/python-django-doc/html/ref/*.html + /usr/share/doc/python-django-doc/html/releases/*.html + /usr/share/doc/python-django-doc/html/topics/*.html --- python-django-1.1.1.orig/debian/python-django.docs +++ python-django-1.1.1/debian/python-django.docs @@ -0,0 +1,2 @@ +README +AUTHORS --- python-django-1.1.1.orig/debian/copyright +++ python-django-1.1.1/debian/copyright @@ -0,0 +1,312 @@ +This package was debianized by Brett Parker with +the assistance of Raphael Hertzog , Gustavo Noronha Silva +, David Spreen and the Debian Python +Modules Team . + +The upstream source is available from . + +Main Django Code Licence: +========================= +Copyright (c) Django Software Foundation and individual contributors. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Django nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Individual copyright holders stated in Main Django License are listed +in /usr/share/doc/python-django/AUTHORS.gz. + +PyDispatcher Licence (django/dispatch/*): +========================================= + + Copyright (c) 2001-2003, Patrick K. O'Brien and Contributors + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials + provided with the distribution. + + The name of Patrick K. O'Brien, or the name of any Contributor, + may not be used to endorse or promote products derived from this + software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + COPYRIGHT HOLDERS AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + OF THE POSSIBILITY OF SUCH DAMAGE. + +License of django/utils/simplejson/* +==================================== + +Copyright (c) 2006 Bob Ippolito + +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. + +License for django/utils/functional.py and django/utils/_decimal.py +(License taken from Python 2.5) +======================================================================= + +functional.py: +Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007 Python Software Foundation + +decimal.py: +Copyright (c) 2004 Python Software Foundation + + +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 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. + +django/utils/autoreload.py +=========================== + +Portions Copyright (c) 2004 CherryPy Team + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + * Neither the name of the CherryPy Team nor the names of its contributors + may be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE + FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, + OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Some code taken from Ian Bicking's Paste which is released under the MIT +License: + +Copyright (c) 2008 Ian Bicking + +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. + +django/contrib/gis/geos/* and django/contrib/gis/gdal/* +======================================================== +Copyright (c) 2007, Justin Bronn + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of GEOSGeometry nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +django/contrib/gis/measure.py: +=============================== +Copyright (c) 2007, Robert Coup + +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + 3. Neither the name of Distance nor the names of its contributors may be used + to endorse or promote products derived from this software without + specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +docs/_static/reset-fonts-grids.css: +==================================== +Copyright (c) 2008, Yahoo! Inc. All rights reserved. + +Software License Agreement (BSD License), downloaded from + on Friday, Aug 29 2008 + +Copyright (c) 2006, Yahoo! Inc. +All rights reserved. + +Redistribution and use of this software in source and binary forms, with or +without modification, are permitted provided that the following conditions are +met: + +* Redistributions of source code must retain the above + copyright notice, this list of conditions and the + following disclaimer. + +* Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other + materials provided with the distribution. + +* Neither the name of Yahoo! Inc. nor the names of its + contributors may be used to endorse or promote products + derived from this software without specific prior + written permission of Yahoo! Inc. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE. --- python-django-1.1.1.orig/debian/python-django.README.Debian +++ python-django-1.1.1/debian/python-django.README.Debian @@ -0,0 +1,178 @@ +0.96 -> 1.0 +=========== + +Django 1.0 has a number of backwards-incompatible changes from Django +0.96. If you have apps written against Django 0.96 that you need to port, +see the detailed porting guide: +/usr/share/doc/python-django/html/releases/1.0-porting-guide.html +or +http://docs.djangoproject.com/en/dev/releases/1.0-porting-guide/ + +You can also find a complete list of of backwards incompatible changes +here: +http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges + +0.95 -> 0.96 +============ + +Information here has been gathered from: + http://www.djangoproject.com/documentation/release_notes_0.96/ +and + http://code.djangoproject.com/wiki/BackwardsIncompatibleChanges + +Backwards Incompatible Changes +------------------------------ + + Database constraint names changed + ================================= + + As of [3512], the format of the constraint names Django generates for + foreign key references changed slightly. These names are only used + sometimes, when it is not possible to put the reference directly on the + affected column, so this is not always visible. + + The effect of this change is that manage.py reset app_name and similar + commands may generate SQL with invalid constraint names and thus generate + an error when run against the database (the database server will complain + about the constraint not existing). To fix this, you will need to tweak the + output of manage.py sqlreset app_name to match the correct constraint names + and pass the results to the database server manually. + + Backslash escaping changed + ========================== + + As of [3552], the Django database API now escapes backslashes given as + query parameters. If you have any database API code that match backslashes, + and it was working before (despite the broken escaping), you'll have to + change your code to "unescape" the slashes one level. + + For example, this used to work: + + # Code that matches a single backslash + MyModel.objects.filter(text__contains='\\\\') + + But it should be rewritten as this: + + # Code that matches a single backslash + MyModel.objects.filter(text__contains='\\') + + Removed ENABLE_PSYCO setting + ============================ + + As of [3877], the ENABLE_PSYCO setting no longer exists. If your settings + file includes ENABLE_PSYCO, nothing will break per se, but it just won't do + anything. If you want to use Psyco with Django, write some custom + middleware that activates Psyco. + + Changed Admin.manager option to more flexible hook + ================================================== + + As of [4342], the manager option to class Admin no longer exists. This + option was undocumented, but we're mentioning the change here in case you + used it. In favor of this option, class Admin may now define one of these + methods: + + * queryset() + * queryset_add() + * queryset_change() + + These give you much more flexibility. + + Note that this change was made to the NewformsAdminBranch. (We initially + called the new method change_list_queryset, but this was changed in [4584] + to be more flexible.) The change will not be made to trunk until that + branch is merged to trunk. + + Changed prepopulate_from to be defined in the Admin class, + not database field classes ¶ + ========================================================== + + As of [4446], the prepopulate_from option to database fields no + longer exists. It's been discontinued in favor of the new + prepopulated_fields option on class Admin. The new + prepopulated_fields option, if given, should be a dictionary + mapping field names to lists/tuples of field names. Here's an + example comparing old syntax and new syntax: + + # OLD: + class MyModel(models.Model): + first_name = models.CharField(maxlength=30) + last_name = models.CharField(maxlength=30) + slug = models.CharField(maxlength=60, prepopulate_from=('first_name', 'last_name')) + + class Admin: + pass + + # NEW: + class MyModel(models.Model): + first_name = models.CharField(maxlength=30) + last_name = models.CharField(maxlength=30) + slug = models.CharField(maxlength=60) + + class Admin: + prepopulated_fields = {'slug': ('first_name', 'last_name')} + + Moved admin doc views into django.contrib.admindocs + ==================================================== + + As of [4585], the documentation views for the Django admin site were moved + into a new package, django.contrib.admindocs. + + The admin docs, which aren't documented very well, were located at docs/ in + the admin site. They're also linked-to by the "Documentation" link in the + upper right of default admin templates. + + Because we've moved the doc views, you now have to activate admin docs + explicitly. Do this by adding the following line to your URLconf: + + (r'^admin/doc/', include('django.contrib.admindocs.urls')), + + Note that this change was made to the NewformsAdminBranch. The change will + not be made to trunk until that branch is merged to trunk. + + Enforcing MySQLdb version + ========================= + + As of [4724], Django will raise an error if you try to use the MySQL + backend with a MySQLdb ( MySQL python module) version earlier than 1.2.1p2. + There were significant, production-related bugs in earlier versions, so we + have upgraded the minimum requirement. + + In [4767], a mysql_old backend was added, that is identical to the original + mysql backend prior to the change in [4724]. This backend can be used if + upgrading the MySQLdb module is not immediately possible, however, it is + deprecated and no further development will be done on it. + +New Features +------------ + + New forms library + ================= + + The new forms library has been merged from the new forms branch in to + django.newforms in 0.96, the next revision will replace django.forms with + django.newforms, the current forms library is already copied to + django.oldforms to make the transition easier - it's advised to either + upgrade your forms code to the newforms library or to change your imports + as follows: + + from django import forms + becomes + from django import oldforms as forms + + URLconf improvements + ==================== + + It's now possible to use imported views in the urlconf rather than a string + representing the view to call. + + Test framework + ============== + + Now possible to write tests based on doctest and unittest + + Admin area changes + ================== + + Changes to the user adding and updating views so that you don't need to + worry about hashed passwords. --- python-django-1.1.1.orig/debian/patches/06_python_2.6.3_regression.diff +++ python-django-1.1.1/debian/patches/06_python_2.6.3_regression.diff @@ -0,0 +1,14 @@ +Forwarded-Upstream: http://code.djangoproject.com/changeset/11619 +Comment: + Fix FTBFS under Python 2.6.3; int(Decimal('nan')) raises ValueError instead + of returning None. + +--- ./django/template/defaultfilters.py (revision 10543) ++++ ./django/template/defaultfilters.py (revision 11619) +@@ -163,5 +163,5 @@ + try: + m = int(d) - d +- except (OverflowError, InvalidOperation): ++ except (ValueError, OverflowError, InvalidOperation): + return input_val + --- python-django-1.1.1.orig/debian/patches/02-embedded_code_copies.diff +++ python-django-1.1.1/debian/patches/02-embedded_code_copies.diff @@ -0,0 +1,3088 @@ + + Use the system version of the decimal module. + + -- Chris Lamb Tue, 01 Dec 2009 22:43:48 +0000 + +--- a/django/utils/_decimal.py 2009-12-01 22:47:42.000000000 +0000 ++++ b/django/utils/_decimal.py 2009-12-01 22:48:42.000000000 +0000 +@@ -1,3079 +1 @@ +-# Copyright (c) 2004 Python Software Foundation. +-# All rights reserved. +- +-# Written by Eric Price +-# and Facundo Batista +-# and Raymond Hettinger +-# and Aahz +-# and Tim Peters +- +-# This module is currently Py2.3 compatible and should be kept that way +-# unless a major compelling advantage arises. IOW, 2.3 compatibility is +-# strongly preferred, but not guaranteed. +- +-# Also, this module should be kept in sync with the latest updates of +-# the IBM specification as it evolves. Those updates will be treated +-# as bug fixes (deviation from the spec is a compatibility, usability +-# bug) and will be backported. At this point the spec is stabilizing +-# and the updates are becoming fewer, smaller, and less significant. +- +-""" +-This is a Py2.3 implementation of decimal floating point arithmetic based on +-the General Decimal Arithmetic Specification: +- +- www2.hursley.ibm.com/decimal/decarith.html +- +-and IEEE standard 854-1987: +- +- www.cs.berkeley.edu/~ejr/projects/754/private/drafts/854-1987/dir.html +- +-Decimal floating point has finite precision with arbitrarily large bounds. +- +-The purpose of the module is to support arithmetic using familiar +-"schoolhouse" rules and to avoid the some of tricky representation +-issues associated with binary floating point. The package is especially +-useful for financial applications or for contexts where users have +-expectations that are at odds with binary floating point (for instance, +-in binary floating point, 1.00 % 0.1 gives 0.09999999999999995 instead +-of the expected Decimal("0.00") returned by decimal floating point). +- +-Here are some examples of using the decimal module: +- +->>> from decimal import * +->>> setcontext(ExtendedContext) +->>> Decimal(0) +-Decimal("0") +->>> Decimal("1") +-Decimal("1") +->>> Decimal("-.0123") +-Decimal("-0.0123") +->>> Decimal(123456) +-Decimal("123456") +->>> Decimal("123.45e12345678901234567890") +-Decimal("1.2345E+12345678901234567892") +->>> Decimal("1.33") + Decimal("1.27") +-Decimal("2.60") +->>> Decimal("12.34") + Decimal("3.87") - Decimal("18.41") +-Decimal("-2.20") +->>> dig = Decimal(1) +->>> print dig / Decimal(3) +-0.333333333 +->>> getcontext().prec = 18 +->>> print dig / Decimal(3) +-0.333333333333333333 +->>> print dig.sqrt() +-1 +->>> print Decimal(3).sqrt() +-1.73205080756887729 +->>> print Decimal(3) ** 123 +-4.85192780976896427E+58 +->>> inf = Decimal(1) / Decimal(0) +->>> print inf +-Infinity +->>> neginf = Decimal(-1) / Decimal(0) +->>> print neginf +--Infinity +->>> print neginf + inf +-NaN +->>> print neginf * inf +--Infinity +->>> print dig / 0 +-Infinity +->>> getcontext().traps[DivisionByZero] = 1 +->>> print dig / 0 +-Traceback (most recent call last): +- ... +- ... +- ... +-DivisionByZero: x / 0 +->>> c = Context() +->>> c.traps[InvalidOperation] = 0 +->>> print c.flags[InvalidOperation] +-0 +->>> c.divide(Decimal(0), Decimal(0)) +-Decimal("NaN") +->>> c.traps[InvalidOperation] = 1 +->>> print c.flags[InvalidOperation] +-1 +->>> c.flags[InvalidOperation] = 0 +->>> print c.flags[InvalidOperation] +-0 +->>> print c.divide(Decimal(0), Decimal(0)) +-Traceback (most recent call last): +- ... +- ... +- ... +-InvalidOperation: 0 / 0 +->>> print c.flags[InvalidOperation] +-1 +->>> c.flags[InvalidOperation] = 0 +->>> c.traps[InvalidOperation] = 0 +->>> print c.divide(Decimal(0), Decimal(0)) +-NaN +->>> print c.flags[InvalidOperation] +-1 +->>> +-""" +- +-__all__ = [ +- # Two major classes +- 'Decimal', 'Context', +- +- # Contexts +- 'DefaultContext', 'BasicContext', 'ExtendedContext', +- +- # Exceptions +- 'DecimalException', 'Clamped', 'InvalidOperation', 'DivisionByZero', +- 'Inexact', 'Rounded', 'Subnormal', 'Overflow', 'Underflow', +- +- # Constants for use in setting up contexts +- 'ROUND_DOWN', 'ROUND_HALF_UP', 'ROUND_HALF_EVEN', 'ROUND_CEILING', +- 'ROUND_FLOOR', 'ROUND_UP', 'ROUND_HALF_DOWN', +- +- # Functions for manipulating contexts +- 'setcontext', 'getcontext' +-] +- +-import copy as _copy +- +-#Rounding +-ROUND_DOWN = 'ROUND_DOWN' +-ROUND_HALF_UP = 'ROUND_HALF_UP' +-ROUND_HALF_EVEN = 'ROUND_HALF_EVEN' +-ROUND_CEILING = 'ROUND_CEILING' +-ROUND_FLOOR = 'ROUND_FLOOR' +-ROUND_UP = 'ROUND_UP' +-ROUND_HALF_DOWN = 'ROUND_HALF_DOWN' +- +-#Rounding decision (not part of the public API) +-NEVER_ROUND = 'NEVER_ROUND' # Round in division (non-divmod), sqrt ONLY +-ALWAYS_ROUND = 'ALWAYS_ROUND' # Every operation rounds at end. +- +-#Errors +- +-class DecimalException(ArithmeticError): +- """Base exception class. +- +- Used exceptions derive from this. +- If an exception derives from another exception besides this (such as +- Underflow (Inexact, Rounded, Subnormal) that indicates that it is only +- called if the others are present. This isn't actually used for +- anything, though. +- +- handle -- Called when context._raise_error is called and the +- trap_enabler is set. First argument is self, second is the +- context. More arguments can be given, those being after +- the explanation in _raise_error (For example, +- context._raise_error(NewError, '(-x)!', self._sign) would +- call NewError().handle(context, self._sign).) +- +- To define a new exception, it should be sufficient to have it derive +- from DecimalException. +- """ +- def handle(self, context, *args): +- pass +- +- +-class Clamped(DecimalException): +- """Exponent of a 0 changed to fit bounds. +- +- This occurs and signals clamped if the exponent of a result has been +- altered in order to fit the constraints of a specific concrete +- representation. This may occur when the exponent of a zero result would +- be outside the bounds of a representation, or when a large normal +- number would have an encoded exponent that cannot be represented. In +- this latter case, the exponent is reduced to fit and the corresponding +- number of zero digits are appended to the coefficient ("fold-down"). +- """ +- +- +-class InvalidOperation(DecimalException): +- """An invalid operation was performed. +- +- Various bad things cause this: +- +- Something creates a signaling NaN +- -INF + INF +- 0 * (+-)INF +- (+-)INF / (+-)INF +- x % 0 +- (+-)INF % x +- x._rescale( non-integer ) +- sqrt(-x) , x > 0 +- 0 ** 0 +- x ** (non-integer) +- x ** (+-)INF +- An operand is invalid +- """ +- def handle(self, context, *args): +- if args: +- if args[0] == 1: #sNaN, must drop 's' but keep diagnostics +- return Decimal( (args[1]._sign, args[1]._int, 'n') ) +- return NaN +- +-class ConversionSyntax(InvalidOperation): +- """Trying to convert badly formed string. +- +- This occurs and signals invalid-operation if an string is being +- converted to a number and it does not conform to the numeric string +- syntax. The result is [0,qNaN]. +- """ +- +- def handle(self, context, *args): +- return (0, (0,), 'n') #Passed to something which uses a tuple. +- +-class DivisionByZero(DecimalException, ZeroDivisionError): +- """Division by 0. +- +- This occurs and signals division-by-zero if division of a finite number +- by zero was attempted (during a divide-integer or divide operation, or a +- power operation with negative right-hand operand), and the dividend was +- not zero. +- +- The result of the operation is [sign,inf], where sign is the exclusive +- or of the signs of the operands for divide, or is 1 for an odd power of +- -0, for power. +- """ +- +- def handle(self, context, sign, double = None, *args): +- if double is not None: +- return (Infsign[sign],)*2 +- return Infsign[sign] +- +-class DivisionImpossible(InvalidOperation): +- """Cannot perform the division adequately. +- +- This occurs and signals invalid-operation if the integer result of a +- divide-integer or remainder operation had too many digits (would be +- longer than precision). The result is [0,qNaN]. +- """ +- +- def handle(self, context, *args): +- return (NaN, NaN) +- +-class DivisionUndefined(InvalidOperation, ZeroDivisionError): +- """Undefined result of division. +- +- This occurs and signals invalid-operation if division by zero was +- attempted (during a divide-integer, divide, or remainder operation), and +- the dividend is also zero. The result is [0,qNaN]. +- """ +- +- def handle(self, context, tup=None, *args): +- if tup is not None: +- return (NaN, NaN) #for 0 %0, 0 // 0 +- return NaN +- +-class Inexact(DecimalException): +- """Had to round, losing information. +- +- This occurs and signals inexact whenever the result of an operation is +- not exact (that is, it needed to be rounded and any discarded digits +- were non-zero), or if an overflow or underflow condition occurs. The +- result in all cases is unchanged. +- +- The inexact signal may be tested (or trapped) to determine if a given +- operation (or sequence of operations) was inexact. +- """ +- pass +- +-class InvalidContext(InvalidOperation): +- """Invalid context. Unknown rounding, for example. +- +- This occurs and signals invalid-operation if an invalid context was +- detected during an operation. This can occur if contexts are not checked +- on creation and either the precision exceeds the capability of the +- underlying concrete representation or an unknown or unsupported rounding +- was specified. These aspects of the context need only be checked when +- the values are required to be used. The result is [0,qNaN]. +- """ +- +- def handle(self, context, *args): +- return NaN +- +-class Rounded(DecimalException): +- """Number got rounded (not necessarily changed during rounding). +- +- This occurs and signals rounded whenever the result of an operation is +- rounded (that is, some zero or non-zero digits were discarded from the +- coefficient), or if an overflow or underflow condition occurs. The +- result in all cases is unchanged. +- +- The rounded signal may be tested (or trapped) to determine if a given +- operation (or sequence of operations) caused a loss of precision. +- """ +- pass +- +-class Subnormal(DecimalException): +- """Exponent < Emin before rounding. +- +- This occurs and signals subnormal whenever the result of a conversion or +- operation is subnormal (that is, its adjusted exponent is less than +- Emin, before any rounding). The result in all cases is unchanged. +- +- The subnormal signal may be tested (or trapped) to determine if a given +- or operation (or sequence of operations) yielded a subnormal result. +- """ +- pass +- +-class Overflow(Inexact, Rounded): +- """Numerical overflow. +- +- This occurs and signals overflow if the adjusted exponent of a result +- (from a conversion or from an operation that is not an attempt to divide +- by zero), after rounding, would be greater than the largest value that +- can be handled by the implementation (the value Emax). +- +- The result depends on the rounding mode: +- +- For round-half-up and round-half-even (and for round-half-down and +- round-up, if implemented), the result of the operation is [sign,inf], +- where sign is the sign of the intermediate result. For round-down, the +- result is the largest finite number that can be represented in the +- current precision, with the sign of the intermediate result. For +- round-ceiling, the result is the same as for round-down if the sign of +- the intermediate result is 1, or is [0,inf] otherwise. For round-floor, +- the result is the same as for round-down if the sign of the intermediate +- result is 0, or is [1,inf] otherwise. In all cases, Inexact and Rounded +- will also be raised. +- """ +- +- def handle(self, context, sign, *args): +- if context.rounding in (ROUND_HALF_UP, ROUND_HALF_EVEN, +- ROUND_HALF_DOWN, ROUND_UP): +- return Infsign[sign] +- if sign == 0: +- if context.rounding == ROUND_CEILING: +- return Infsign[sign] +- return Decimal((sign, (9,)*context.prec, +- context.Emax-context.prec+1)) +- if sign == 1: +- if context.rounding == ROUND_FLOOR: +- return Infsign[sign] +- return Decimal( (sign, (9,)*context.prec, +- context.Emax-context.prec+1)) +- +- +-class Underflow(Inexact, Rounded, Subnormal): +- """Numerical underflow with result rounded to 0. +- +- This occurs and signals underflow if a result is inexact and the +- adjusted exponent of the result would be smaller (more negative) than +- the smallest value that can be handled by the implementation (the value +- Emin). That is, the result is both inexact and subnormal. +- +- The result after an underflow will be a subnormal number rounded, if +- necessary, so that its exponent is not less than Etiny. This may result +- in 0 with the sign of the intermediate result and an exponent of Etiny. +- +- In all cases, Inexact, Rounded, and Subnormal will also be raised. +- """ +- +-# List of public traps and flags +-_signals = [Clamped, DivisionByZero, Inexact, Overflow, Rounded, +- Underflow, InvalidOperation, Subnormal] +- +-# Map conditions (per the spec) to signals +-_condition_map = {ConversionSyntax:InvalidOperation, +- DivisionImpossible:InvalidOperation, +- DivisionUndefined:InvalidOperation, +- InvalidContext:InvalidOperation} +- +-##### Context Functions ####################################### +- +-# The getcontext() and setcontext() function manage access to a thread-local +-# current context. Py2.4 offers direct support for thread locals. If that +-# is not available, use threading.currentThread() which is slower but will +-# work for older Pythons. If threads are not part of the build, create a +-# mock threading object with threading.local() returning the module namespace. +- +-try: +- import threading +-except ImportError: +- # Python was compiled without threads; create a mock object instead +- import sys +- class MockThreading: +- def local(self, sys=sys): +- return sys.modules[__name__] +- threading = MockThreading() +- del sys, MockThreading +- +-try: +- threading.local +- +-except AttributeError: +- +- #To fix reloading, force it to create a new context +- #Old contexts have different exceptions in their dicts, making problems. +- if hasattr(threading.currentThread(), '__decimal_context__'): +- del threading.currentThread().__decimal_context__ +- +- def setcontext(context): +- """Set this thread's context to context.""" +- if context in (DefaultContext, BasicContext, ExtendedContext): +- context = context.copy() +- context.clear_flags() +- threading.currentThread().__decimal_context__ = context +- +- def getcontext(): +- """Returns this thread's context. +- +- If this thread does not yet have a context, returns +- a new context and sets this thread's context. +- New contexts are copies of DefaultContext. +- """ +- try: +- return threading.currentThread().__decimal_context__ +- except AttributeError: +- context = Context() +- threading.currentThread().__decimal_context__ = context +- return context +- +-else: +- +- local = threading.local() +- if hasattr(local, '__decimal_context__'): +- del local.__decimal_context__ +- +- def getcontext(_local=local): +- """Returns this thread's context. +- +- If this thread does not yet have a context, returns +- a new context and sets this thread's context. +- New contexts are copies of DefaultContext. +- """ +- try: +- return _local.__decimal_context__ +- except AttributeError: +- context = Context() +- _local.__decimal_context__ = context +- return context +- +- def setcontext(context, _local=local): +- """Set this thread's context to context.""" +- if context in (DefaultContext, BasicContext, ExtendedContext): +- context = context.copy() +- context.clear_flags() +- _local.__decimal_context__ = context +- +- del threading, local # Don't contaminate the namespace +- +- +-##### Decimal class ########################################### +- +-class Decimal(object): +- """Floating point class for decimal arithmetic.""" +- +- __slots__ = ('_exp','_int','_sign', '_is_special') +- # Generally, the value of the Decimal instance is given by +- # (-1)**_sign * _int * 10**_exp +- # Special values are signified by _is_special == True +- +- # We're immutable, so use __new__ not __init__ +- def __new__(cls, value="0", context=None): +- """Create a decimal point instance. +- +- >>> Decimal('3.14') # string input +- Decimal("3.14") +- >>> Decimal((0, (3, 1, 4), -2)) # tuple input (sign, digit_tuple, exponent) +- Decimal("3.14") +- >>> Decimal(314) # int or long +- Decimal("314") +- >>> Decimal(Decimal(314)) # another decimal instance +- Decimal("314") +- """ +- +- self = object.__new__(cls) +- self._is_special = False +- +- # From an internal working value +- if isinstance(value, _WorkRep): +- self._sign = value.sign +- self._int = tuple(map(int, str(value.int))) +- self._exp = int(value.exp) +- return self +- +- # From another decimal +- if isinstance(value, Decimal): +- self._exp = value._exp +- self._sign = value._sign +- self._int = value._int +- self._is_special = value._is_special +- return self +- +- # From an integer +- if isinstance(value, (int,long)): +- if value >= 0: +- self._sign = 0 +- else: +- self._sign = 1 +- self._exp = 0 +- self._int = tuple(map(int, str(abs(value)))) +- return self +- +- # tuple/list conversion (possibly from as_tuple()) +- if isinstance(value, (list,tuple)): +- if len(value) != 3: +- raise ValueError, 'Invalid arguments' +- if value[0] not in (0,1): +- raise ValueError, 'Invalid sign' +- for digit in value[1]: +- if not isinstance(digit, (int,long)) or digit < 0: +- raise ValueError, "The second value in the tuple must be composed of non negative integer elements." +- +- self._sign = value[0] +- self._int = tuple(value[1]) +- if value[2] in ('F','n','N'): +- self._exp = value[2] +- self._is_special = True +- else: +- self._exp = int(value[2]) +- return self +- +- if isinstance(value, float): +- raise TypeError("Cannot convert float to Decimal. " + +- "First convert the float to a string") +- +- # Other argument types may require the context during interpretation +- if context is None: +- context = getcontext() +- +- # From a string +- # REs insist on real strings, so we can too. +- if isinstance(value, basestring): +- if _isinfinity(value): +- self._exp = 'F' +- self._int = (0,) +- self._is_special = True +- if _isinfinity(value) == 1: +- self._sign = 0 +- else: +- self._sign = 1 +- return self +- if _isnan(value): +- sig, sign, diag = _isnan(value) +- self._is_special = True +- if len(diag) > context.prec: #Diagnostic info too long +- self._sign, self._int, self._exp = \ +- context._raise_error(ConversionSyntax) +- return self +- if sig == 1: +- self._exp = 'n' #qNaN +- else: #sig == 2 +- self._exp = 'N' #sNaN +- self._sign = sign +- self._int = tuple(map(int, diag)) #Diagnostic info +- return self +- try: +- self._sign, self._int, self._exp = _string2exact(value) +- except ValueError: +- self._is_special = True +- self._sign, self._int, self._exp = context._raise_error(ConversionSyntax) +- return self +- +- raise TypeError("Cannot convert %r to Decimal" % value) +- +- def _isnan(self): +- """Returns whether the number is not actually one. +- +- 0 if a number +- 1 if NaN +- 2 if sNaN +- """ +- if self._is_special: +- exp = self._exp +- if exp == 'n': +- return 1 +- elif exp == 'N': +- return 2 +- return 0 +- +- def _isinfinity(self): +- """Returns whether the number is infinite +- +- 0 if finite or not a number +- 1 if +INF +- -1 if -INF +- """ +- if self._exp == 'F': +- if self._sign: +- return -1 +- return 1 +- return 0 +- +- def _check_nans(self, other = None, context=None): +- """Returns whether the number is not actually one. +- +- if self, other are sNaN, signal +- if self, other are NaN return nan +- return 0 +- +- Done before operations. +- """ +- +- self_is_nan = self._isnan() +- if other is None: +- other_is_nan = False +- else: +- other_is_nan = other._isnan() +- +- if self_is_nan or other_is_nan: +- if context is None: +- context = getcontext() +- +- if self_is_nan == 2: +- return context._raise_error(InvalidOperation, 'sNaN', +- 1, self) +- if other_is_nan == 2: +- return context._raise_error(InvalidOperation, 'sNaN', +- 1, other) +- if self_is_nan: +- return self +- +- return other +- return 0 +- +- def __nonzero__(self): +- """Is the number non-zero? +- +- 0 if self == 0 +- 1 if self != 0 +- """ +- if self._is_special: +- return 1 +- return sum(self._int) != 0 +- +- def __cmp__(self, other, context=None): +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- if self._is_special or other._is_special: +- ans = self._check_nans(other, context) +- if ans: +- return 1 # Comparison involving NaN's always reports self > other +- +- # INF = INF +- return cmp(self._isinfinity(), other._isinfinity()) +- +- if not self and not other: +- return 0 #If both 0, sign comparison isn't certain. +- +- #If different signs, neg one is less +- if other._sign < self._sign: +- return -1 +- if self._sign < other._sign: +- return 1 +- +- self_adjusted = self.adjusted() +- other_adjusted = other.adjusted() +- if self_adjusted == other_adjusted and \ +- self._int + (0,)*(self._exp - other._exp) == \ +- other._int + (0,)*(other._exp - self._exp): +- return 0 #equal, except in precision. ([0]*(-x) = []) +- elif self_adjusted > other_adjusted and self._int[0] != 0: +- return (-1)**self._sign +- elif self_adjusted < other_adjusted and other._int[0] != 0: +- return -((-1)**self._sign) +- +- # Need to round, so make sure we have a valid context +- if context is None: +- context = getcontext() +- +- context = context._shallow_copy() +- rounding = context._set_rounding(ROUND_UP) #round away from 0 +- +- flags = context._ignore_all_flags() +- res = self.__sub__(other, context=context) +- +- context._regard_flags(*flags) +- +- context.rounding = rounding +- +- if not res: +- return 0 +- elif res._sign: +- return -1 +- return 1 +- +- def __eq__(self, other): +- if not isinstance(other, (Decimal, int, long)): +- return NotImplemented +- return self.__cmp__(other) == 0 +- +- def __ne__(self, other): +- if not isinstance(other, (Decimal, int, long)): +- return NotImplemented +- return self.__cmp__(other) != 0 +- +- def compare(self, other, context=None): +- """Compares one to another. +- +- -1 => a < b +- 0 => a = b +- 1 => a > b +- NaN => one is NaN +- Like __cmp__, but returns Decimal instances. +- """ +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- #compare(NaN, NaN) = NaN +- if (self._is_special or other and other._is_special): +- ans = self._check_nans(other, context) +- if ans: +- return ans +- +- return Decimal(self.__cmp__(other, context)) +- +- def __hash__(self): +- """x.__hash__() <==> hash(x)""" +- # Decimal integers must hash the same as the ints +- # Non-integer decimals are normalized and hashed as strings +- # Normalization assures that hast(100E-1) == hash(10) +- if self._is_special: +- if self._isnan(): +- raise TypeError('Cannot hash a NaN value.') +- return hash(str(self)) +- i = int(self) +- if self == Decimal(i): +- return hash(i) +- assert self.__nonzero__() # '-0' handled by integer case +- return hash(str(self.normalize())) +- +- def as_tuple(self): +- """Represents the number as a triple tuple. +- +- To show the internals exactly as they are. +- """ +- return (self._sign, self._int, self._exp) +- +- def __repr__(self): +- """Represents the number as an instance of Decimal.""" +- # Invariant: eval(repr(d)) == d +- return 'Decimal("%s")' % str(self) +- +- def __str__(self, eng = 0, context=None): +- """Return string representation of the number in scientific notation. +- +- Captures all of the information in the underlying representation. +- """ +- +- if self._is_special: +- if self._isnan(): +- minus = '-'*self._sign +- if self._int == (0,): +- info = '' +- else: +- info = ''.join(map(str, self._int)) +- if self._isnan() == 2: +- return minus + 'sNaN' + info +- return minus + 'NaN' + info +- if self._isinfinity(): +- minus = '-'*self._sign +- return minus + 'Infinity' +- +- if context is None: +- context = getcontext() +- +- tmp = map(str, self._int) +- numdigits = len(self._int) +- leftdigits = self._exp + numdigits +- if eng and not self: #self = 0eX wants 0[.0[0]]eY, not [[0]0]0eY +- if self._exp < 0 and self._exp >= -6: #short, no need for e/E +- s = '-'*self._sign + '0.' + '0'*(abs(self._exp)) +- return s +- #exp is closest mult. of 3 >= self._exp +- exp = ((self._exp - 1)// 3 + 1) * 3 +- if exp != self._exp: +- s = '0.'+'0'*(exp - self._exp) +- else: +- s = '0' +- if exp != 0: +- if context.capitals: +- s += 'E' +- else: +- s += 'e' +- if exp > 0: +- s += '+' #0.0e+3, not 0.0e3 +- s += str(exp) +- s = '-'*self._sign + s +- return s +- if eng: +- dotplace = (leftdigits-1)%3+1 +- adjexp = leftdigits -1 - (leftdigits-1)%3 +- else: +- adjexp = leftdigits-1 +- dotplace = 1 +- if self._exp == 0: +- pass +- elif self._exp < 0 and adjexp >= 0: +- tmp.insert(leftdigits, '.') +- elif self._exp < 0 and adjexp >= -6: +- tmp[0:0] = ['0'] * int(-leftdigits) +- tmp.insert(0, '0.') +- else: +- if numdigits > dotplace: +- tmp.insert(dotplace, '.') +- elif numdigits < dotplace: +- tmp.extend(['0']*(dotplace-numdigits)) +- if adjexp: +- if not context.capitals: +- tmp.append('e') +- else: +- tmp.append('E') +- if adjexp > 0: +- tmp.append('+') +- tmp.append(str(adjexp)) +- if eng: +- while tmp[0:1] == ['0']: +- tmp[0:1] = [] +- if len(tmp) == 0 or tmp[0] == '.' or tmp[0].lower() == 'e': +- tmp[0:0] = ['0'] +- if self._sign: +- tmp.insert(0, '-') +- +- return ''.join(tmp) +- +- def to_eng_string(self, context=None): +- """Convert to engineering-type string. +- +- Engineering notation has an exponent which is a multiple of 3, so there +- are up to 3 digits left of the decimal place. +- +- Same rules for when in exponential and when as a value as in __str__. +- """ +- return self.__str__(eng=1, context=context) +- +- def __neg__(self, context=None): +- """Returns a copy with the sign switched. +- +- Rounds, if it has reason. +- """ +- if self._is_special: +- ans = self._check_nans(context=context) +- if ans: +- return ans +- +- if not self: +- # -Decimal('0') is Decimal('0'), not Decimal('-0') +- sign = 0 +- elif self._sign: +- sign = 0 +- else: +- sign = 1 +- +- if context is None: +- context = getcontext() +- if context._rounding_decision == ALWAYS_ROUND: +- return Decimal((sign, self._int, self._exp))._fix(context) +- return Decimal( (sign, self._int, self._exp)) +- +- def __pos__(self, context=None): +- """Returns a copy, unless it is a sNaN. +- +- Rounds the number (if more then precision digits) +- """ +- if self._is_special: +- ans = self._check_nans(context=context) +- if ans: +- return ans +- +- sign = self._sign +- if not self: +- # + (-0) = 0 +- sign = 0 +- +- if context is None: +- context = getcontext() +- +- if context._rounding_decision == ALWAYS_ROUND: +- ans = self._fix(context) +- else: +- ans = Decimal(self) +- ans._sign = sign +- return ans +- +- def __abs__(self, round=1, context=None): +- """Returns the absolute value of self. +- +- If the second argument is 0, do not round. +- """ +- if self._is_special: +- ans = self._check_nans(context=context) +- if ans: +- return ans +- +- if not round: +- if context is None: +- context = getcontext() +- context = context._shallow_copy() +- context._set_rounding_decision(NEVER_ROUND) +- +- if self._sign: +- ans = self.__neg__(context=context) +- else: +- ans = self.__pos__(context=context) +- +- return ans +- +- def __add__(self, other, context=None): +- """Returns self + other. +- +- -INF + INF (or the reverse) cause InvalidOperation errors. +- """ +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- if context is None: +- context = getcontext() +- +- if self._is_special or other._is_special: +- ans = self._check_nans(other, context) +- if ans: +- return ans +- +- if self._isinfinity(): +- #If both INF, same sign => same as both, opposite => error. +- if self._sign != other._sign and other._isinfinity(): +- return context._raise_error(InvalidOperation, '-INF + INF') +- return Decimal(self) +- if other._isinfinity(): +- return Decimal(other) #Can't both be infinity here +- +- shouldround = context._rounding_decision == ALWAYS_ROUND +- +- exp = min(self._exp, other._exp) +- negativezero = 0 +- if context.rounding == ROUND_FLOOR and self._sign != other._sign: +- #If the answer is 0, the sign should be negative, in this case. +- negativezero = 1 +- +- if not self and not other: +- sign = min(self._sign, other._sign) +- if negativezero: +- sign = 1 +- return Decimal( (sign, (0,), exp)) +- if not self: +- exp = max(exp, other._exp - context.prec-1) +- ans = other._rescale(exp, watchexp=0, context=context) +- if shouldround: +- ans = ans._fix(context) +- return ans +- if not other: +- exp = max(exp, self._exp - context.prec-1) +- ans = self._rescale(exp, watchexp=0, context=context) +- if shouldround: +- ans = ans._fix(context) +- return ans +- +- op1 = _WorkRep(self) +- op2 = _WorkRep(other) +- op1, op2 = _normalize(op1, op2, shouldround, context.prec) +- +- result = _WorkRep() +- if op1.sign != op2.sign: +- # Equal and opposite +- if op1.int == op2.int: +- if exp < context.Etiny(): +- exp = context.Etiny() +- context._raise_error(Clamped) +- return Decimal((negativezero, (0,), exp)) +- if op1.int < op2.int: +- op1, op2 = op2, op1 +- #OK, now abs(op1) > abs(op2) +- if op1.sign == 1: +- result.sign = 1 +- op1.sign, op2.sign = op2.sign, op1.sign +- else: +- result.sign = 0 +- #So we know the sign, and op1 > 0. +- elif op1.sign == 1: +- result.sign = 1 +- op1.sign, op2.sign = (0, 0) +- else: +- result.sign = 0 +- #Now, op1 > abs(op2) > 0 +- +- if op2.sign == 0: +- result.int = op1.int + op2.int +- else: +- result.int = op1.int - op2.int +- +- result.exp = op1.exp +- ans = Decimal(result) +- if shouldround: +- ans = ans._fix(context) +- return ans +- +- __radd__ = __add__ +- +- def __sub__(self, other, context=None): +- """Return self + (-other)""" +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- if self._is_special or other._is_special: +- ans = self._check_nans(other, context=context) +- if ans: +- return ans +- +- # -Decimal(0) = Decimal(0), which we don't want since +- # (-0 - 0 = -0 + (-0) = -0, but -0 + 0 = 0.) +- # so we change the sign directly to a copy +- tmp = Decimal(other) +- tmp._sign = 1-tmp._sign +- +- return self.__add__(tmp, context=context) +- +- def __rsub__(self, other, context=None): +- """Return other + (-self)""" +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- tmp = Decimal(self) +- tmp._sign = 1 - tmp._sign +- return other.__add__(tmp, context=context) +- +- def _increment(self, round=1, context=None): +- """Special case of add, adding 1eExponent +- +- Since it is common, (rounding, for example) this adds +- (sign)*one E self._exp to the number more efficiently than add. +- +- For example: +- Decimal('5.624e10')._increment() == Decimal('5.625e10') +- """ +- if self._is_special: +- ans = self._check_nans(context=context) +- if ans: +- return ans +- +- return Decimal(self) # Must be infinite, and incrementing makes no difference +- +- L = list(self._int) +- L[-1] += 1 +- spot = len(L)-1 +- while L[spot] == 10: +- L[spot] = 0 +- if spot == 0: +- L[0:0] = [1] +- break +- L[spot-1] += 1 +- spot -= 1 +- ans = Decimal((self._sign, L, self._exp)) +- +- if context is None: +- context = getcontext() +- if round and context._rounding_decision == ALWAYS_ROUND: +- ans = ans._fix(context) +- return ans +- +- def __mul__(self, other, context=None): +- """Return self * other. +- +- (+-) INF * 0 (or its reverse) raise InvalidOperation. +- """ +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- if context is None: +- context = getcontext() +- +- resultsign = self._sign ^ other._sign +- +- if self._is_special or other._is_special: +- ans = self._check_nans(other, context) +- if ans: +- return ans +- +- if self._isinfinity(): +- if not other: +- return context._raise_error(InvalidOperation, '(+-)INF * 0') +- return Infsign[resultsign] +- +- if other._isinfinity(): +- if not self: +- return context._raise_error(InvalidOperation, '0 * (+-)INF') +- return Infsign[resultsign] +- +- resultexp = self._exp + other._exp +- shouldround = context._rounding_decision == ALWAYS_ROUND +- +- # Special case for multiplying by zero +- if not self or not other: +- ans = Decimal((resultsign, (0,), resultexp)) +- if shouldround: +- #Fixing in case the exponent is out of bounds +- ans = ans._fix(context) +- return ans +- +- # Special case for multiplying by power of 10 +- if self._int == (1,): +- ans = Decimal((resultsign, other._int, resultexp)) +- if shouldround: +- ans = ans._fix(context) +- return ans +- if other._int == (1,): +- ans = Decimal((resultsign, self._int, resultexp)) +- if shouldround: +- ans = ans._fix(context) +- return ans +- +- op1 = _WorkRep(self) +- op2 = _WorkRep(other) +- +- ans = Decimal( (resultsign, map(int, str(op1.int * op2.int)), resultexp)) +- if shouldround: +- ans = ans._fix(context) +- +- return ans +- __rmul__ = __mul__ +- +- def __div__(self, other, context=None): +- """Return self / other.""" +- return self._divide(other, context=context) +- __truediv__ = __div__ +- +- def _divide(self, other, divmod = 0, context=None): +- """Return a / b, to context.prec precision. +- +- divmod: +- 0 => true division +- 1 => (a //b, a%b) +- 2 => a //b +- 3 => a%b +- +- Actually, if divmod is 2 or 3 a tuple is returned, but errors for +- computing the other value are not raised. +- """ +- other = _convert_other(other) +- if other is NotImplemented: +- if divmod in (0, 1): +- return NotImplemented +- return (NotImplemented, NotImplemented) +- +- if context is None: +- context = getcontext() +- +- sign = self._sign ^ other._sign +- +- if self._is_special or other._is_special: +- ans = self._check_nans(other, context) +- if ans: +- if divmod: +- return (ans, ans) +- return ans +- +- if self._isinfinity() and other._isinfinity(): +- if divmod: +- return (context._raise_error(InvalidOperation, +- '(+-)INF // (+-)INF'), +- context._raise_error(InvalidOperation, +- '(+-)INF % (+-)INF')) +- return context._raise_error(InvalidOperation, '(+-)INF/(+-)INF') +- +- if self._isinfinity(): +- if divmod == 1: +- return (Infsign[sign], +- context._raise_error(InvalidOperation, 'INF % x')) +- elif divmod == 2: +- return (Infsign[sign], NaN) +- elif divmod == 3: +- return (Infsign[sign], +- context._raise_error(InvalidOperation, 'INF % x')) +- return Infsign[sign] +- +- if other._isinfinity(): +- if divmod: +- return (Decimal((sign, (0,), 0)), Decimal(self)) +- context._raise_error(Clamped, 'Division by infinity') +- return Decimal((sign, (0,), context.Etiny())) +- +- # Special cases for zeroes +- if not self and not other: +- if divmod: +- return context._raise_error(DivisionUndefined, '0 / 0', 1) +- return context._raise_error(DivisionUndefined, '0 / 0') +- +- if not self: +- if divmod: +- otherside = Decimal(self) +- otherside._exp = min(self._exp, other._exp) +- return (Decimal((sign, (0,), 0)), otherside) +- exp = self._exp - other._exp +- if exp < context.Etiny(): +- exp = context.Etiny() +- context._raise_error(Clamped, '0e-x / y') +- if exp > context.Emax: +- exp = context.Emax +- context._raise_error(Clamped, '0e+x / y') +- return Decimal( (sign, (0,), exp) ) +- +- if not other: +- if divmod: +- return context._raise_error(DivisionByZero, 'divmod(x,0)', +- sign, 1) +- return context._raise_error(DivisionByZero, 'x / 0', sign) +- +- #OK, so neither = 0, INF or NaN +- +- shouldround = context._rounding_decision == ALWAYS_ROUND +- +- #If we're dividing into ints, and self < other, stop. +- #self.__abs__(0) does not round. +- if divmod and (self.__abs__(0, context) < other.__abs__(0, context)): +- +- if divmod == 1 or divmod == 3: +- exp = min(self._exp, other._exp) +- ans2 = self._rescale(exp, context=context, watchexp=0) +- if shouldround: +- ans2 = ans2._fix(context) +- return (Decimal( (sign, (0,), 0) ), +- ans2) +- +- elif divmod == 2: +- #Don't round the mod part, if we don't need it. +- return (Decimal( (sign, (0,), 0) ), Decimal(self)) +- +- op1 = _WorkRep(self) +- op2 = _WorkRep(other) +- op1, op2, adjust = _adjust_coefficients(op1, op2) +- res = _WorkRep( (sign, 0, (op1.exp - op2.exp)) ) +- if divmod and res.exp > context.prec + 1: +- return context._raise_error(DivisionImpossible) +- +- prec_limit = 10 ** context.prec +- while 1: +- while op2.int <= op1.int: +- res.int += 1 +- op1.int -= op2.int +- if res.exp == 0 and divmod: +- if res.int >= prec_limit and shouldround: +- return context._raise_error(DivisionImpossible) +- otherside = Decimal(op1) +- frozen = context._ignore_all_flags() +- +- exp = min(self._exp, other._exp) +- otherside = otherside._rescale(exp, context=context, watchexp=0) +- context._regard_flags(*frozen) +- if shouldround: +- otherside = otherside._fix(context) +- return (Decimal(res), otherside) +- +- if op1.int == 0 and adjust >= 0 and not divmod: +- break +- if res.int >= prec_limit and shouldround: +- if divmod: +- return context._raise_error(DivisionImpossible) +- shouldround=1 +- # Really, the answer is a bit higher, so adding a one to +- # the end will make sure the rounding is right. +- if op1.int != 0: +- res.int *= 10 +- res.int += 1 +- res.exp -= 1 +- +- break +- res.int *= 10 +- res.exp -= 1 +- adjust += 1 +- op1.int *= 10 +- op1.exp -= 1 +- +- if res.exp == 0 and divmod and op2.int > op1.int: +- #Solves an error in precision. Same as a previous block. +- +- if res.int >= prec_limit and shouldround: +- return context._raise_error(DivisionImpossible) +- otherside = Decimal(op1) +- frozen = context._ignore_all_flags() +- +- exp = min(self._exp, other._exp) +- otherside = otherside._rescale(exp, context=context) +- +- context._regard_flags(*frozen) +- +- return (Decimal(res), otherside) +- +- ans = Decimal(res) +- if shouldround: +- ans = ans._fix(context) +- return ans +- +- def __rdiv__(self, other, context=None): +- """Swaps self/other and returns __div__.""" +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- return other.__div__(self, context=context) +- __rtruediv__ = __rdiv__ +- +- def __divmod__(self, other, context=None): +- """ +- (self // other, self % other) +- """ +- return self._divide(other, 1, context) +- +- def __rdivmod__(self, other, context=None): +- """Swaps self/other and returns __divmod__.""" +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- return other.__divmod__(self, context=context) +- +- def __mod__(self, other, context=None): +- """ +- self % other +- """ +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- if self._is_special or other._is_special: +- ans = self._check_nans(other, context) +- if ans: +- return ans +- +- if self and not other: +- return context._raise_error(InvalidOperation, 'x % 0') +- +- return self._divide(other, 3, context)[1] +- +- def __rmod__(self, other, context=None): +- """Swaps self/other and returns __mod__.""" +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- return other.__mod__(self, context=context) +- +- def remainder_near(self, other, context=None): +- """ +- Remainder nearest to 0- abs(remainder-near) <= other/2 +- """ +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- if self._is_special or other._is_special: +- ans = self._check_nans(other, context) +- if ans: +- return ans +- if self and not other: +- return context._raise_error(InvalidOperation, 'x % 0') +- +- if context is None: +- context = getcontext() +- # If DivisionImpossible causes an error, do not leave Rounded/Inexact +- # ignored in the calling function. +- context = context._shallow_copy() +- flags = context._ignore_flags(Rounded, Inexact) +- #keep DivisionImpossible flags +- (side, r) = self.__divmod__(other, context=context) +- +- if r._isnan(): +- context._regard_flags(*flags) +- return r +- +- context = context._shallow_copy() +- rounding = context._set_rounding_decision(NEVER_ROUND) +- +- if other._sign: +- comparison = other.__div__(Decimal(-2), context=context) +- else: +- comparison = other.__div__(Decimal(2), context=context) +- +- context._set_rounding_decision(rounding) +- context._regard_flags(*flags) +- +- s1, s2 = r._sign, comparison._sign +- r._sign, comparison._sign = 0, 0 +- +- if r < comparison: +- r._sign, comparison._sign = s1, s2 +- #Get flags now +- self.__divmod__(other, context=context) +- return r._fix(context) +- r._sign, comparison._sign = s1, s2 +- +- rounding = context._set_rounding_decision(NEVER_ROUND) +- +- (side, r) = self.__divmod__(other, context=context) +- context._set_rounding_decision(rounding) +- if r._isnan(): +- return r +- +- decrease = not side._iseven() +- rounding = context._set_rounding_decision(NEVER_ROUND) +- side = side.__abs__(context=context) +- context._set_rounding_decision(rounding) +- +- s1, s2 = r._sign, comparison._sign +- r._sign, comparison._sign = 0, 0 +- if r > comparison or decrease and r == comparison: +- r._sign, comparison._sign = s1, s2 +- context.prec += 1 +- if len(side.__add__(Decimal(1), context=context)._int) >= context.prec: +- context.prec -= 1 +- return context._raise_error(DivisionImpossible)[1] +- context.prec -= 1 +- if self._sign == other._sign: +- r = r.__sub__(other, context=context) +- else: +- r = r.__add__(other, context=context) +- else: +- r._sign, comparison._sign = s1, s2 +- +- return r._fix(context) +- +- def __floordiv__(self, other, context=None): +- """self // other""" +- return self._divide(other, 2, context)[0] +- +- def __rfloordiv__(self, other, context=None): +- """Swaps self/other and returns __floordiv__.""" +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- return other.__floordiv__(self, context=context) +- +- def __float__(self): +- """Float representation.""" +- return float(str(self)) +- +- def __int__(self): +- """Converts self to an int, truncating if necessary.""" +- if self._is_special: +- if self._isnan(): +- context = getcontext() +- return context._raise_error(InvalidContext) +- elif self._isinfinity(): +- raise OverflowError, "Cannot convert infinity to long" +- if self._exp >= 0: +- s = ''.join(map(str, self._int)) + '0'*self._exp +- else: +- s = ''.join(map(str, self._int))[:self._exp] +- if s == '': +- s = '0' +- sign = '-'*self._sign +- return int(sign + s) +- +- def __long__(self): +- """Converts to a long. +- +- Equivalent to long(int(self)) +- """ +- return long(self.__int__()) +- +- def _fix(self, context): +- """Round if it is necessary to keep self within prec precision. +- +- Rounds and fixes the exponent. Does not raise on a sNaN. +- +- Arguments: +- self - Decimal instance +- context - context used. +- """ +- if self._is_special: +- return self +- if context is None: +- context = getcontext() +- prec = context.prec +- ans = self._fixexponents(context) +- if len(ans._int) > prec: +- ans = ans._round(prec, context=context) +- ans = ans._fixexponents(context) +- return ans +- +- def _fixexponents(self, context): +- """Fix the exponents and return a copy with the exponent in bounds. +- Only call if known to not be a special value. +- """ +- folddown = context._clamp +- Emin = context.Emin +- ans = self +- ans_adjusted = ans.adjusted() +- if ans_adjusted < Emin: +- Etiny = context.Etiny() +- if ans._exp < Etiny: +- if not ans: +- ans = Decimal(self) +- ans._exp = Etiny +- context._raise_error(Clamped) +- return ans +- ans = ans._rescale(Etiny, context=context) +- #It isn't zero, and exp < Emin => subnormal +- context._raise_error(Subnormal) +- if context.flags[Inexact]: +- context._raise_error(Underflow) +- else: +- if ans: +- #Only raise subnormal if non-zero. +- context._raise_error(Subnormal) +- else: +- Etop = context.Etop() +- if folddown and ans._exp > Etop: +- context._raise_error(Clamped) +- ans = ans._rescale(Etop, context=context) +- else: +- Emax = context.Emax +- if ans_adjusted > Emax: +- if not ans: +- ans = Decimal(self) +- ans._exp = Emax +- context._raise_error(Clamped) +- return ans +- context._raise_error(Inexact) +- context._raise_error(Rounded) +- return context._raise_error(Overflow, 'above Emax', ans._sign) +- return ans +- +- def _round(self, prec=None, rounding=None, context=None): +- """Returns a rounded version of self. +- +- You can specify the precision or rounding method. Otherwise, the +- context determines it. +- """ +- +- if self._is_special: +- ans = self._check_nans(context=context) +- if ans: +- return ans +- +- if self._isinfinity(): +- return Decimal(self) +- +- if context is None: +- context = getcontext() +- +- if rounding is None: +- rounding = context.rounding +- if prec is None: +- prec = context.prec +- +- if not self: +- if prec <= 0: +- dig = (0,) +- exp = len(self._int) - prec + self._exp +- else: +- dig = (0,) * prec +- exp = len(self._int) + self._exp - prec +- ans = Decimal((self._sign, dig, exp)) +- context._raise_error(Rounded) +- return ans +- +- if prec == 0: +- temp = Decimal(self) +- temp._int = (0,)+temp._int +- prec = 1 +- elif prec < 0: +- exp = self._exp + len(self._int) - prec - 1 +- temp = Decimal( (self._sign, (0, 1), exp)) +- prec = 1 +- else: +- temp = Decimal(self) +- +- numdigits = len(temp._int) +- if prec == numdigits: +- return temp +- +- # See if we need to extend precision +- expdiff = prec - numdigits +- if expdiff > 0: +- tmp = list(temp._int) +- tmp.extend([0] * expdiff) +- ans = Decimal( (temp._sign, tmp, temp._exp - expdiff)) +- return ans +- +- #OK, but maybe all the lost digits are 0. +- lostdigits = self._int[expdiff:] +- if lostdigits == (0,) * len(lostdigits): +- ans = Decimal( (temp._sign, temp._int[:prec], temp._exp - expdiff)) +- #Rounded, but not Inexact +- context._raise_error(Rounded) +- return ans +- +- # Okay, let's round and lose data +- +- this_function = getattr(temp, self._pick_rounding_function[rounding]) +- #Now we've got the rounding function +- +- if prec != context.prec: +- context = context._shallow_copy() +- context.prec = prec +- ans = this_function(prec, expdiff, context) +- context._raise_error(Rounded) +- context._raise_error(Inexact, 'Changed in rounding') +- +- return ans +- +- _pick_rounding_function = {} +- +- def _round_down(self, prec, expdiff, context): +- """Also known as round-towards-0, truncate.""" +- return Decimal( (self._sign, self._int[:prec], self._exp - expdiff) ) +- +- def _round_half_up(self, prec, expdiff, context, tmp = None): +- """Rounds 5 up (away from 0)""" +- +- if tmp is None: +- tmp = Decimal( (self._sign,self._int[:prec], self._exp - expdiff)) +- if self._int[prec] >= 5: +- tmp = tmp._increment(round=0, context=context) +- if len(tmp._int) > prec: +- return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1)) +- return tmp +- +- def _round_half_even(self, prec, expdiff, context): +- """Round 5 to even, rest to nearest.""" +- +- tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff)) +- half = (self._int[prec] == 5) +- if half: +- for digit in self._int[prec+1:]: +- if digit != 0: +- half = 0 +- break +- if half: +- if self._int[prec-1] & 1 == 0: +- return tmp +- return self._round_half_up(prec, expdiff, context, tmp) +- +- def _round_half_down(self, prec, expdiff, context): +- """Round 5 down""" +- +- tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff)) +- half = (self._int[prec] == 5) +- if half: +- for digit in self._int[prec+1:]: +- if digit != 0: +- half = 0 +- break +- if half: +- return tmp +- return self._round_half_up(prec, expdiff, context, tmp) +- +- def _round_up(self, prec, expdiff, context): +- """Rounds away from 0.""" +- tmp = Decimal( (self._sign, self._int[:prec], self._exp - expdiff) ) +- for digit in self._int[prec:]: +- if digit != 0: +- tmp = tmp._increment(round=1, context=context) +- if len(tmp._int) > prec: +- return Decimal( (tmp._sign, tmp._int[:-1], tmp._exp + 1)) +- else: +- return tmp +- return tmp +- +- def _round_ceiling(self, prec, expdiff, context): +- """Rounds up (not away from 0 if negative.)""" +- if self._sign: +- return self._round_down(prec, expdiff, context) +- else: +- return self._round_up(prec, expdiff, context) +- +- def _round_floor(self, prec, expdiff, context): +- """Rounds down (not towards 0 if negative)""" +- if not self._sign: +- return self._round_down(prec, expdiff, context) +- else: +- return self._round_up(prec, expdiff, context) +- +- def __pow__(self, n, modulo = None, context=None): +- """Return self ** n (mod modulo) +- +- If modulo is None (default), don't take it mod modulo. +- """ +- n = _convert_other(n) +- if n is NotImplemented: +- return n +- +- if context is None: +- context = getcontext() +- +- if self._is_special or n._is_special or n.adjusted() > 8: +- #Because the spot << doesn't work with really big exponents +- if n._isinfinity() or n.adjusted() > 8: +- return context._raise_error(InvalidOperation, 'x ** INF') +- +- ans = self._check_nans(n, context) +- if ans: +- return ans +- +- if not n._isinteger(): +- return context._raise_error(InvalidOperation, 'x ** (non-integer)') +- +- if not self and not n: +- return context._raise_error(InvalidOperation, '0 ** 0') +- +- if not n: +- return Decimal(1) +- +- if self == Decimal(1): +- return Decimal(1) +- +- sign = self._sign and not n._iseven() +- n = int(n) +- +- if self._isinfinity(): +- if modulo: +- return context._raise_error(InvalidOperation, 'INF % x') +- if n > 0: +- return Infsign[sign] +- return Decimal( (sign, (0,), 0) ) +- +- #with ludicrously large exponent, just raise an overflow and return inf. +- if not modulo and n > 0 and (self._exp + len(self._int) - 1) * n > context.Emax \ +- and self: +- +- tmp = Decimal('inf') +- tmp._sign = sign +- context._raise_error(Rounded) +- context._raise_error(Inexact) +- context._raise_error(Overflow, 'Big power', sign) +- return tmp +- +- elength = len(str(abs(n))) +- firstprec = context.prec +- +- if not modulo and firstprec + elength + 1 > DefaultContext.Emax: +- return context._raise_error(Overflow, 'Too much precision.', sign) +- +- mul = Decimal(self) +- val = Decimal(1) +- context = context._shallow_copy() +- context.prec = firstprec + elength + 1 +- if n < 0: +- #n is a long now, not Decimal instance +- n = -n +- mul = Decimal(1).__div__(mul, context=context) +- +- spot = 1 +- while spot <= n: +- spot <<= 1 +- +- spot >>= 1 +- #Spot is the highest power of 2 less than n +- while spot: +- val = val.__mul__(val, context=context) +- if val._isinfinity(): +- val = Infsign[sign] +- break +- if spot & n: +- val = val.__mul__(mul, context=context) +- if modulo is not None: +- val = val.__mod__(modulo, context=context) +- spot >>= 1 +- context.prec = firstprec +- +- if context._rounding_decision == ALWAYS_ROUND: +- return val._fix(context) +- return val +- +- def __rpow__(self, other, context=None): +- """Swaps self/other and returns __pow__.""" +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- return other.__pow__(self, context=context) +- +- def normalize(self, context=None): +- """Normalize- strip trailing 0s, change anything equal to 0 to 0e0""" +- +- if self._is_special: +- ans = self._check_nans(context=context) +- if ans: +- return ans +- +- dup = self._fix(context) +- if dup._isinfinity(): +- return dup +- +- if not dup: +- return Decimal( (dup._sign, (0,), 0) ) +- end = len(dup._int) +- exp = dup._exp +- while dup._int[end-1] == 0: +- exp += 1 +- end -= 1 +- return Decimal( (dup._sign, dup._int[:end], exp) ) +- +- +- def quantize(self, exp, rounding=None, context=None, watchexp=1): +- """Quantize self so its exponent is the same as that of exp. +- +- Similar to self._rescale(exp._exp) but with error checking. +- """ +- if self._is_special or exp._is_special: +- ans = self._check_nans(exp, context) +- if ans: +- return ans +- +- if exp._isinfinity() or self._isinfinity(): +- if exp._isinfinity() and self._isinfinity(): +- return self #if both are inf, it is OK +- if context is None: +- context = getcontext() +- return context._raise_error(InvalidOperation, +- 'quantize with one INF') +- return self._rescale(exp._exp, rounding, context, watchexp) +- +- def same_quantum(self, other): +- """Test whether self and other have the same exponent. +- +- same as self._exp == other._exp, except NaN == sNaN +- """ +- if self._is_special or other._is_special: +- if self._isnan() or other._isnan(): +- return self._isnan() and other._isnan() and True +- if self._isinfinity() or other._isinfinity(): +- return self._isinfinity() and other._isinfinity() and True +- return self._exp == other._exp +- +- def _rescale(self, exp, rounding=None, context=None, watchexp=1): +- """Rescales so that the exponent is exp. +- +- exp = exp to scale to (an integer) +- rounding = rounding version +- watchexp: if set (default) an error is returned if exp is greater +- than Emax or less than Etiny. +- """ +- if context is None: +- context = getcontext() +- +- if self._is_special: +- if self._isinfinity(): +- return context._raise_error(InvalidOperation, 'rescale with an INF') +- +- ans = self._check_nans(context=context) +- if ans: +- return ans +- +- if watchexp and (context.Emax < exp or context.Etiny() > exp): +- return context._raise_error(InvalidOperation, 'rescale(a, INF)') +- +- if not self: +- ans = Decimal(self) +- ans._int = (0,) +- ans._exp = exp +- return ans +- +- diff = self._exp - exp +- digits = len(self._int) + diff +- +- if watchexp and digits > context.prec: +- return context._raise_error(InvalidOperation, 'Rescale > prec') +- +- tmp = Decimal(self) +- tmp._int = (0,) + tmp._int +- digits += 1 +- +- if digits < 0: +- tmp._exp = -digits + tmp._exp +- tmp._int = (0,1) +- digits = 1 +- tmp = tmp._round(digits, rounding, context=context) +- +- if tmp._int[0] == 0 and len(tmp._int) > 1: +- tmp._int = tmp._int[1:] +- tmp._exp = exp +- +- tmp_adjusted = tmp.adjusted() +- if tmp and tmp_adjusted < context.Emin: +- context._raise_error(Subnormal) +- elif tmp and tmp_adjusted > context.Emax: +- return context._raise_error(InvalidOperation, 'rescale(a, INF)') +- return tmp +- +- def to_integral(self, rounding=None, context=None): +- """Rounds to the nearest integer, without raising inexact, rounded.""" +- if self._is_special: +- ans = self._check_nans(context=context) +- if ans: +- return ans +- if self._exp >= 0: +- return self +- if context is None: +- context = getcontext() +- flags = context._ignore_flags(Rounded, Inexact) +- ans = self._rescale(0, rounding, context=context) +- context._regard_flags(flags) +- return ans +- +- def sqrt(self, context=None): +- """Return the square root of self. +- +- Uses a converging algorithm (Xn+1 = 0.5*(Xn + self / Xn)) +- Should quadratically approach the right answer. +- """ +- if self._is_special: +- ans = self._check_nans(context=context) +- if ans: +- return ans +- +- if self._isinfinity() and self._sign == 0: +- return Decimal(self) +- +- if not self: +- #exponent = self._exp / 2, using round_down. +- #if self._exp < 0: +- # exp = (self._exp+1) // 2 +- #else: +- exp = (self._exp) // 2 +- if self._sign == 1: +- #sqrt(-0) = -0 +- return Decimal( (1, (0,), exp)) +- else: +- return Decimal( (0, (0,), exp)) +- +- if context is None: +- context = getcontext() +- +- if self._sign == 1: +- return context._raise_error(InvalidOperation, 'sqrt(-x), x > 0') +- +- tmp = Decimal(self) +- +- expadd = tmp._exp // 2 +- if tmp._exp & 1: +- tmp._int += (0,) +- tmp._exp = 0 +- else: +- tmp._exp = 0 +- +- context = context._shallow_copy() +- flags = context._ignore_all_flags() +- firstprec = context.prec +- context.prec = 3 +- if tmp.adjusted() & 1 == 0: +- ans = Decimal( (0, (8,1,9), tmp.adjusted() - 2) ) +- ans = ans.__add__(tmp.__mul__(Decimal((0, (2,5,9), -2)), +- context=context), context=context) +- ans._exp -= 1 + tmp.adjusted() // 2 +- else: +- ans = Decimal( (0, (2,5,9), tmp._exp + len(tmp._int)- 3) ) +- ans = ans.__add__(tmp.__mul__(Decimal((0, (8,1,9), -3)), +- context=context), context=context) +- ans._exp -= 1 + tmp.adjusted() // 2 +- +- #ans is now a linear approximation. +- +- Emax, Emin = context.Emax, context.Emin +- context.Emax, context.Emin = DefaultContext.Emax, DefaultContext.Emin +- +- half = Decimal('0.5') +- +- maxp = firstprec + 2 +- rounding = context._set_rounding(ROUND_HALF_EVEN) +- while 1: +- context.prec = min(2*context.prec - 2, maxp) +- ans = half.__mul__(ans.__add__(tmp.__div__(ans, context=context), +- context=context), context=context) +- if context.prec == maxp: +- break +- +- #round to the answer's precision-- the only error can be 1 ulp. +- context.prec = firstprec +- prevexp = ans.adjusted() +- ans = ans._round(context=context) +- +- #Now, check if the other last digits are better. +- context.prec = firstprec + 1 +- # In case we rounded up another digit and we should actually go lower. +- if prevexp != ans.adjusted(): +- ans._int += (0,) +- ans._exp -= 1 +- +- +- lower = ans.__sub__(Decimal((0, (5,), ans._exp-1)), context=context) +- context._set_rounding(ROUND_UP) +- if lower.__mul__(lower, context=context) > (tmp): +- ans = ans.__sub__(Decimal((0, (1,), ans._exp)), context=context) +- +- else: +- upper = ans.__add__(Decimal((0, (5,), ans._exp-1)),context=context) +- context._set_rounding(ROUND_DOWN) +- if upper.__mul__(upper, context=context) < tmp: +- ans = ans.__add__(Decimal((0, (1,), ans._exp)),context=context) +- +- ans._exp += expadd +- +- context.prec = firstprec +- context.rounding = rounding +- ans = ans._fix(context) +- +- rounding = context._set_rounding_decision(NEVER_ROUND) +- if not ans.__mul__(ans, context=context) == self: +- # Only rounded/inexact if here. +- context._regard_flags(flags) +- context._raise_error(Rounded) +- context._raise_error(Inexact) +- else: +- #Exact answer, so let's set the exponent right. +- #if self._exp < 0: +- # exp = (self._exp +1)// 2 +- #else: +- exp = self._exp // 2 +- context.prec += ans._exp - exp +- ans = ans._rescale(exp, context=context) +- context.prec = firstprec +- context._regard_flags(flags) +- context.Emax, context.Emin = Emax, Emin +- +- return ans._fix(context) +- +- def max(self, other, context=None): +- """Returns the larger value. +- +- like max(self, other) except if one is not a number, returns +- NaN (and signals if one is sNaN). Also rounds. +- """ +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- if self._is_special or other._is_special: +- # if one operand is a quiet NaN and the other is number, then the +- # number is always returned +- sn = self._isnan() +- on = other._isnan() +- if sn or on: +- if on == 1 and sn != 2: +- return self +- if sn == 1 and on != 2: +- return other +- return self._check_nans(other, context) +- +- ans = self +- c = self.__cmp__(other) +- if c == 0: +- # if both operands are finite and equal in numerical value +- # then an ordering is applied: +- # +- # if the signs differ then max returns the operand with the +- # positive sign and min returns the operand with the negative sign +- # +- # if the signs are the same then the exponent is used to select +- # the result. +- if self._sign != other._sign: +- if self._sign: +- ans = other +- elif self._exp < other._exp and not self._sign: +- ans = other +- elif self._exp > other._exp and self._sign: +- ans = other +- elif c == -1: +- ans = other +- +- if context is None: +- context = getcontext() +- if context._rounding_decision == ALWAYS_ROUND: +- return ans._fix(context) +- return ans +- +- def min(self, other, context=None): +- """Returns the smaller value. +- +- like min(self, other) except if one is not a number, returns +- NaN (and signals if one is sNaN). Also rounds. +- """ +- other = _convert_other(other) +- if other is NotImplemented: +- return other +- +- if self._is_special or other._is_special: +- # if one operand is a quiet NaN and the other is number, then the +- # number is always returned +- sn = self._isnan() +- on = other._isnan() +- if sn or on: +- if on == 1 and sn != 2: +- return self +- if sn == 1 and on != 2: +- return other +- return self._check_nans(other, context) +- +- ans = self +- c = self.__cmp__(other) +- if c == 0: +- # if both operands are finite and equal in numerical value +- # then an ordering is applied: +- # +- # if the signs differ then max returns the operand with the +- # positive sign and min returns the operand with the negative sign +- # +- # if the signs are the same then the exponent is used to select +- # the result. +- if self._sign != other._sign: +- if other._sign: +- ans = other +- elif self._exp > other._exp and not self._sign: +- ans = other +- elif self._exp < other._exp and self._sign: +- ans = other +- elif c == 1: +- ans = other +- +- if context is None: +- context = getcontext() +- if context._rounding_decision == ALWAYS_ROUND: +- return ans._fix(context) +- return ans +- +- def _isinteger(self): +- """Returns whether self is an integer""" +- if self._exp >= 0: +- return True +- rest = self._int[self._exp:] +- return rest == (0,)*len(rest) +- +- def _iseven(self): +- """Returns 1 if self is even. Assumes self is an integer.""" +- if self._exp > 0: +- return 1 +- return self._int[-1+self._exp] & 1 == 0 +- +- def adjusted(self): +- """Return the adjusted exponent of self""" +- try: +- return self._exp + len(self._int) - 1 +- #If NaN or Infinity, self._exp is string +- except TypeError: +- return 0 +- +- # support for pickling, copy, and deepcopy +- def __reduce__(self): +- return (self.__class__, (str(self),)) +- +- def __copy__(self): +- if type(self) == Decimal: +- return self # I'm immutable; therefore I am my own clone +- return self.__class__(str(self)) +- +- def __deepcopy__(self, memo): +- if type(self) == Decimal: +- return self # My components are also immutable +- return self.__class__(str(self)) +- +-##### Context class ########################################### +- +- +-# get rounding method function: +-rounding_functions = [name for name in Decimal.__dict__.keys() if name.startswith('_round_')] +-for name in rounding_functions: +- #name is like _round_half_even, goes to the global ROUND_HALF_EVEN value. +- globalname = name[1:].upper() +- val = globals()[globalname] +- Decimal._pick_rounding_function[val] = name +- +-del name, val, globalname, rounding_functions +- +-class Context(object): +- """Contains the context for a Decimal instance. +- +- Contains: +- prec - precision (for use in rounding, division, square roots..) +- rounding - rounding type. (how you round) +- _rounding_decision - ALWAYS_ROUND, NEVER_ROUND -- do you round? +- traps - If traps[exception] = 1, then the exception is +- raised when it is caused. Otherwise, a value is +- substituted in. +- flags - When an exception is caused, flags[exception] is incremented. +- (Whether or not the trap_enabler is set) +- Should be reset by user of Decimal instance. +- Emin - Minimum exponent +- Emax - Maximum exponent +- capitals - If 1, 1*10^1 is printed as 1E+1. +- If 0, printed as 1e1 +- _clamp - If 1, change exponents if too high (Default 0) +- """ +- +- def __init__(self, prec=None, rounding=None, +- traps=None, flags=None, +- _rounding_decision=None, +- Emin=None, Emax=None, +- capitals=None, _clamp=0, +- _ignored_flags=None): +- if flags is None: +- flags = [] +- if _ignored_flags is None: +- _ignored_flags = [] +- if not isinstance(flags, dict): +- flags = dict([(s,s in flags) for s in _signals]) +- del s +- if traps is not None and not isinstance(traps, dict): +- traps = dict([(s,s in traps) for s in _signals]) +- del s +- for name, val in locals().items(): +- if val is None: +- setattr(self, name, _copy.copy(getattr(DefaultContext, name))) +- else: +- setattr(self, name, val) +- del self.self +- +- def __repr__(self): +- """Show the current context.""" +- s = [] +- s.append('Context(prec=%(prec)d, rounding=%(rounding)s, Emin=%(Emin)d, Emax=%(Emax)d, capitals=%(capitals)d' % vars(self)) +- s.append('flags=[' + ', '.join([f.__name__ for f, v in self.flags.items() if v]) + ']') +- s.append('traps=[' + ', '.join([t.__name__ for t, v in self.traps.items() if v]) + ']') +- return ', '.join(s) + ')' +- +- def clear_flags(self): +- """Reset all flags to zero""" +- for flag in self.flags: +- self.flags[flag] = 0 +- +- def _shallow_copy(self): +- """Returns a shallow copy from self.""" +- nc = Context(self.prec, self.rounding, self.traps, self.flags, +- self._rounding_decision, self.Emin, self.Emax, +- self.capitals, self._clamp, self._ignored_flags) +- return nc +- +- def copy(self): +- """Returns a deep copy from self.""" +- nc = Context(self.prec, self.rounding, self.traps.copy(), self.flags.copy(), +- self._rounding_decision, self.Emin, self.Emax, +- self.capitals, self._clamp, self._ignored_flags) +- return nc +- __copy__ = copy +- +- def _raise_error(self, condition, explanation = None, *args): +- """Handles an error +- +- If the flag is in _ignored_flags, returns the default response. +- Otherwise, it increments the flag, then, if the corresponding +- trap_enabler is set, it reaises the exception. Otherwise, it returns +- the default value after incrementing the flag. +- """ +- error = _condition_map.get(condition, condition) +- if error in self._ignored_flags: +- #Don't touch the flag +- return error().handle(self, *args) +- +- self.flags[error] += 1 +- if not self.traps[error]: +- #The errors define how to handle themselves. +- return condition().handle(self, *args) +- +- # Errors should only be risked on copies of the context +- #self._ignored_flags = [] +- raise error, explanation +- +- def _ignore_all_flags(self): +- """Ignore all flags, if they are raised""" +- return self._ignore_flags(*_signals) +- +- def _ignore_flags(self, *flags): +- """Ignore the flags, if they are raised""" +- # Do not mutate-- This way, copies of a context leave the original +- # alone. +- self._ignored_flags = (self._ignored_flags + list(flags)) +- return list(flags) +- +- def _regard_flags(self, *flags): +- """Stop ignoring the flags, if they are raised""" +- if flags and isinstance(flags[0], (tuple,list)): +- flags = flags[0] +- for flag in flags: +- self._ignored_flags.remove(flag) +- +- def __hash__(self): +- """A Context cannot be hashed.""" +- # We inherit object.__hash__, so we must deny this explicitly +- raise TypeError, "Cannot hash a Context." +- +- def Etiny(self): +- """Returns Etiny (= Emin - prec + 1)""" +- return int(self.Emin - self.prec + 1) +- +- def Etop(self): +- """Returns maximum exponent (= Emax - prec + 1)""" +- return int(self.Emax - self.prec + 1) +- +- def _set_rounding_decision(self, type): +- """Sets the rounding decision. +- +- Sets the rounding decision, and returns the current (previous) +- rounding decision. Often used like: +- +- context = context._shallow_copy() +- # That so you don't change the calling context +- # if an error occurs in the middle (say DivisionImpossible is raised). +- +- rounding = context._set_rounding_decision(NEVER_ROUND) +- instance = instance / Decimal(2) +- context._set_rounding_decision(rounding) +- +- This will make it not round for that operation. +- """ +- +- rounding = self._rounding_decision +- self._rounding_decision = type +- return rounding +- +- def _set_rounding(self, type): +- """Sets the rounding type. +- +- Sets the rounding type, and returns the current (previous) +- rounding type. Often used like: +- +- context = context.copy() +- # so you don't change the calling context +- # if an error occurs in the middle. +- rounding = context._set_rounding(ROUND_UP) +- val = self.__sub__(other, context=context) +- context._set_rounding(rounding) +- +- This will make it round up for that operation. +- """ +- rounding = self.rounding +- self.rounding= type +- return rounding +- +- def create_decimal(self, num='0'): +- """Creates a new Decimal instance but using self as context.""" +- d = Decimal(num, context=self) +- return d._fix(self) +- +- #Methods +- def abs(self, a): +- """Returns the absolute value of the operand. +- +- If the operand is negative, the result is the same as using the minus +- operation on the operand. Otherwise, the result is the same as using +- the plus operation on the operand. +- +- >>> ExtendedContext.abs(Decimal('2.1')) +- Decimal("2.1") +- >>> ExtendedContext.abs(Decimal('-100')) +- Decimal("100") +- >>> ExtendedContext.abs(Decimal('101.5')) +- Decimal("101.5") +- >>> ExtendedContext.abs(Decimal('-101.5')) +- Decimal("101.5") +- """ +- return a.__abs__(context=self) +- +- def add(self, a, b): +- """Return the sum of the two operands. +- +- >>> ExtendedContext.add(Decimal('12'), Decimal('7.00')) +- Decimal("19.00") +- >>> ExtendedContext.add(Decimal('1E+2'), Decimal('1.01E+4')) +- Decimal("1.02E+4") +- """ +- return a.__add__(b, context=self) +- +- def _apply(self, a): +- return str(a._fix(self)) +- +- def compare(self, a, b): +- """Compares values numerically. +- +- If the signs of the operands differ, a value representing each operand +- ('-1' if the operand is less than zero, '0' if the operand is zero or +- negative zero, or '1' if the operand is greater than zero) is used in +- place of that operand for the comparison instead of the actual +- operand. +- +- The comparison is then effected by subtracting the second operand from +- the first and then returning a value according to the result of the +- subtraction: '-1' if the result is less than zero, '0' if the result is +- zero or negative zero, or '1' if the result is greater than zero. +- +- >>> ExtendedContext.compare(Decimal('2.1'), Decimal('3')) +- Decimal("-1") +- >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.1')) +- Decimal("0") +- >>> ExtendedContext.compare(Decimal('2.1'), Decimal('2.10')) +- Decimal("0") +- >>> ExtendedContext.compare(Decimal('3'), Decimal('2.1')) +- Decimal("1") +- >>> ExtendedContext.compare(Decimal('2.1'), Decimal('-3')) +- Decimal("1") +- >>> ExtendedContext.compare(Decimal('-3'), Decimal('2.1')) +- Decimal("-1") +- """ +- return a.compare(b, context=self) +- +- def divide(self, a, b): +- """Decimal division in a specified context. +- +- >>> ExtendedContext.divide(Decimal('1'), Decimal('3')) +- Decimal("0.333333333") +- >>> ExtendedContext.divide(Decimal('2'), Decimal('3')) +- Decimal("0.666666667") +- >>> ExtendedContext.divide(Decimal('5'), Decimal('2')) +- Decimal("2.5") +- >>> ExtendedContext.divide(Decimal('1'), Decimal('10')) +- Decimal("0.1") +- >>> ExtendedContext.divide(Decimal('12'), Decimal('12')) +- Decimal("1") +- >>> ExtendedContext.divide(Decimal('8.00'), Decimal('2')) +- Decimal("4.00") +- >>> ExtendedContext.divide(Decimal('2.400'), Decimal('2.0')) +- Decimal("1.20") +- >>> ExtendedContext.divide(Decimal('1000'), Decimal('100')) +- Decimal("10") +- >>> ExtendedContext.divide(Decimal('1000'), Decimal('1')) +- Decimal("1000") +- >>> ExtendedContext.divide(Decimal('2.40E+6'), Decimal('2')) +- Decimal("1.20E+6") +- """ +- return a.__div__(b, context=self) +- +- def divide_int(self, a, b): +- """Divides two numbers and returns the integer part of the result. +- +- >>> ExtendedContext.divide_int(Decimal('2'), Decimal('3')) +- Decimal("0") +- >>> ExtendedContext.divide_int(Decimal('10'), Decimal('3')) +- Decimal("3") +- >>> ExtendedContext.divide_int(Decimal('1'), Decimal('0.3')) +- Decimal("3") +- """ +- return a.__floordiv__(b, context=self) +- +- def divmod(self, a, b): +- return a.__divmod__(b, context=self) +- +- def max(self, a,b): +- """max compares two values numerically and returns the maximum. +- +- If either operand is a NaN then the general rules apply. +- Otherwise, the operands are compared as as though by the compare +- operation. If they are numerically equal then the left-hand operand +- is chosen as the result. Otherwise the maximum (closer to positive +- infinity) of the two operands is chosen as the result. +- +- >>> ExtendedContext.max(Decimal('3'), Decimal('2')) +- Decimal("3") +- >>> ExtendedContext.max(Decimal('-10'), Decimal('3')) +- Decimal("3") +- >>> ExtendedContext.max(Decimal('1.0'), Decimal('1')) +- Decimal("1") +- >>> ExtendedContext.max(Decimal('7'), Decimal('NaN')) +- Decimal("7") +- """ +- return a.max(b, context=self) +- +- def min(self, a,b): +- """min compares two values numerically and returns the minimum. +- +- If either operand is a NaN then the general rules apply. +- Otherwise, the operands are compared as as though by the compare +- operation. If they are numerically equal then the left-hand operand +- is chosen as the result. Otherwise the minimum (closer to negative +- infinity) of the two operands is chosen as the result. +- +- >>> ExtendedContext.min(Decimal('3'), Decimal('2')) +- Decimal("2") +- >>> ExtendedContext.min(Decimal('-10'), Decimal('3')) +- Decimal("-10") +- >>> ExtendedContext.min(Decimal('1.0'), Decimal('1')) +- Decimal("1.0") +- >>> ExtendedContext.min(Decimal('7'), Decimal('NaN')) +- Decimal("7") +- """ +- return a.min(b, context=self) +- +- def minus(self, a): +- """Minus corresponds to unary prefix minus in Python. +- +- The operation is evaluated using the same rules as subtract; the +- operation minus(a) is calculated as subtract('0', a) where the '0' +- has the same exponent as the operand. +- +- >>> ExtendedContext.minus(Decimal('1.3')) +- Decimal("-1.3") +- >>> ExtendedContext.minus(Decimal('-1.3')) +- Decimal("1.3") +- """ +- return a.__neg__(context=self) +- +- def multiply(self, a, b): +- """multiply multiplies two operands. +- +- If either operand is a special value then the general rules apply. +- Otherwise, the operands are multiplied together ('long multiplication'), +- resulting in a number which may be as long as the sum of the lengths +- of the two operands. +- +- >>> ExtendedContext.multiply(Decimal('1.20'), Decimal('3')) +- Decimal("3.60") +- >>> ExtendedContext.multiply(Decimal('7'), Decimal('3')) +- Decimal("21") +- >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('0.8')) +- Decimal("0.72") +- >>> ExtendedContext.multiply(Decimal('0.9'), Decimal('-0')) +- Decimal("-0.0") +- >>> ExtendedContext.multiply(Decimal('654321'), Decimal('654321')) +- Decimal("4.28135971E+11") +- """ +- return a.__mul__(b, context=self) +- +- def normalize(self, a): +- """normalize reduces an operand to its simplest form. +- +- Essentially a plus operation with all trailing zeros removed from the +- result. +- +- >>> ExtendedContext.normalize(Decimal('2.1')) +- Decimal("2.1") +- >>> ExtendedContext.normalize(Decimal('-2.0')) +- Decimal("-2") +- >>> ExtendedContext.normalize(Decimal('1.200')) +- Decimal("1.2") +- >>> ExtendedContext.normalize(Decimal('-120')) +- Decimal("-1.2E+2") +- >>> ExtendedContext.normalize(Decimal('120.00')) +- Decimal("1.2E+2") +- >>> ExtendedContext.normalize(Decimal('0.00')) +- Decimal("0") +- """ +- return a.normalize(context=self) +- +- def plus(self, a): +- """Plus corresponds to unary prefix plus in Python. +- +- The operation is evaluated using the same rules as add; the +- operation plus(a) is calculated as add('0', a) where the '0' +- has the same exponent as the operand. +- +- >>> ExtendedContext.plus(Decimal('1.3')) +- Decimal("1.3") +- >>> ExtendedContext.plus(Decimal('-1.3')) +- Decimal("-1.3") +- """ +- return a.__pos__(context=self) +- +- def power(self, a, b, modulo=None): +- """Raises a to the power of b, to modulo if given. +- +- The right-hand operand must be a whole number whose integer part (after +- any exponent has been applied) has no more than 9 digits and whose +- fractional part (if any) is all zeros before any rounding. The operand +- may be positive, negative, or zero; if negative, the absolute value of +- the power is used, and the left-hand operand is inverted (divided into +- 1) before use. +- +- If the increased precision needed for the intermediate calculations +- exceeds the capabilities of the implementation then an Invalid operation +- condition is raised. +- +- If, when raising to a negative power, an underflow occurs during the +- division into 1, the operation is not halted at that point but +- continues. +- +- >>> ExtendedContext.power(Decimal('2'), Decimal('3')) +- Decimal("8") +- >>> ExtendedContext.power(Decimal('2'), Decimal('-3')) +- Decimal("0.125") +- >>> ExtendedContext.power(Decimal('1.7'), Decimal('8')) +- Decimal("69.7575744") +- >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-2')) +- Decimal("0") +- >>> ExtendedContext.power(Decimal('Infinity'), Decimal('-1')) +- Decimal("0") +- >>> ExtendedContext.power(Decimal('Infinity'), Decimal('0')) +- Decimal("1") +- >>> ExtendedContext.power(Decimal('Infinity'), Decimal('1')) +- Decimal("Infinity") +- >>> ExtendedContext.power(Decimal('Infinity'), Decimal('2')) +- Decimal("Infinity") +- >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-2')) +- Decimal("0") +- >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('-1')) +- Decimal("-0") +- >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('0')) +- Decimal("1") +- >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('1')) +- Decimal("-Infinity") +- >>> ExtendedContext.power(Decimal('-Infinity'), Decimal('2')) +- Decimal("Infinity") +- >>> ExtendedContext.power(Decimal('0'), Decimal('0')) +- Decimal("NaN") +- """ +- return a.__pow__(b, modulo, context=self) +- +- def quantize(self, a, b): +- """Returns a value equal to 'a' (rounded) and having the exponent of 'b'. +- +- The coefficient of the result is derived from that of the left-hand +- operand. It may be rounded using the current rounding setting (if the +- exponent is being increased), multiplied by a positive power of ten (if +- the exponent is being decreased), or is unchanged (if the exponent is +- already equal to that of the right-hand operand). +- +- Unlike other operations, if the length of the coefficient after the +- quantize operation would be greater than precision then an Invalid +- operation condition is raised. This guarantees that, unless there is an +- error condition, the exponent of the result of a quantize is always +- equal to that of the right-hand operand. +- +- Also unlike other operations, quantize will never raise Underflow, even +- if the result is subnormal and inexact. +- +- >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.001')) +- Decimal("2.170") +- >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.01')) +- Decimal("2.17") +- >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('0.1')) +- Decimal("2.2") +- >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+0')) +- Decimal("2") +- >>> ExtendedContext.quantize(Decimal('2.17'), Decimal('1e+1')) +- Decimal("0E+1") +- >>> ExtendedContext.quantize(Decimal('-Inf'), Decimal('Infinity')) +- Decimal("-Infinity") +- >>> ExtendedContext.quantize(Decimal('2'), Decimal('Infinity')) +- Decimal("NaN") +- >>> ExtendedContext.quantize(Decimal('-0.1'), Decimal('1')) +- Decimal("-0") +- >>> ExtendedContext.quantize(Decimal('-0'), Decimal('1e+5')) +- Decimal("-0E+5") +- >>> ExtendedContext.quantize(Decimal('+35236450.6'), Decimal('1e-2')) +- Decimal("NaN") +- >>> ExtendedContext.quantize(Decimal('-35236450.6'), Decimal('1e-2')) +- Decimal("NaN") +- >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-1')) +- Decimal("217.0") +- >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e-0')) +- Decimal("217") +- >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+1')) +- Decimal("2.2E+2") +- >>> ExtendedContext.quantize(Decimal('217'), Decimal('1e+2')) +- Decimal("2E+2") +- """ +- return a.quantize(b, context=self) +- +- def remainder(self, a, b): +- """Returns the remainder from integer division. +- +- The result is the residue of the dividend after the operation of +- calculating integer division as described for divide-integer, rounded to +- precision digits if necessary. The sign of the result, if non-zero, is +- the same as that of the original dividend. +- +- This operation will fail under the same conditions as integer division +- (that is, if integer division on the same two operands would fail, the +- remainder cannot be calculated). +- +- >>> ExtendedContext.remainder(Decimal('2.1'), Decimal('3')) +- Decimal("2.1") +- >>> ExtendedContext.remainder(Decimal('10'), Decimal('3')) +- Decimal("1") +- >>> ExtendedContext.remainder(Decimal('-10'), Decimal('3')) +- Decimal("-1") +- >>> ExtendedContext.remainder(Decimal('10.2'), Decimal('1')) +- Decimal("0.2") +- >>> ExtendedContext.remainder(Decimal('10'), Decimal('0.3')) +- Decimal("0.1") +- >>> ExtendedContext.remainder(Decimal('3.6'), Decimal('1.3')) +- Decimal("1.0") +- """ +- return a.__mod__(b, context=self) +- +- def remainder_near(self, a, b): +- """Returns to be "a - b * n", where n is the integer nearest the exact +- value of "x / b" (if two integers are equally near then the even one +- is chosen). If the result is equal to 0 then its sign will be the +- sign of a. +- +- This operation will fail under the same conditions as integer division +- (that is, if integer division on the same two operands would fail, the +- remainder cannot be calculated). +- +- >>> ExtendedContext.remainder_near(Decimal('2.1'), Decimal('3')) +- Decimal("-0.9") +- >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('6')) +- Decimal("-2") +- >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('3')) +- Decimal("1") +- >>> ExtendedContext.remainder_near(Decimal('-10'), Decimal('3')) +- Decimal("-1") +- >>> ExtendedContext.remainder_near(Decimal('10.2'), Decimal('1')) +- Decimal("0.2") +- >>> ExtendedContext.remainder_near(Decimal('10'), Decimal('0.3')) +- Decimal("0.1") +- >>> ExtendedContext.remainder_near(Decimal('3.6'), Decimal('1.3')) +- Decimal("-0.3") +- """ +- return a.remainder_near(b, context=self) +- +- def same_quantum(self, a, b): +- """Returns True if the two operands have the same exponent. +- +- The result is never affected by either the sign or the coefficient of +- either operand. +- +- >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.001')) +- False +- >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('0.01')) +- True +- >>> ExtendedContext.same_quantum(Decimal('2.17'), Decimal('1')) +- False +- >>> ExtendedContext.same_quantum(Decimal('Inf'), Decimal('-Inf')) +- True +- """ +- return a.same_quantum(b) +- +- def sqrt(self, a): +- """Returns the square root of a non-negative number to context precision. +- +- If the result must be inexact, it is rounded using the round-half-even +- algorithm. +- +- >>> ExtendedContext.sqrt(Decimal('0')) +- Decimal("0") +- >>> ExtendedContext.sqrt(Decimal('-0')) +- Decimal("-0") +- >>> ExtendedContext.sqrt(Decimal('0.39')) +- Decimal("0.624499800") +- >>> ExtendedContext.sqrt(Decimal('100')) +- Decimal("10") +- >>> ExtendedContext.sqrt(Decimal('1')) +- Decimal("1") +- >>> ExtendedContext.sqrt(Decimal('1.0')) +- Decimal("1.0") +- >>> ExtendedContext.sqrt(Decimal('1.00')) +- Decimal("1.0") +- >>> ExtendedContext.sqrt(Decimal('7')) +- Decimal("2.64575131") +- >>> ExtendedContext.sqrt(Decimal('10')) +- Decimal("3.16227766") +- >>> ExtendedContext.prec +- 9 +- """ +- return a.sqrt(context=self) +- +- def subtract(self, a, b): +- """Return the difference between the two operands. +- +- >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.07')) +- Decimal("0.23") +- >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('1.30')) +- Decimal("0.00") +- >>> ExtendedContext.subtract(Decimal('1.3'), Decimal('2.07')) +- Decimal("-0.77") +- """ +- return a.__sub__(b, context=self) +- +- def to_eng_string(self, a): +- """Converts a number to a string, using scientific notation. +- +- The operation is not affected by the context. +- """ +- return a.to_eng_string(context=self) +- +- def to_sci_string(self, a): +- """Converts a number to a string, using scientific notation. +- +- The operation is not affected by the context. +- """ +- return a.__str__(context=self) +- +- def to_integral(self, a): +- """Rounds to an integer. +- +- When the operand has a negative exponent, the result is the same +- as using the quantize() operation using the given operand as the +- left-hand-operand, 1E+0 as the right-hand-operand, and the precision +- of the operand as the precision setting, except that no flags will +- be set. The rounding mode is taken from the context. +- +- >>> ExtendedContext.to_integral(Decimal('2.1')) +- Decimal("2") +- >>> ExtendedContext.to_integral(Decimal('100')) +- Decimal("100") +- >>> ExtendedContext.to_integral(Decimal('100.0')) +- Decimal("100") +- >>> ExtendedContext.to_integral(Decimal('101.5')) +- Decimal("102") +- >>> ExtendedContext.to_integral(Decimal('-101.5')) +- Decimal("-102") +- >>> ExtendedContext.to_integral(Decimal('10E+5')) +- Decimal("1.0E+6") +- >>> ExtendedContext.to_integral(Decimal('7.89E+77')) +- Decimal("7.89E+77") +- >>> ExtendedContext.to_integral(Decimal('-Inf')) +- Decimal("-Infinity") +- """ +- return a.to_integral(context=self) +- +-class _WorkRep(object): +- __slots__ = ('sign','int','exp') +- # sign: 0 or 1 +- # int: int or long +- # exp: None, int, or string +- +- def __init__(self, value=None): +- if value is None: +- self.sign = None +- self.int = 0 +- self.exp = None +- elif isinstance(value, Decimal): +- self.sign = value._sign +- cum = 0 +- for digit in value._int: +- cum = cum * 10 + digit +- self.int = cum +- self.exp = value._exp +- else: +- # assert isinstance(value, tuple) +- self.sign = value[0] +- self.int = value[1] +- self.exp = value[2] +- +- def __repr__(self): +- return "(%r, %r, %r)" % (self.sign, self.int, self.exp) +- +- __str__ = __repr__ +- +- +- +-def _normalize(op1, op2, shouldround = 0, prec = 0): +- """Normalizes op1, op2 to have the same exp and length of coefficient. +- +- Done during addition. +- """ +- # Yes, the exponent is a long, but the difference between exponents +- # must be an int-- otherwise you'd get a big memory problem. +- numdigits = int(op1.exp - op2.exp) +- if numdigits < 0: +- numdigits = -numdigits +- tmp = op2 +- other = op1 +- else: +- tmp = op1 +- other = op2 +- +- +- if shouldround and numdigits > prec + 1: +- # Big difference in exponents - check the adjusted exponents +- tmp_len = len(str(tmp.int)) +- other_len = len(str(other.int)) +- if numdigits > (other_len + prec + 1 - tmp_len): +- # If the difference in adjusted exps is > prec+1, we know +- # other is insignificant, so might as well put a 1 after the precision. +- # (since this is only for addition.) Also stops use of massive longs. +- +- extend = prec + 2 - tmp_len +- if extend <= 0: +- extend = 1 +- tmp.int *= 10 ** extend +- tmp.exp -= extend +- other.int = 1 +- other.exp = tmp.exp +- return op1, op2 +- +- tmp.int *= 10 ** numdigits +- tmp.exp -= numdigits +- return op1, op2 +- +-def _adjust_coefficients(op1, op2): +- """Adjust op1, op2 so that op2.int * 10 > op1.int >= op2.int. +- +- Returns the adjusted op1, op2 as well as the change in op1.exp-op2.exp. +- +- Used on _WorkRep instances during division. +- """ +- adjust = 0 +- #If op1 is smaller, make it larger +- while op2.int > op1.int: +- op1.int *= 10 +- op1.exp -= 1 +- adjust += 1 +- +- #If op2 is too small, make it larger +- while op1.int >= (10 * op2.int): +- op2.int *= 10 +- op2.exp -= 1 +- adjust -= 1 +- +- return op1, op2, adjust +- +-##### Helper Functions ######################################## +- +-def _convert_other(other): +- """Convert other to Decimal. +- +- Verifies that it's ok to use in an implicit construction. +- """ +- if isinstance(other, Decimal): +- return other +- if isinstance(other, (int, long)): +- return Decimal(other) +- return NotImplemented +- +-_infinity_map = { +- 'inf' : 1, +- 'infinity' : 1, +- '+inf' : 1, +- '+infinity' : 1, +- '-inf' : -1, +- '-infinity' : -1 +-} +- +-def _isinfinity(num): +- """Determines whether a string or float is infinity. +- +- +1 for negative infinity; 0 for finite ; +1 for positive infinity +- """ +- num = str(num).lower() +- return _infinity_map.get(num, 0) +- +-def _isnan(num): +- """Determines whether a string or float is NaN +- +- (1, sign, diagnostic info as string) => NaN +- (2, sign, diagnostic info as string) => sNaN +- 0 => not a NaN +- """ +- num = str(num).lower() +- if not num: +- return 0 +- +- #get the sign, get rid of trailing [+-] +- sign = 0 +- if num[0] == '+': +- num = num[1:] +- elif num[0] == '-': #elif avoids '+-nan' +- num = num[1:] +- sign = 1 +- +- if num.startswith('nan'): +- if len(num) > 3 and not num[3:].isdigit(): #diagnostic info +- return 0 +- return (1, sign, num[3:].lstrip('0')) +- if num.startswith('snan'): +- if len(num) > 4 and not num[4:].isdigit(): +- return 0 +- return (2, sign, num[4:].lstrip('0')) +- return 0 +- +- +-##### Setup Specific Contexts ################################ +- +-# The default context prototype used by Context() +-# Is mutable, so that new contexts can have different default values +- +-DefaultContext = Context( +- prec=28, rounding=ROUND_HALF_EVEN, +- traps=[DivisionByZero, Overflow, InvalidOperation], +- flags=[], +- _rounding_decision=ALWAYS_ROUND, +- Emax=999999999, +- Emin=-999999999, +- capitals=1 +-) +- +-# Pre-made alternate contexts offered by the specification +-# Don't change these; the user should be able to select these +-# contexts and be able to reproduce results from other implementations +-# of the spec. +- +-BasicContext = Context( +- prec=9, rounding=ROUND_HALF_UP, +- traps=[DivisionByZero, Overflow, InvalidOperation, Clamped, Underflow], +- flags=[], +-) +- +-ExtendedContext = Context( +- prec=9, rounding=ROUND_HALF_EVEN, +- traps=[], +- flags=[], +-) +- +- +-##### Useful Constants (internal use only) #################### +- +-#Reusable defaults +-Inf = Decimal('Inf') +-negInf = Decimal('-Inf') +- +-#Infsign[sign] is infinity w/ that sign +-Infsign = (Inf, negInf) +- +-NaN = Decimal('NaN') +- +- +-##### crud for parsing strings ################################# +-import re +- +-# There's an optional sign at the start, and an optional exponent +-# at the end. The exponent has an optional sign and at least one +-# digit. In between, must have either at least one digit followed +-# by an optional fraction, or a decimal point followed by at least +-# one digit. Yuck. +- +-_parser = re.compile(r""" +-# \s* +- (?P[-+])? +- ( +- (?P\d+) (\. (?P\d*))? +- | +- \. (?P\d+) +- ) +- ([eE](?P[-+]? \d+))? +-# \s* +- $ +-""", re.VERBOSE).match #Uncomment the \s* to allow leading or trailing spaces. +- +-del re +- +-# return sign, n, p s.t. float string value == -1**sign * n * 10**p exactly +- +-def _string2exact(s): +- m = _parser(s) +- if m is None: +- raise ValueError("invalid literal for Decimal: %r" % s) +- +- if m.group('sign') == "-": +- sign = 1 +- else: +- sign = 0 +- +- exp = m.group('exp') +- if exp is None: +- exp = 0 +- else: +- exp = int(exp) +- +- intpart = m.group('int') +- if intpart is None: +- intpart = "" +- fracpart = m.group('onlyfrac') +- else: +- fracpart = m.group('frac') +- if fracpart is None: +- fracpart = "" +- +- exp -= len(fracpart) +- +- mantissa = intpart + fracpart +- tmp = map(int, mantissa) +- backup = tmp +- while tmp and tmp[0] == 0: +- del tmp[0] +- +- # It's a zero +- if not tmp: +- if backup: +- return (sign, tuple(backup), exp) +- return (sign, (0,), exp) +- mantissa = tuple(tmp) +- +- return (sign, mantissa, exp) +- +- +-if __name__ == '__main__': +- import doctest, sys +- doctest.testmod(sys.modules[__name__]) ++from decimal import * --- python-django-1.1.1.orig/debian/patches/03_manpage.diff +++ python-django-1.1.1/debian/patches/03_manpage.diff @@ -0,0 +1,23 @@ +Forwarded-Upstream: not needed +Author: Brett Parker +Comment: + Update the manual page to speak of django-admin instead of + django-admin.py as that's the name used by the Debian package. + . + This is a Debian specific patch. + +--- a/docs/man/django-admin.1 2007-09-08 10:47:27.516890257 +0100 ++++ b/docs/man/django-admin.1 2007-09-08 10:48:01.822845242 +0100 +@@ -1,9 +1,9 @@ +-.TH "django-admin.py" "1" "March 2008" "Django Project" "" ++.TH "django-admin" "1" "March 2008" "Django Project" "" + .SH "NAME" +-django\-admin.py \- Utility script for the Django web framework ++django\-admin \- Utility script for the Django web framework + .SH "SYNOPSIS" +-.B django\-admin.py ++.B django\-admin + .I + .B [options] + .sp + .SH "DESCRIPTION" --- python-django-1.1.1.orig/debian/patches/05_ftbfs_in_november.diff +++ python-django-1.1.1/debian/patches/05_ftbfs_in_november.diff @@ -0,0 +1,13 @@ +Forwarded-Upstream: http://code.djangoproject.com/changeset/11697 +Comment: + Fix FTBFS in November. + +--- ./tests/regressiontests/views/tests/generic/date_based.py (revision 10556) ++++ ./tests/regressiontests/views/tests/generic/date_based.py (revision 11697) +@@ -101,5 +101,5 @@ + now = datetime.now() + prev_month = now.date().replace(day=1) +- if prev_month.month == 11: ++ if prev_month.month == 1: + prev_month = prev_month.replace(year=prev_month.year-1, month=12) + else: --- python-django-1.1.1.orig/debian/patches/01_disable_url_verify_regression_tests.diff +++ python-django-1.1.1/debian/patches/01_disable_url_verify_regression_tests.diff @@ -0,0 +1,41 @@ +Forwarded-Upstream: not needed +Author: Krzysztof Klimonda +Comment: + Disable regression tests that require an internet connection. + . + This is a Debian specific patch. + +Index: python-django-1.1/tests/regressiontests/forms/fields.py +=================================================================== +--- python-django-1.1.orig/tests/regressiontests/forms/fields.py 2009-08-15 21:03:21.248330080 +0200 ++++ python-django-1.1/tests/regressiontests/forms/fields.py 2009-08-15 21:03:45.709392050 +0200 +@@ -977,29 +977,6 @@ + ... + ValidationError: [u'Enter a valid URL.'] + +-URLField takes an optional verify_exists parameter, which is False by default. +-This verifies that the URL is live on the Internet and doesn't return a 404 or 500: +->>> f = URLField(verify_exists=True) +->>> f.clean('http://www.google.com') # This will fail if there's no Internet connection +-u'http://www.google.com/' +->>> f.clean('http://example') +-Traceback (most recent call last): +-... +-ValidationError: [u'Enter a valid URL.'] +->>> f.clean('http://www.broken.djangoproject.com') # bad domain +-Traceback (most recent call last): +-... +-ValidationError: [u'This URL appears to be a broken link.'] +->>> f.clean('http://google.com/we-love-microsoft.html') # good domain, bad page +-Traceback (most recent call last): +-... +-ValidationError: [u'This URL appears to be a broken link.'] +->>> f = URLField(verify_exists=True, required=False) +->>> f.clean('') +-u'' +->>> f.clean('http://www.google.com') # This will fail if there's no Internet connection +-u'http://www.google.com/' +- + URLField also access min_length and max_length parameters, for convenience. + >>> f = URLField(min_length=15, max_length=20) + >>> f.clean('http://f.com') --- python-django-1.1.1.orig/debian/patches/04_hyphen-manpage.diff +++ python-django-1.1.1/debian/patches/04_hyphen-manpage.diff @@ -0,0 +1,17 @@ +Forwarded-Upstream: not yet +Author: Raphael Hertzog +Comment: + Fix a lintian I: message about improper usage of minus instead + of hyphen. + +--- a/docs/man/django-admin.1 2008-09-04 08:51:48.000000000 +0200 ++++ b/docs/man/django-admin.1 2008-09-04 08:52:47.000000000 +0200 +@@ -153,7 +153,7 @@ + .TP + .I \-e, \-\-extension=EXTENSION + The file extension(s) to examine (default: ".html", separate multiple +-extensions with commas, or use -e multiple times). ++extensions with commas, or use \-e multiple times). + .TP + .I \-a, \-\-all + Process all available locales when using makemessages..SH "ENVIRONMENT" --- python-django-1.1.1.orig/debian/patches/series +++ python-django-1.1.1/debian/patches/series @@ -0,0 +1,6 @@ +01_disable_url_verify_regression_tests.diff +02-embedded_code_copies.diff +03_manpage.diff +04_hyphen-manpage.diff +05_ftbfs_in_november.diff +06_python_2.6.3_regression.diff --- python-django-1.1.1.orig/debian/contrib/default +++ python-django-1.1.1/debian/contrib/default @@ -0,0 +1,16 @@ +# django project names/directories +DJANGO_SITES="myapp myapp2 myapp3" + +# path to the directory with your django projects +#SITES_PATH=/home/django/projects + +# path to the directory for socket and pid files +RUNFILES_PATH=$SITES_PATH/run + +# please make sure this is NOT root +# local user prefered, www-data accepted +RUN_AS=django + +# maximum requests before fast-cgi process respawns +# (a.k.a. get killed and let live) +MAXREQUESTS=100 --- python-django-1.1.1.orig/debian/contrib/initscript +++ python-django-1.1.1/debian/contrib/initscript @@ -0,0 +1,131 @@ +#! /bin/sh +### BEGIN INIT INFO +# Provides: FastCGI servers for Django +# Required-Start: networking +# Required-Stop: networking +# Default-Start: 2 3 4 5 +# Default-Stop: S 0 1 6 +# Short-Description: Start FastCGI servers with Django. +# Description: Django, in order to operate with FastCGI, must be started +# in a very specific way with manage.py. This must be done +# for each Django web server that has to run. +### END INIT INFO +# +# Author: Guillermo Fernandez Castellanos +# . +# +# Changed: Jannis Leidel +# +# Joost Cassee +# +# +# Version: @(#)fastcgi 0.3 05-Aug-2008 joost AT cassee.net +# + +set -e + +#### CONFIGURATION (override in /etc/default/django) + +# django project names/directories +DJANGO_SITES="" + +# path to the directory with your django projects +SITES_PATH=/var/lib/django + +# path to the directory for socket and pid files +RUNFILES_PATH=/var/run/django + +# please make sure this is NOT root +# local user prefered, www-data accepted +RUN_AS=www-data + +# maximum requests before fast-cgi process respawns +# (a.k.a. get killed and let live) +MAXREQUESTS=1000 + +#### END CONFIGURATION + +# Include defaults if available +if [ -f /etc/default/django ] ; then + . /etc/default/django +fi + +PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin +DESC="Django FastCGI servers" +NAME=$0 +SCRIPTNAME=/etc/init.d/$NAME +mkdir -p $RUNFILES_PATH +chown -R $RUN_AS:$RUN_AS $RUNFILES_PATH + +# +# Function that starts the daemon/service. +# +d_start() +{ + # Starting all Django FastCGI processes + # PORT=$PORT_START + for SITE in $DJANGO_SITES + do + echo -n ", $SITE" + if [ -f $RUNFILES_PATH/$SITE.pid ]; then + echo -n " already running" + else + start-stop-daemon --start --quiet \ + --pidfile $RUNFILES_PATH/$SITE.pid \ + --chuid $RUN_AS --exec /usr/bin/env -- python \ + $SITES_PATH/$SITE/manage.py runfcgi \ + protocol=fcgi method=threaded maxrequests=$MAXREQUESTS \ + socket=$RUNFILES_PATH/$SITE.socket \ + pidfile=$RUNFILES_PATH/$SITE.pid + chmod 400 $RUNFILES_PATH/$SITE.pid + fi + sleep 1 + done +} + +# +# Function that stops the daemon/service. +# +d_stop() { + # Killing all Django FastCGI processes running + for SITE in $DJANGO_SITES + do + echo -n ", $SITE" + start-stop-daemon --stop --quiet --pidfile $RUNFILES_PATH/$SITE.pid \ + || echo -n " not running" + if [ -f $RUNFILES_PATH/$SITE.pid ]; then + rm -f $RUNFILES_PATH/$SITE.pid + fi + sleep 1 + done +} + +ACTION="$1" +case "$ACTION" in + start) + echo -n "Starting $DESC: $NAME" + d_start + echo "." + ;; + + stop) + echo -n "Stopping $DESC: $NAME" + d_stop + echo "." + ;; + + restart|force-reload) + echo -n "Restarting $DESC: $NAME" + d_stop + sleep 2 + d_start + echo "." + ;; + + *) + echo "Usage: $NAME {start|stop|restart|force-reload}" >&2 + exit 3 + ;; +esac + +exit 0