Rev 4778: Merge bzr.dev, resolve NEWS in http://bazaar.launchpad.net/~jameinel/bzr/2.1-static-tuple-btree-string-intern

John Arbash Meinel john at arbash-meinel.com
Thu Oct 15 19:18:58 BST 2009


At http://bazaar.launchpad.net/~jameinel/bzr/2.1-static-tuple-btree-string-intern

------------------------------------------------------------
revno: 4778 [merge]
revision-id: john at arbash-meinel.com-20091015181844-ame1y9yxta689ojp
parent: john at arbash-meinel.com-20091014140356-f8819b4n4lygkf3u
parent: pqm at pqm.ubuntu.com-20091015180224-g9dphv661law8y20
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.1-static-tuple-btree-string-intern
timestamp: Thu 2009-10-15 13:18:44 -0500
message:
  Merge bzr.dev, resolve NEWS
added:
  bzrlib/tests/per_uifactory/    bzrlibtestsper_uifac-20090923023429-a6kukw4evi29ovza-1
  bzrlib/tests/per_uifactory/__init__.py __init__.py-20090923045301-o12zypjwsidxn2hy-1
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
  bzrlib/_simple_set_pyx.pyx     _static_tuple_intern-20091002053806-sid67p8spedru51w-1
  bzrlib/_static_tuple_c.c       _keys_type_c.c-20090908204220-aa346ccw4l37jzt7-1
  bzrlib/commands.py             bzr.py-20050309040720-d10f4714595cf8c3
  bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
  bzrlib/tests/test__simple_set.py test__static_tuple_i-20091002053806-sid67p8spedru51w-2
  bzrlib/tests/test_ui.py        test_ui.py-20051130162854-458e667a7414af09
  bzrlib/ui/__init__.py          ui.py-20050824083933-8cf663c763ba53a9
  bzrlib/ui/text.py              text.py-20051130153916-2e438cffc8afc478
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS	2009-10-14 13:54:09 +0000
+++ b/NEWS	2009-10-15 18:18:44 +0000
@@ -6,11 +6,113 @@
    :depth: 1
 
 
-2.1.0 series (not released yet)
-###############################
-
-Compatibility Breaks
-********************
+bzr 2.1.0b2 (not released yet)
+##############################
+
+:Codename:
+:2.1.0b2: ???
+
+
+Compatibility Breaks
+********************
+
+New Features
+************
+
+Bug Fixes
+*********
+
+Improvements
+************
+
+* When reading index files, we now use a ``StaticTuple`` rather than a
+  plain ``tuple`` object. This generally gives a 20% decrease in peak
+  memory, and can give a performance boost up to 40% on large projects.
+  (John Arbash Meinel)
+
+Documentation
+*************
+
+API Changes
+***********
+
+* ``UIFactory`` now has new ``show_error``, ``show_message`` and
+  ``show_warning`` methods, which can be hooked by non-text UIs.  
+  (Martin Pool)
+
+Internals
+*********
+
+* Added ``bzrlib._simple_set_pyx``. This is a hybrid between a Set and a
+  Dict (it only holds keys, but you can lookup the object located at a
+  given key). It has significantly reduced memory consumption versus the
+  builtin objects (1/2 the size of Set, 1/3rd the size of Dict). This is
+  used as the interning structure for StaticTuple objects.
+  (John Arbash Meinel)
+
+* ``bzrlib._static_tuple_pyx.StaticTuple`` is now available and used by
+  the btree index parser. This class functions similarly to ``tuple``
+  objects. However, it can only point at other ``StaticTuple`` instances
+  or strings. This allows us to remove it from the garbage collector (it
+  cannot be in a cycle), it also allows us to intern the objects. In
+  testing, this can reduce peak memory by 20-40%, and significantly
+  improve performance by removing objects from being inspected by the
+  garbage collector. (John Arbash Meinel)
+
+Testing
+*******
+
+
+bzr 2.0.2 (not released yet)
+############################
+
+:Codename:
+:2.0.2: ???
+
+Compatibility Breaks
+********************
+
+New Features
+************
+
+Bug Fixes
+*********
+
+Improvements
+************
+
+Documentation
+*************
+
+API Changes
+***********
+
+Internals
+*********
+
+Testing
+*******
+
+
+bzr 2.1.0b1
+###########
+
+:Codename: While the cat is away
+:2.1.0b1: 2009-10-14
+
+This is the first development release in the new split "stable" and
+"development" series. As such, the release is a snapshot of bzr.dev
+without creating a release candidate first. This release includes a
+fair amount of internal changes, with deprecated code being removed,
+and several new feature developments. People looking for a stable code
+base with only bugfixes should focus on the 2.0.1 release. All bugfixes
+present in 2.0.1 are present in 2.1.0b1.
+
+Highlights include support for ``bzr+ssh://host/~/homedir`` style urls,
+finer control over the plugin search path via extended BZR_PLUGIN_PATH
+syntax, visible warnings when extension modules fail to load, and improved
+error handling during unlocking.
+
 
 New Features
 ************
@@ -60,113 +162,41 @@
   filename will issue a warning and skip over those files.
   (Robert Collins, #3918)
 
-* ``bzr check`` in pack-0.92, 1.6 and 1.9 format repositories will no
-  longer report incorrect errors about ``Missing inventory ('TREE_ROOT', ...)``
-  (Robert Collins, #416732)
-
 * ``bzr dpush`` now aborts if uncommitted changes (including pending merges)
   are present in the working tree. The configuration option ``dpush_strict``
   can be used to set the default for this behavior.
   (Vincent Ladeuil, #438158)
 
-* ``bzr info -v`` on a 2a format still claimed that it was a "Development
-  format" (John Arbash Meinel, #424392)
-
 * ``bzr merge`` and ``bzr remove-tree`` now requires --force if pending
   merges are present in the working tree.
   (Vincent Ladeuil, #426344)
 
-* bzr will attempt to authenticate with SSH servers that support
-  ``keyboard-interactive`` auth but not ``password`` auth when using
-  Paramiko.   (Andrew Bennetts, #433846)
-
 * Clearer message when Bazaar runs out of memory, instead of a ``MemoryError``
   traceback.  (Martin Pool, #109115)
 
-* Conversion to 2a will create a single pack for all the new revisions (as
-  long as it ran without interruption). This improves both ``bzr upgrade``
-  and ``bzr pull`` or ``bzr merge`` from local branches in older formats.
-  The autopack logic that occurs every 100 revisions during local
-  conversions was not returning that pack's identifier, which resulted in
-  the partial packs created during the conversion not being consolidated
-  at the end of the conversion process. (Robert Collins, #423818)
-
 * Don't give a warning on Windows when failing to import ``_readdir_pyx``
   as it is never built. (John Arbash Meinel, #430645)
 
 * Don't restrict the command name used to run the test suite.
   (Vincent Ladeuil, #419950)
 
-* Fetches from 2a to 2a are now again requested in 'groupcompress' order.
-  Groups that are seen as 'underutilized' will be repacked on-the-fly.
-  This means that when the source is fully packed, there is minimal
-  overhead during the fetch, but if the source is poorly packed the result
-  is a fairly well packed repository (not as good as 'bzr pack' but
-  good-enough.) (Robert Collins, John Arbash Meinel, #402652)
-
-* Fixed fetches from a stacked branch on a smart server that were failing
-  with some combinations of remote and local formats.  This was causing
-  "unknown object type identifier 60" errors.  (Andrew Bennetts, #427736)
-
-* Fixed ``ObjectNotLocked`` errors when doing some log and diff operations
-  on branches via a smart server.  (Andrew Bennetts, #389413)
-
 * ftp transports were built differently when the kerberos python module was
   present leading to obscure failures related to ASCII/BINARY modes.
   (Vincent Ladeuil, #443041)
 
-* Handle things like ``bzr add foo`` and ``bzr rm foo`` when the tree is
-  at the root of a drive. ``osutils._cicp_canonical_relpath`` always
-  assumed that ``abspath()`` returned a path that did not have a trailing
-  ``/``, but that is not true when working at the root of the filesystem.
-  (John Arbash Meinel, Jason Spashett, #322807)
-
-* Improve the time for ``bzr log DIR`` for 2a format repositories.
-  We had been using the same code path as for <2a formats, which required
-  iterating over all objects in all revisions.
-  (John Arbash Meinel, #374730)
-
-* Make sure that we unlock the tree if we fail to create a TreeTransform
-  object when doing a merge, and there is limbo, or pending-deletions
-  directory.  (Gary van der Merwe, #427773)
-
 * Network streams now decode adjacent records of the same type into a
   single stream, reducing layering churn. (Robert Collins)
 
-* Occasional IndexError on renamed files have been fixed. Operations that
-  set a full inventory in the working tree will now go via the
-  apply_inventory_delta code path which is simpler and easier to
-  understand than dirstates set_state_from_inventory method. This may
-  have a small performance impact on operations built on _write_inventory,
-  but such operations are already doing full tree scans, so no radical
-  performance change should be observed. (Robert Collins, #403322)
-
-* Prevent some kinds of incomplete data from being committed to a 2a
-  repository, such as revisions without inventories or inventories without
-  chk_bytes root records.
-  (Andrew Bennetts, #423506)
-
 * PreviewTree behaves correctly when get_file_mtime is invoked on an unmodified
   file. (Aaron Bentley, #251532)
 
 * Registry objects should not use iteritems() when asked to use items().
   (Vincent Ladeuil, #430510)
 
-* Retrieving file text or mtime from a _PreviewTree has good performance when
-  there are many changes.  (Aaron Bentley)
-
-* The CHK index pages now use an unlimited cache size. With a limited
-  cache and a large project, the random access of chk pages could cause us
-  to download the entire cix file many times.
-  (John Arbash Meinel, #402623)
-
 * Weave based repositories couldn't be cloned when committers were using
   domains or user ids embedding '.sig'. Now they can.
   (Matthew Fuller, Vincent Ladeuil, #430868)
 
-* When a file kind becomes unversionable after being added, a sensible
-  error will be shown instead of a traceback. (Robert Collins, #438569)
-
 Improvements
 ************
 
@@ -185,12 +215,6 @@
   ``TooManyConcurrentRequests`` and similar errors.
   (Andrew Bennetts, #429747)
 
-* When reading index files, we now use a ``StaticTuple`` rather than a
-  plain ``tuple`` object. This generally gives a 20% decrease in peak
-  memory, and can give a performance boost up to 40% on large projects.
-  (John Arbash Meinel)
-
-
 Documentation
 *************
 
@@ -199,12 +223,6 @@
 * Help on hooks no longer says 'Not deprecated' for hooks that are
   currently supported. (Ian Clatworthy, #422415)
 
-* Improved README. (Ian Clatworthy)
-
-* Improved upgrade documentation for Launchpad branches.
-  (Barry Warsaw)
-
-
 API Changes
 ***********
 
@@ -239,27 +257,11 @@
   repository or branch object is unlocked then relocked the same way.
   (Andrew Bennetts)
   
-* Added ``bzrlib._simple_set_pyx``. This is a hybrid between a Set and a
-  Dict (it only holds keys, but you can lookup the object located at a
-  given key). It has significantly reduced memory consumption versus the
-  builtin objects (1/2 the size of Set, 1/3rd the size of Dict). This is
-  used as the interning structure for StaticTuple objects.
-  (John Arbash Meinel)
-
 * ``BTreeLeafParser.extract_key`` has been tweaked slightly to reduce
   mallocs while parsing the index (approx 3=>1 mallocs per key read).
   This results in a 10% speedup while reading an index.
   (John Arbash Meinel)
 
-* ``bzrlib._static_tuple_pyx.StaticTuple`` is now available and used by
-  the btree index parser. This class functions similarly to ``tuple``
-  objects. However, it can only point at other ``StaticTuple`` instances
-  or strings. This allows us to remove it from the garbage collector (it
-  cannot be in a cycle), it also allows us to intern the objects. In
-  testing, this can reduce peak memory by 20-40%, and significantly
-  improve performance by removing objects from being inspected by the
-  garbage collector. (John Arbash Meinel)
-
 * The ``bzrlib.lsprof`` module has a new class ``BzrProfiler`` which makes
   profiling in some situations like callbacks and generators easier.
   (Robert Collins)
@@ -301,8 +303,16 @@
   present. (Vincent Ladeuil, #430749)
 
 
-bzr 2.0.1 (Not Released Yet)
-############################
+bzr 2.0.1
+#########
+
+:Codename: Stability First
+:2.0.1: 2009-10-14
+
+The first of our new ongoing bugfix-only stable releases has arrived. It
+includes a collection of 12 bugfixes applied to bzr 2.0.0, but does not
+include any of the feature development in the 2.1.0 series.
+
 
 Bug Fixes
 *********
@@ -328,6 +338,9 @@
   ``/``, but that is not true when working at the root of the filesystem.
   (John Arbash Meinel, Jason Spashett, #322807)
 
+* Hide deprecation warnings for 'final' releases for python2.6.
+  (John Arbash Meinel, #440062)
+
 * Improve the time for ``bzr log DIR`` for 2a format repositories.
   We had been using the same code path as for <2a formats, which required
   iterating over all objects in all revisions.
@@ -356,7 +369,6 @@
 * When a file kind becomes unversionable after being added, a sensible
   error will be shown instead of a traceback. (Robert Collins, #438569)
 
-
 Documentation
 *************
 
@@ -10985,5 +10997,38 @@
 * Storage of local versions: init, add, remove, rm, info, log,
   diff, status, etc.
 
+
+bzr ?.?.? (not released yet)
+############################
+
+:Codename: template
+:2.0.2: ???
+
+Compatibility Breaks
+********************
+
+New Features
+************
+
+Bug Fixes
+*********
+
+Improvements
+************
+
+Documentation
+*************
+
+API Changes
+***********
+
+Internals
+*********
+
+Testing
+*******
+
+
+
 ..
    vim: tw=74 ft=rst ff=unix

=== modified file 'bzrlib/__init__.py'
--- a/bzrlib/__init__.py	2009-09-25 21:24:21 +0000
+++ b/bzrlib/__init__.py	2009-10-15 04:06:32 +0000
@@ -44,7 +44,7 @@
 # Python version 2.0 is (2, 0, 0, 'final', 0)."  Additionally we use a
 # releaselevel of 'dev' for unreleased under-development code.
 
-version_info = (2, 1, 0, 'dev', 0)
+version_info = (2, 1, 0, 'dev', 2)
 
 # API compatibility version: bzrlib is currently API compatible with 1.15.
 api_minimum_version = (2, 1, 0)

=== modified file 'bzrlib/_simple_set_pyx.pyx'
--- a/bzrlib/_simple_set_pyx.pyx	2009-10-13 16:44:43 +0000
+++ b/bzrlib/_simple_set_pyx.pyx	2009-10-14 15:57:06 +0000
@@ -21,13 +21,11 @@
 
 cdef extern from "Python.h":
     ctypedef unsigned long size_t
-    ctypedef long (*hashfunc)(PyObject*)
-    ctypedef PyObject *(*richcmpfunc)(PyObject *, PyObject *, int)
+    ctypedef long (*hashfunc)(PyObject*) except -1
+    ctypedef object (*richcmpfunc)(PyObject *, PyObject *, int)
     ctypedef int (*visitproc)(PyObject *, void *)
     ctypedef int (*traverseproc)(PyObject *, visitproc, void *)
     int Py_EQ
-    PyObject *Py_True
-    PyObject *Py_NotImplemented
     void Py_INCREF(PyObject *)
     void Py_DECREF(PyObject *)
     ctypedef struct PyTypeObject:
@@ -36,7 +34,6 @@
         traverseproc tp_traverse
 
     PyTypeObject *Py_TYPE(PyObject *)
-    int PyObject_IsTrue(PyObject *)
     # Note: *Don't* use hash(), Pyrex 0.9.8.5 thinks it returns an 'int', and
     #       thus silently truncates to 32-bits on 64-bit machines.
     long PyObject_Hash(PyObject *) except -1
@@ -58,9 +55,12 @@
 _dummy = <PyObject *>_dummy_obj
 
 
+cdef object _NotImplemented
+_NotImplemented = NotImplemented
+
+
 cdef int _is_equal(PyObject *this, long this_hash, PyObject *other) except -1:
     cdef long other_hash
-    cdef PyObject *res
 
     if this == other:
         return 1
@@ -76,20 +76,12 @@
     #      equal. (It doesn't try to cast them both to some intermediate form
     #      that would compare equal.)
     res = Py_TYPE(this).tp_richcompare(this, other, Py_EQ)
-    if res == NULL: # Exception
-        return -1
-    if PyObject_IsTrue(res):
-        Py_DECREF(res)
-        return 1
-    if res == Py_NotImplemented:
-        Py_DECREF(res)
+    if res is _NotImplemented:
         res = Py_TYPE(other).tp_richcompare(other, this, Py_EQ)
-    if res == NULL:
-        return -1
-    if PyObject_IsTrue(res):
-        Py_DECREF(res)
+        if res is _NotImplemented:
+            return 0
+    if res:
         return 1
-    Py_DECREF(res)
     return 0
 
 

=== modified file 'bzrlib/_static_tuple_c.c'
--- a/bzrlib/_static_tuple_c.c	2009-10-14 13:54:09 +0000
+++ b/bzrlib/_static_tuple_c.c	2009-10-15 18:18:44 +0000
@@ -610,7 +610,7 @@
     (hashfunc)StaticTuple_hash,                  /* tp_hash */
     0,                                           /* tp_call */
     0,                                           /* tp_str */
-    PyObject_GenericGetAttr,                     /* tp_getattro */
+    0,                                           /* tp_getattro */
     0,                                           /* tp_setattro */
     0,                                           /* tp_as_buffer */
     Py_TPFLAGS_DEFAULT,                          /* tp_flags*/
@@ -745,6 +745,7 @@
 {
     PyObject* m;
 
+    StaticTuple_Type.tp_getattro = PyObject_GenericGetAttr;
     if (PyType_Ready(&StaticTuple_Type) < 0)
         return;
 

=== modified file 'bzrlib/commands.py'
--- a/bzrlib/commands.py	2009-09-17 07:16:12 +0000
+++ b/bzrlib/commands.py	2009-10-14 20:02:28 +0000
@@ -1097,7 +1097,7 @@
 
     # Is this a final release version? If so, we should suppress warnings
     if bzrlib.version_info[3] == 'final':
-        suppress_deprecation_warnings(override=False)
+        suppress_deprecation_warnings(override=True)
     if argv is None:
         argv = osutils.get_unicode_argv()
     else:

=== modified file 'bzrlib/tests/__init__.py'
--- a/bzrlib/tests/__init__.py	2009-10-13 08:46:44 +0000
+++ b/bzrlib/tests/__init__.py	2009-10-14 08:51:44 +0000
@@ -3690,6 +3690,7 @@
         'bzrlib.tests.per_repository',
         'bzrlib.tests.per_repository_chk',
         'bzrlib.tests.per_repository_reference',
+        'bzrlib.tests.per_uifactory',
         'bzrlib.tests.per_versionedfile',
         'bzrlib.tests.per_workingtree',
         'bzrlib.tests.test__annotator',

=== added directory 'bzrlib/tests/per_uifactory'
=== added file 'bzrlib/tests/per_uifactory/__init__.py'
--- a/bzrlib/tests/per_uifactory/__init__.py	1970-01-01 00:00:00 +0000
+++ b/bzrlib/tests/per_uifactory/__init__.py	2009-09-23 06:29:46 +0000
@@ -0,0 +1,148 @@
+# Copyright (C) 2009 Canonical Ltd
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+"""Tests run per UIFactory."""
+
+# Testing UIFactories is a bit interesting because we require they all support a
+# common interface, but the way they implement it can vary very widely.  Between
+# text, batch-mode, graphical and other potential UIFactories, the requirements
+# to set up a factory, to make it respond to requests, and to simulate user
+# input can vary a lot.
+#
+# We want tests that therefore allow for the evaluation of the result to vary
+# per implementation, but we want to check that the supported facilities are
+# the same across all UIFactorys, unless they're specifically skipped.
+#
+# Our normal approach is to use test scenarios but that seems to just end up
+# creating test-like objects inside the scenario.  Therefore we fall back to
+# the older method of putting the common tests in a mixin.
+#
+# Plugins that add new UIFactorys can create their own subclasses.
+
+
+from cStringIO import StringIO
+import unittest
+
+
+from bzrlib import (
+    tests,
+    ui,
+    )
+
+
+class UIFactoryTestMixin(object):
+    """Common tests for UIFactories.
+
+    These are supposed to be expressed with no assumptions about how the
+    UIFactory implements the method, only that it does implement them (or
+    fails cleanly), and that the concrete subclass will make arrangements to
+    build a factory and to examine its behaviour.
+
+    Note that this is *not* a TestCase, because it can't be directly run, but
+    the concrete subclasses should be.
+    """
+
+    def test_note(self):
+        self.factory.note("a note to the user")
+        self._check_note("a note to the user")
+
+    def test_show_error(self):
+        msg = 'an error occurred'
+        self.factory.show_error(msg)
+        self._check_show_error(msg)
+
+    def test_show_message(self):
+        msg = 'a message'
+        self.factory.show_message(msg)
+        self._check_show_message(msg)
+
+    def test_show_warning(self):
+        msg = 'a warning'
+        self.factory.show_warning(msg)
+        self._check_show_warning(msg)
+
+
+class TestTextUIFactory(tests.TestCase, UIFactoryTestMixin):
+
+    def setUp(self):
+        super(TestTextUIFactory, self).setUp()
+        self.stdin = StringIO()
+        self.stdout = StringIO()
+        self.stderr = StringIO()
+        self.factory = ui.text.TextUIFactory(self.stdin, self.stdout,
+            self.stderr)
+
+    def _check_note(self, note_text):
+        self.assertEquals("%s\n" % note_text,
+            self.stdout.getvalue())
+
+    def _check_show_error(self, msg):
+        self.assertEquals("bzr: error: %s\n" % msg,
+            self.stderr.getvalue())
+        self.assertEquals("", self.stdout.getvalue())
+
+    def _check_show_message(self, msg):
+        self.assertEquals("%s\n" % msg,
+            self.stdout.getvalue())
+        self.assertEquals("", self.stderr.getvalue())
+
+    def _check_show_warning(self, msg):
+        self.assertEquals("bzr: warning: %s\n" % msg,
+            self.stderr.getvalue())
+        self.assertEquals("", self.stdout.getvalue())
+
+
+class TestSilentUIFactory(tests.TestCase, UIFactoryTestMixin):
+    # discards output, therefore tests for output expect nothing
+
+    def setUp(self):
+        super(TestSilentUIFactory, self).setUp()
+        self.factory = ui.SilentUIFactory()
+
+    def _check_note(self, note_text):
+        # it's just discarded
+        pass
+
+    def _check_show_error(self, msg):
+        pass
+
+    def _check_show_message(self, msg):
+        pass
+
+    def _check_show_warning(self, msg):
+        pass
+
+
+class TestCannedInputUIFactory(tests.TestCase, UIFactoryTestMixin):
+    # discards output, reads input from variables
+
+    def setUp(self):
+        super(TestCannedInputUIFactory, self).setUp()
+        self.factory = ui.CannedInputUIFactory([])
+
+    def _check_note(self, note_text):
+        pass
+
+    def _check_show_error(self, msg):
+        pass
+
+    def _check_show_message(self, msg):
+        pass
+
+    def _check_show_warning(self, msg):
+        pass
+
+

=== modified file 'bzrlib/tests/test__simple_set.py'
--- a/bzrlib/tests/test__simple_set.py	2009-10-12 15:55:26 +0000
+++ b/bzrlib/tests/test__simple_set.py	2009-10-14 15:53:34 +0000
@@ -69,6 +69,12 @@
         raise RuntimeError('I refuse to play nice')
 
 
+class _NoImplementCompare(_Hashable):
+
+    def __eq__(self, other):
+        return NotImplemented
+
+
 # Even though this is an extension, we don't permute the tests for a python
 # version. As the plain python version is just a dict or set
 
@@ -329,6 +335,20 @@
         # Tries to compare with k1, fails
         self.assertRaises(RuntimeError, obj.add, k2)
 
+    def test_richcompare_not_implemented(self):
+        obj = self.module.SimpleSet()
+        # Even though their hashes are the same, tp_richcompare returns
+        # NotImplemented, which means we treat them as not equal
+        k1 = _NoImplementCompare(200)
+        k2 = _NoImplementCompare(200)
+        self.assertLookup(200, '<null>', obj, k1)
+        self.assertLookup(200, '<null>', obj, k2)
+        self.assertIs(k1, obj.add(k1))
+        self.assertLookup(200, k1, obj, k1)
+        self.assertLookup(201, '<null>', obj, k2)
+        self.assertIs(k2, obj.add(k2))
+        self.assertIs(k1, obj[k1])
+
     def test_add_and_remove_lots_of_items(self):
         obj = self.module.SimpleSet()
         chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890'

=== modified file 'bzrlib/tests/test_ui.py'
--- a/bzrlib/tests/test_ui.py	2009-09-24 08:56:52 +0000
+++ b/bzrlib/tests/test_ui.py	2009-10-14 08:51:44 +0000
@@ -54,7 +54,7 @@
     )
 
 
-class UITests(tests.TestCase):
+class TestTextUIFactory(tests.TestCase):
 
     def test_text_factory_ascii_password(self):
         ui = tests.TestUIFactory(stdin='secret\n',
@@ -100,56 +100,6 @@
         finally:
             pb.finished()
 
-    def test_progress_construction(self):
-        """TextUIFactory constructs the right progress view.
-        """
-        for (file_class, term, pb, expected_pb_class) in (
-            # on an xterm, either use them or not as the user requests,
-            # otherwise default on
-            (_TTYStringIO, 'xterm', 'none', NullProgressView),
-            (_TTYStringIO, 'xterm', 'text', TextProgressView),
-            (_TTYStringIO, 'xterm', None, TextProgressView),
-            # on a dumb terminal, again if there's explicit configuration do
-            # it, otherwise default off
-            (_TTYStringIO, 'dumb', 'none', NullProgressView),
-            (_TTYStringIO, 'dumb', 'text', TextProgressView),
-            (_TTYStringIO, 'dumb', None, NullProgressView),
-            # on a non-tty terminal, it's null regardless of $TERM
-            (StringIO, 'xterm', None, NullProgressView),
-            (StringIO, 'dumb', None, NullProgressView),
-            # however, it can still be forced on
-            (StringIO, 'dumb', 'text', TextProgressView),
-            ):
-            os.environ['TERM'] = term
-            if pb is None:
-                if 'BZR_PROGRESS_BAR' in os.environ:
-                    del os.environ['BZR_PROGRESS_BAR']
-            else:
-                os.environ['BZR_PROGRESS_BAR'] = pb
-            stdin = file_class('')
-            stderr = file_class()
-            stdout = file_class()
-            uif = make_ui_for_terminal(stdin, stdout, stderr)
-            self.assertIsInstance(uif, TextUIFactory,
-                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
-            self.assertIsInstance(uif.make_progress_view(),
-                expected_pb_class,
-                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
-
-    def test_text_ui_non_terminal(self):
-        """Even on non-ttys, make_ui_for_terminal gives a text ui."""
-        stdin = _NonTTYStringIO('')
-        stderr = _NonTTYStringIO()
-        stdout = _NonTTYStringIO()
-        for term_type in ['dumb', None, 'xterm']:
-            if term_type is None:
-                del os.environ['TERM']
-            else:
-                os.environ['TERM'] = term_type
-            uif = make_ui_for_terminal(stdin, stdout, stderr)
-            self.assertIsInstance(uif, TextUIFactory,
-                'TERM=%r' % (term_type,))
-
     def test_progress_note(self):
         stderr = StringIO()
         stdout = StringIO()
@@ -304,6 +254,59 @@
             pb.finished()
 
 
+class UITests(tests.TestCase):
+
+    def test_progress_construction(self):
+        """TextUIFactory constructs the right progress view.
+        """
+        for (file_class, term, pb, expected_pb_class) in (
+            # on an xterm, either use them or not as the user requests,
+            # otherwise default on
+            (_TTYStringIO, 'xterm', 'none', NullProgressView),
+            (_TTYStringIO, 'xterm', 'text', TextProgressView),
+            (_TTYStringIO, 'xterm', None, TextProgressView),
+            # on a dumb terminal, again if there's explicit configuration do
+            # it, otherwise default off
+            (_TTYStringIO, 'dumb', 'none', NullProgressView),
+            (_TTYStringIO, 'dumb', 'text', TextProgressView),
+            (_TTYStringIO, 'dumb', None, NullProgressView),
+            # on a non-tty terminal, it's null regardless of $TERM
+            (StringIO, 'xterm', None, NullProgressView),
+            (StringIO, 'dumb', None, NullProgressView),
+            # however, it can still be forced on
+            (StringIO, 'dumb', 'text', TextProgressView),
+            ):
+            os.environ['TERM'] = term
+            if pb is None:
+                if 'BZR_PROGRESS_BAR' in os.environ:
+                    del os.environ['BZR_PROGRESS_BAR']
+            else:
+                os.environ['BZR_PROGRESS_BAR'] = pb
+            stdin = file_class('')
+            stderr = file_class()
+            stdout = file_class()
+            uif = make_ui_for_terminal(stdin, stdout, stderr)
+            self.assertIsInstance(uif, TextUIFactory,
+                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
+            self.assertIsInstance(uif.make_progress_view(),
+                expected_pb_class,
+                "TERM=%s BZR_PROGRESS_BAR=%s uif=%r" % (term, pb, uif,))
+
+    def test_text_ui_non_terminal(self):
+        """Even on non-ttys, make_ui_for_terminal gives a text ui."""
+        stdin = _NonTTYStringIO('')
+        stderr = _NonTTYStringIO()
+        stdout = _NonTTYStringIO()
+        for term_type in ['dumb', None, 'xterm']:
+            if term_type is None:
+                del os.environ['TERM']
+            else:
+                os.environ['TERM'] = term_type
+            uif = make_ui_for_terminal(stdin, stdout, stderr)
+            self.assertIsInstance(uif, TextUIFactory,
+                'TERM=%r' % (term_type,))
+
+
 class CLIUITests(TestCase):
 
     def test_cli_factory_deprecated(self):

=== modified file 'bzrlib/ui/__init__.py'
--- a/bzrlib/ui/__init__.py	2009-07-22 07:34:08 +0000
+++ b/bzrlib/ui/__init__.py	2009-09-23 06:29:46 +0000
@@ -22,18 +22,18 @@
 Several levels are supported, and you can also register new factories such as
 for a GUI.
 
-UIFactory
+bzrlib.ui.UIFactory
     Semi-abstract base class
 
-SilentUIFactory
+bzrlib.ui.SilentUIFactory
     Produces no output and cannot take any input; useful for programs using
     bzrlib in batch mode or for programs such as loggerhead.
 
-CannedInputUIFactory
+bzrlib.ui.CannedInputUIFactory
     For use in testing; the input values to be returned are provided 
     at construction.
 
-TextUIFactory
+bzrlib.ui.text.TextUIFactory
     Standard text command-line interface, with stdin, stdout, stderr.
     May make more or less advanced use of them, eg in drawing progress bars,
     depending on the detected capabilities of the terminal.
@@ -208,6 +208,22 @@
         """
         pass
 
+    def show_error(self, msg):
+        """Show an error message (not an exception) to the user.
+        
+        The message should not have an error prefix or trailing newline.  That
+        will be added by the factory if appropriate. 
+        """
+        raise NotImplementedError(self.show_error)
+
+    def show_message(self, msg):
+        """Show a message to the user."""
+        raise NotImplementedError(self.show_message)
+
+    def show_warning(self, msg):
+        """Show a warning to the user."""
+        raise NotImplementedError(self.show_warning)
+
 
 
 class CLIUIFactory(UIFactory):
@@ -318,6 +334,15 @@
     def get_username(self, prompt, **kwargs):
         return None
 
+    def show_error(self, msg):
+        pass
+
+    def show_message(self, msg):
+        pass
+
+    def show_warning(self, msg):
+        pass
+
 
 class CannedInputUIFactory(SilentUIFactory):
     """A silent UI that return canned input."""

=== modified file 'bzrlib/ui/text.py'
--- a/bzrlib/ui/text.py	2009-08-06 02:23:37 +0000
+++ b/bzrlib/ui/text.py	2009-09-23 06:29:46 +0000
@@ -49,9 +49,6 @@
                  stdout=None,
                  stderr=None):
         """Create a TextUIFactory.
-
-        :param bar_type: The type of progress bar to create.  Deprecated
-            and ignored; a TextProgressView is always used.
         """
         super(TextUIFactory, self).__init__()
         # TODO: there's no good reason not to pass all three streams, maybe we
@@ -176,6 +173,17 @@
         self._progress_view.show_transport_activity(transport,
             direction, byte_count)
 
+    def show_error(self, msg):
+        self.clear_term()
+        self.stderr.write("bzr: error: %s\n" % msg)
+
+    def show_message(self, msg):
+        self.note(msg)
+
+    def show_warning(self, msg):
+        self.clear_term()
+        self.stderr.write("bzr: warning: %s\n" % msg)
+
     def _progress_updated(self, task):
         """A task has been updated and wants to be displayed.
         """



More information about the bazaar-commits mailing list