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