Merge lp:~vila/bzr/389648-hook-calls-base into lp:~bzr/bzr/trunk-old

Proposed by Vincent Ladeuil
Status: Merged
Approved by: John A Meinel
Approved revision: no longer in the source branch.
Merge reported by: Vincent Ladeuil
Merged at revision: not available
Proposed branch: lp:~vila/bzr/389648-hook-calls-base
Merge into: lp:~bzr/bzr/trunk-old
Diff against target: 29287 lines
0 files modified
To merge this branch: bzr merge lp:~vila/bzr/389648-hook-calls-base
Reviewer Review Type Date Requested Status
John A Meinel Approve
Review via email: mp+14347@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Vincent Ladeuil (vila) wrote :

I finalized a patch proposed by bialix with a more focused test.
Like bialix tests it catches the two actual bugs in bzr but in addition,
it will catch any such bugs in plugins.

Revision history for this message
Alexander Belchenko (bialix) wrote :

Something wrong with the diff.

Revision history for this message
Aaron Bentley (abentley) wrote :

> Something wrong with the diff.

I think you want to propose against lp:~bzr-pqm/bzr/bzr.dev, not lp:~bzr/bzr/trunk, which is a 1.9-format mirror from before the 2a upgrade.

Revision history for this message
John A Meinel (jameinel) wrote :

As mentioned above, the target was wrong, it should be 'lp:bzr' which is ~bzr-pqm/bzr/bzr.dev, not ~bzr/bzr/trunk.

Anyway, I did the review locally. It was still a bit hard to follow, because a lot of 'formatting' updates. Stuff like:

-class TestHook(TestCase):
+class TestHook(tests.TestCase):

I wonder if this wouldn't be like the whitespace fixes, and we should have "one big patch" across the codebase to fix them, rather than getting them piecemeal. Then again, the same arguments apply for and against that were present for the whitespace updates...

Anyway, I think the basic fix here was:

1) Add
+ super(InfoHooks, self).__init__()

To a couple of the hook instances

2) Add
+ self.assertEqual("No hook name", new_hooks.get_hook_name(None))
To the tests to ensure that the internal dictionary is created and able to return a value for an unnamed hook.

Which seems just fine.

I should comment that using "super()" is not always correct anymore. To start with, it only matters when you have multiple inheritance. But even more importantly, python 2.6 'broke' super(...).__init__() if there are any arguments. Because object.__init__() no longer allows arguments. (So as near as I can tell, there is no way to safely __init__ a multiple inheritance structure that wants arguments passed as part of init. Unless maybe you do something like use a single abstract base class that all classes inherit from, that *doesn't* call super?)

Anyway, IMO super().__init__() was broken in 2.6, though certainly someone thought it was the right thing to do.

review: Approve
Revision history for this message
Vincent Ladeuil (vila) wrote :

>>>>> "jam" == John A Meinel <email address hidden> writes:

    jam> Review: Approve
    jam> As mentioned above, the target was wrong, it should be 'lp:bzr'
    jam> which is ~bzr-pqm/bzr/bzr.dev, not ~bzr/bzr/trunk.

Amazing, obviously I clicked the wrong button... no idea why nor
when... that wasn't intended anyway.

    jam> Anyway, I did the review locally. It was still a bit hard to
    jam> follow, because a lot of 'formatting' updates. Stuff like:

    jam> -class TestHook(TestCase):
    jam> +class TestHook(tests.TestCase):

Yeah :-(

In the past I've sent these trivial updates directly without
review, but then you commented that may be I should at least send
them so that people know about them even without waiting for an
approval.

I tried a middle term approach here, because I thought there was
only a few of them (but you call them 'a lot' :-)...

I don't mind fixing them as I encounter them, I don't want to
make the reviews harder than they have to either, but I'd like a
minimal effort workflow to get these fixes landed too.

    jam> I wonder if this wouldn't be like the whitespace fixes, and we
    jam> should have "one big patch" across the codebase to fix them,
    jam> rather than getting them piecemeal. Then again, the same
    jam> arguments apply for and against that were present for the
    jam> whitespace updates...

Yeah, exactly the same arguments. But again, I feel that I spend
less energy fixing them that discussing how to fix them all,
so...

    jam> Anyway, I think the basic fix here was:

You're right.

<snip/>

    jam> Which seems just fine.

Ok.

    jam> I should comment that using "super()" is not always
    jam> correct anymore.

    jam> To start with, it only matters when you have multiple
    jam> inheritance. But even more importantly, python 2.6
    jam> 'broke' super(...).__init__() if there are any
    jam> arguments.

I disagree. python-2.6 is just stricter and catch bogus calls.

    jam> Because object.__init__() no longer allows
    jam> arguments. (So as near as I can tell, there is no way to
    jam> safely __init__ a multiple inheritance structure that
    jam> wants arguments passed as part of init.

Yes there is, you handle arguments where they are expected and
you don't pass them where they are not.

The cases I had to fix when I addressed python-2.6 compatibility
weren't that complex once I understood what was going on.

And as I remember the only case that seemed controversial at the
time was indeed an abuse.

<snip/>

    jam> Anyway, IMO super().__init__() was broken in 2.6, though
    jam> certainly someone thought it was the right thing to do.

Well, it would be good to agree on that and decide whether we
want to use super() or not.

I refrained to fix all calls to Hooks.__init__ because I
considered it was slightly out of scope for this patch but only
slightly.

If you can provide examples in the actual code base where calling
super().__init__ will be bogus, I'll be happy to revise my
opinion.

        Vincent

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

...
>
> jam> I should comment that using "super()" is not always
> jam> correct anymore.
>
>
> jam> To start with, it only matters when you have multiple
> jam> inheritance. But even more importantly, python 2.6
> jam> 'broke' super(...).__init__() if there are any
> jam> arguments.
>
> I disagree. python-2.6 is just stricter and catch bogus calls.
>
> jam> Because object.__init__() no longer allows
> jam> arguments. (So as near as I can tell, there is no way to
> jam> safely __init__ a multiple inheritance structure that
> jam> wants arguments passed as part of init.
>
> Yes there is, you handle arguments where they are expected and
> you don't pass them where they are not.
>
> The cases I had to fix when I addressed python-2.6 compatibility
> weren't that complex once I understood what was going on.
>
> And as I remember the only case that seemed controversial at the
> time was indeed an abuse.

By the way, don't block landing this on us resolving super() issues. I'm
moving the super() discussion over to the regular mailing list.

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkr10xMACgkQJdeBCYSNAANU8QCdGUx5dQkzaNrZV3f3p0SAQNj5
q1MAoM5oqOsF0jXtbfuy7hNYgOC1kV13
=uKqH
-----END PGP SIGNATURE-----

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

I'm trying to split up a few discussion points into different emails.
Sorry if things get a bit broken. Thunderbird isn't as nice as 'bzr
shelve' :)

Vincent Ladeuil wrote:
>>>>>> "jam" == John A Meinel <email address hidden> writes:
>
> jam> Review: Approve
> jam> As mentioned above, the target was wrong, it should be 'lp:bzr'
> jam> which is ~bzr-pqm/bzr/bzr.dev, not ~bzr/bzr/trunk.
>
> Amazing, obviously I clicked the wrong button... no idea why nor
> when... that wasn't intended anyway.
>
> jam> Anyway, I did the review locally. It was still a bit hard to
> jam> follow, because a lot of 'formatting' updates. Stuff like:
>
> jam> -class TestHook(TestCase):
> jam> +class TestHook(tests.TestCase):
>
> Yeah :-(
>
> In the past I've sent these trivial updates directly without
> review, but then you commented that may be I should at least send
> them so that people know about them even without waiting for an
> approval.
>
> I tried a middle term approach here, because I thought there was
> only a few of them (but you call them 'a lot' :-)...

Your fix was about 2 lines long, and it was about 10 lines of
'tests.TestCase' changes.

so not many, but *more* of those trivial changes than there were actual
content changes.

>
> I don't mind fixing them as I encounter them, I don't want to
> make the reviews harder than they have to either, but I'd like a
> minimal effort workflow to get these fixes landed too.
>
> jam> I wonder if this wouldn't be like the whitespace fixes, and we
> jam> should have "one big patch" across the codebase to fix them,
> jam> rather than getting them piecemeal. Then again, the same
> jam> arguments apply for and against that were present for the
> jam> whitespace updates...
>
> Yeah, exactly the same arguments. But again, I feel that I spend
> less energy fixing them that discussing how to fix them all,
> so...

Style patches are always a bit contentious. Far to easy for people to
bikeshed on. Which is why we say "PEP 8" but even that doesn't cover all
the cases of things you want to do.

Similarly stripping the whitespace from all files is trivially easy to
do. (We now have about 300? files that have trailing whitespace again.)

I'd like to say just land trivial cleanups. But on the flip side, your
'trivial cleanups' may cause merge conflicts in any pending work people
are doing. However, we don't want to hold cleaning up the code hostage
for work that may land in the future either.

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.9 (Cygwin)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iEYEARECAAYFAkr108YACgkQJdeBCYSNAANHTwCgxsrLQOM7+0sySJtYKRW2NSaI
QooAnRk6sP/DUSgjDQjf2+n8NDgKzU7A
=OUbh
-----END PGP SIGNATURE-----

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file '.bzrignore'
2--- .bzrignore 2009-07-31 19:56:19 +0000
3+++ .bzrignore 2009-11-03 09:40:55 +0000
4@@ -5,10 +5,21 @@
5 ./.bzr.log
6 # Generated files
7 CHANGELOG
8+# generated documents
9 bzr.1
10 ./doc/*.html
11-./doc/_build/
12+./doc/*/_build/
13+./doc/*/Makefile
14+./doc/*/make.bat
15 ./tutorial.html
16+./build_doc_website
17+./html_docs
18+./pretty_docs
19+./api
20+./doc/**/*.html
21+./doc/developers/performance.png
22+./doc/en/user-reference/*.txt
23+./doc/en/release-notes/*.txt
24 BRANCH-INFO
25 # setup.py working directory
26 ./build
27@@ -35,11 +46,7 @@
28 ./dist
29 # performance history data file
30 ./.perf_history
31-./html_docs
32-./pretty_docs
33-./api
34-doc/**/*.html
35-doc/developers/performance.png
36+# Pyrex
37 bzrlib/_annotator_pyx.c
38 bzrlib/_bencode_pyx.c
39 bzrlib/_btree_serializer_pyx.c
40@@ -51,16 +58,12 @@
41 bzrlib/_known_graph_pyx.c
42 bzrlib/_readdir_pyx.c
43 bzrlib/_rio_pyx.c
44+bzrlib/_simple_set_pyx.c
45+bzrlib/_simple_set_pyx.h
46+bzrlib/_simple_set_pyx_api.h
47 bzrlib/_walkdirs_win32.c
48-doc/en/release-notes/NEWS.txt
49-doc/en/developer-guide/HACKING.txt
50-doc/en/user-reference/bzr_man.txt
51 # built extension modules
52 bzrlib/_*.dll
53 bzrlib/_*.so
54 bzrlib/_*.pyd
55-# generated help topics
56-doc/en/user-reference/*.txt
57-./doc/en/user-guide/latex_prepared
58-./doc/en/user-guide/*.pdf
59 ./.ccache
60
61=== modified file 'Makefile'
62--- Makefile 2009-08-27 00:53:27 +0000
63+++ Makefile 2009-11-03 09:40:55 +0000
64@@ -75,44 +75,161 @@
65 # these are treated as phony so they'll always be rebuilt - it's pretty quick
66 .PHONY: TAGS tags
67
68+
69 ### Documentation ###
70
71-# set PRETTY to get docs that look like the Bazaar web site
72-ifdef PRETTY
73-rst2html := $(PYTHON) tools/rst2prettyhtml.py doc/bazaar-vcs.org.kid
74-else
75-rst2html := $(PYTHON) tools/rst2html.py --link-stylesheet --footnote-references=superscript --halt=warning
76-endif
77+# Default to plain documentation for maximum backwards compatibility.
78+# (Post 2.0, the defaults will most likely be Sphinx-style instead.)
79+
80+docs: docs-plain
81+
82+clean-docs: clean-plain
83+
84+html-docs: html-plain
85+
86+
87+### Man-page Documentation ###
88+
89+MAN_DEPENDENCIES = bzrlib/builtins.py \
90+ $(wildcard bzrlib/*.py) \
91+ $(wildcard bzrlib/*/*.py) \
92+ tools/generate_docs.py \
93+ $(wildcard $(addsuffix /*.txt, bzrlib/help_topics/en))
94+
95+MAN_PAGES = man1/bzr.1
96+man1/bzr.1: $(MAN_DEPENDENCIES)
97+ $(PYTHON) tools/generate_docs.py -o $@ man
98+
99+
100+### Sphinx-style Documentation ###
101+
102+# Build the documentation. To keep the dependencies down to a minimum
103+# for distro packagers, we only build the html documentation by default.
104+# Sphinx 0.6 or later is preferred for the best rendering, though
105+# Sphinx 0.4 or later should work. See http://sphinx.pocoo.org/index.html
106+# for installation instructions.
107+docs-sphinx: html-sphinx
108+
109+# Clean out generated documentation
110+clean-sphinx:
111+ cd doc/en && make clean
112+ cd doc/es && make clean
113+ cd doc/ru && make clean
114+ cd doc/developers && make clean
115+
116+SPHINX_DEPENDENCIES = \
117+ doc/en/release-notes/index.txt \
118+ doc/en/user-reference/index.txt \
119+ doc/es/Makefile \
120+ doc/es/make.bat \
121+ doc/ru/Makefile \
122+ doc/ru/make.bat \
123+ doc/developers/Makefile \
124+ doc/developers/make.bat
125+
126+doc/en/user-reference/index.txt: $(MAN_DEPENDENCIES)
127+ $(PYTHON) tools/generate_docs.py -o $@ rstx
128+
129+doc/en/release-notes/index.txt: NEWS tools/generate_release_notes.py
130+ $(PYTHON) tools/generate_release_notes.py NEWS $@
131+
132+doc/%/Makefile: doc/en/Makefile
133+ $(PYTHON) -c "import shutil; shutil.copyfile('$<', '$@')"
134+
135+doc/%/make.bat: doc/en/make.bat
136+ $(PYTHON) -c "import shutil; shutil.copyfile('$<', '$@')"
137+
138+# Build the html docs using Sphinx.
139+html-sphinx: $(SPHINX_DEPENDENCIES)
140+ cd doc/en && make html
141+ cd doc/es && make html
142+ cd doc/ru && make html
143+ cd doc/developers && make html
144+
145+# Build the PDF docs using Sphinx. This requires numerous LaTeX
146+# packages. See http://sphinx.pocoo.org/builders.html for details.
147+# Note: We don't currently build PDFs for the Russian docs because
148+# they require additional packages to be installed (to handle
149+# Russian hyphenation rules, etc.)
150+pdf-sphinx: $(SPHINX_DEPENDENCIES)
151+ cd doc/en && make latex
152+ cd doc/es && make latex
153+ cd doc/developers && make latex
154+ cd doc/en/_build/latex && make all-pdf
155+ cd doc/es/_build/latex && make all-pdf
156+ cd doc/developers/_build/latex && make all-pdf
157+
158+# Build the CHM (Windows Help) docs using Sphinx.
159+# Note: HtmlHelp Workshop needs to be used on the generated hhp files
160+# to generate the final chm files.
161+chm-sphinx: $(SPHINX_DEPENDENCIES)
162+ cd doc/en && make htmlhelp
163+ cd doc/es && make htmlhelp
164+ cd doc/ru && make htmlhelp
165+ cd doc/developers && make htmlhelp
166+
167+
168+### Documentation Website ###
169+
170+# Where to build the website
171+DOC_WEBSITE_BUILD = build_doc_website
172+
173+# Build and package docs into a website, complete with downloads.
174+doc-website: html-sphinx pdf-sphinx
175+ $(PYTHON) tools/package_docs.py doc/en $(DOC_WEBSITE_BUILD)
176+ $(PYTHON) tools/package_docs.py doc/es $(DOC_WEBSITE_BUILD)
177+ $(PYTHON) tools/package_docs.py doc/ru $(DOC_WEBSITE_BUILD)
178+ $(PYTHON) tools/package_docs.py doc/developers $(DOC_WEBSITE_BUILD)
179+
180+
181+### Plain Documentation ###
182+
183+# While Sphinx is the preferred tool for building documentation, we still
184+# support our "plain" html documentation so that Sphinx is not a hard
185+# dependency for packagers on older platforms.
186+
187+rst2html = $(PYTHON) tools/rst2html.py --link-stylesheet --footnote-references=superscript --halt=warning
188
189 # translate txt docs to html
190-derived_txt_files := \
191+derived_txt_files = \
192 doc/en/user-reference/bzr_man.txt \
193 doc/en/release-notes/NEWS.txt
194-txt_files := \
195+txt_all = \
196 doc/en/tutorials/tutorial.txt \
197 doc/en/tutorials/using_bazaar_with_launchpad.txt \
198 doc/en/tutorials/centralized_workflow.txt \
199+ $(wildcard doc/es/tutorials/*.txt) \
200 $(wildcard doc/ru/tutorials/*.txt) \
201 $(wildcard doc/*/mini-tutorial/index.txt) \
202- $(wildcard doc/*/user-guide/index.txt) \
203+ $(wildcard doc/*/user-guide/index-plain.txt) \
204+ $(wildcard doc/es/guia-usario/*.txt) \
205 $(derived_txt_files) \
206- doc/en/developer-guide/HACKING.txt \
207 doc/en/upgrade-guide/index.txt \
208- $(wildcard doc/es/guia-usario/*.txt) \
209- doc/es/mini-tutorial/index.txt \
210 doc/index.txt \
211 $(wildcard doc/index.*.txt)
212-non_txt_files := \
213+txt_nohtml = \
214+ doc/en/user-guide/index.txt \
215+ doc/es/user-guide/index.txt \
216+ doc/ru/user-guide/index.txt
217+txt_files = $(filter-out $(txt_nohtml), $(txt_all))
218+htm_files = $(patsubst %.txt, %.html, $(txt_files))
219+
220+non_txt_files = \
221 doc/default.css \
222- $(wildcard doc/*/quick-reference/bzr-quick-reference.svg) \
223- $(wildcard doc/*/quick-reference/bzr-quick-reference.png) \
224- $(wildcard doc/*/quick-reference/bzr-quick-reference.pdf) \
225+ $(wildcard doc/*/bzr-en-quick-reference.svg) \
226+ $(wildcard doc/*/bzr-en-quick-reference.png) \
227+ $(wildcard doc/*/bzr-en-quick-reference.pdf) \
228+ $(wildcard doc/*/bzr-es-quick-reference.svg) \
229+ $(wildcard doc/*/bzr-es-quick-reference.png) \
230+ $(wildcard doc/*/bzr-es-quick-reference.pdf) \
231+ $(wildcard doc/*/bzr-ru-quick-reference.svg) \
232+ $(wildcard doc/*/bzr-ru-quick-reference.png) \
233+ $(wildcard doc/*/bzr-ru-quick-reference.pdf) \
234 $(wildcard doc/*/user-guide/images/*.png)
235-htm_files := $(patsubst %.txt, %.html, $(txt_files))
236
237 # doc/developers/*.txt files that should *not* be individually
238 # converted to HTML
239-dev_txt_nohtml := \
240+dev_txt_nohtml = \
241 doc/developers/add.txt \
242 doc/developers/annotate.txt \
243 doc/developers/bundle-creation.txt \
244@@ -120,46 +237,37 @@
245 doc/developers/diff.txt \
246 doc/developers/directory-fingerprints.txt \
247 doc/developers/gc.txt \
248+ doc/developers/implementation-notes.txt \
249 doc/developers/incremental-push-pull.txt \
250+ doc/developers/index.txt \
251 doc/developers/initial-push-pull.txt \
252 doc/developers/merge-scaling.txt \
253+ doc/developers/miscellaneous-notes.txt \
254 doc/developers/missing.txt \
255 doc/developers/performance-roadmap-rationale.txt \
256 doc/developers/performance-use-case-analysis.txt \
257 doc/developers/planned-change-integration.txt \
258 doc/developers/planned-performance-changes.txt \
259+ doc/developers/plans.txt \
260+ doc/developers/process.txt \
261 doc/developers/revert.txt \
262+ doc/developers/specifications.txt \
263 doc/developers/status.txt \
264 doc/developers/uncommit.txt
265
266-dev_txt_all := $(wildcard $(addsuffix /*.txt, doc/developers))
267-dev_txt_files := $(filter-out $(dev_txt_nohtml), $(dev_txt_all))
268-dev_htm_files := $(patsubst %.txt, %.html, $(dev_txt_files))
269-
270-doc/%/user-guide/index.html: $(wildcard $(addsuffix /*.txt, doc/%/user-guide))
271- $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@
272-
273-# Set the paper size for PDF files.
274-# Options: 'a4' (ISO A4 size), 'letter' (US Letter size)
275-PAPERSIZE = a4
276-# TODO: Add generation for Russian PDF
277-PDF_DOCS := doc/en/user-guide/user-guide.$(PAPERSIZE).pdf
278-
279-# Copy and modify the RST sources, and convert SVG images to PDF
280-# files for use a images in the LaTeX-generated PDF.
281-# Then generate the PDF output from the modified RST sources.
282-doc/en/user-guide/user-guide.$(PAPERSIZE).pdf: $(wildcard $(addsuffix /*.txt, doc/en/user-guide))
283- mkdir -p doc/en/user-guide/latex_prepared
284- $(PYTHON) tools/prepare_for_latex.py \
285- --out-dir=doc/en/user-guide/latex_prepared \
286- --in-dir=doc/en/user-guide
287- cd doc/en/user-guide/latex_prepared && \
288- $(PYTHON) ../../../../tools/rst2pdf.py \
289- --documentoptions=10pt,$(PAPERSIZE)paper \
290- --input-encoding=UTF-8:strict --output-encoding=UTF-8:strict \
291- --strict --title="Bazaar User Guide" \
292- index.txt ../user-guide.$(PAPERSIZE).pdf
293-
294+dev_txt_all = $(wildcard $(addsuffix /*.txt, doc/developers))
295+dev_txt_files = $(filter-out $(dev_txt_nohtml), $(dev_txt_all))
296+dev_htm_files = $(patsubst %.txt, %.html, $(dev_txt_files))
297+
298+doc/en/user-guide/index-plain.html: $(wildcard $(addsuffix /*.txt, doc/en/user-guide))
299+ $(rst2html) --stylesheet=../../default.css $(dir $@)index-plain.txt $@
300+
301+#doc/es/user-guide/index.html: $(wildcard $(addsuffix /*.txt, doc/es/user-guide))
302+# $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@
303+#
304+#doc/ru/user-guide/index.html: $(wildcard $(addsuffix /*.txt, doc/ru/user-guide))
305+# $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@
306+#
307 doc/developers/%.html: doc/developers/%.txt
308 $(rst2html) --stylesheet=../default.css $< $@
309
310@@ -172,55 +280,42 @@
311 %.html: %.txt
312 $(rst2html) --stylesheet=../../default.css $< $@
313
314-MAN_DEPENDENCIES = bzrlib/builtins.py \
315- $(wildcard bzrlib/*.py) \
316- $(wildcard bzrlib/*/*.py) \
317- tools/generate_docs.py \
318- $(wildcard $(addsuffix /*.txt, bzrlib/help_topics/en))
319-
320 doc/en/user-reference/bzr_man.txt: $(MAN_DEPENDENCIES)
321 $(PYTHON) tools/generate_docs.py -o $@ rstx
322
323 doc/en/release-notes/NEWS.txt: NEWS
324 $(PYTHON) -c "import shutil; shutil.copyfile('$<', '$@')"
325
326-MAN_PAGES = man1/bzr.1
327-man1/bzr.1: $(MAN_DEPENDENCIES)
328- $(PYTHON) tools/generate_docs.py -o $@ man
329-
330 upgrade_guide_dependencies = $(wildcard $(addsuffix /*.txt, doc/en/upgrade-guide))
331
332 doc/en/upgrade-guide/index.html: $(upgrade_guide_dependencies)
333 $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@
334
335-# build a png of our performance task list
336-#
337-# this is no longer built by default; you can build it if you want to look at it
338-doc/developers/performance.png: doc/developers/performance.dot
339- @echo Generating $@
340- @dot -Tpng $< -o$@ || echo "Dot not installed; skipping generation of $@"
341-
342 derived_web_docs = $(htm_files) $(dev_htm_files)
343 WEB_DOCS = $(derived_web_docs) $(non_txt_files)
344 ALL_DOCS = $(derived_web_docs) $(MAN_PAGES)
345
346 # the main target to build all the docs
347-docs: $(ALL_DOCS)
348+docs-plain: $(ALL_DOCS)
349
350 # produce a tree containing just the final docs, ready for uploading to the web
351-HTMLDIR := html_docs
352-html-docs: docs
353+HTMLDIR = html_docs
354+html-plain: docs-plain
355 $(PYTHON) tools/win32/ostools.py copytree $(WEB_DOCS) $(HTMLDIR)
356
357-# Produce PDF documents. Requires pdfLaTeX, rubber, and Inkscape.
358-pdf-docs: $(PDF_DOCS)
359-
360 # clean produced docs
361-clean-docs:
362+clean-plain:
363 $(PYTHON) tools/win32/ostools.py remove $(ALL_DOCS) \
364 $(HTMLDIR) $(derived_txt_files)
365- rm -f doc/*/user-guide/*.pdf
366- rm -rf doc/*/user-guide/latex_prepared
367+
368+
369+### Miscellaneous Documentation Targets ###
370+
371+# build a png of our performance task list
372+# this is no longer built by default; you can build it if you want to look at it
373+doc/developers/performance.png: doc/developers/performance.dot
374+ @echo Generating $@
375+ @dot -Tpng $< -o$@ || echo "Dot not installed; skipping generation of $@"
376
377
378 ### Windows Support ###
379@@ -230,7 +325,7 @@
380 # These are files that need to be copied into the build location to boostrap
381 # the build process.
382 # Note that the path is relative to tools/win32
383-BUILDOUT_FILES := buildout.cfg \
384+BUILDOUT_FILES = buildout.cfg \
385 buildout-templates/bin/build-installer.bat.in \
386 ostools.py bootstrap.py
387
388@@ -296,9 +391,12 @@
389 $(PYTHON) tools/win32/ostools.py remove bzr-*win32.exe
390 $(PYTHON) tools/win32/ostools.py remove dist
391
392+
393+### Packaging Targets ###
394+
395 .PHONY: dist dist-upload-escudero check-dist-tarball
396
397-# build a distribution tarball and zip file.
398+# build a distribution source tarball
399 #
400 # this method of copying the pyrex generated files is a bit ugly; it would be
401 # nicer to generate it from distutils.
402@@ -308,15 +406,12 @@
403 expbasedir=`mktemp -t -d tmp_bzr_dist.XXXXXXXXXX` && \
404 expdir=$$expbasedir/bzr-$$version && \
405 tarball=$$PWD/../bzr-$$version.tar.gz && \
406- zipball=$$PWD/../bzr-$$version.zip && \
407 $(MAKE) clean && \
408 $(MAKE) && \
409 bzr export $$expdir && \
410- cp bzrlib/*.c $$expdir/bzrlib/. && \
411+ cp bzrlib/*.c bzrlib/*.h $$expdir/bzrlib/. && \
412 tar cfz $$tarball -C $$expbasedir bzr-$$version && \
413- (cd $$expbasedir && zip -r $$zipball bzr-$$version) && \
414 gpg --detach-sign $$tarball && \
415- gpg --detach-sign $$zipball && \
416 rm -rf $$expbasedir
417
418 # run all tests in a previously built tarball
419@@ -334,15 +429,10 @@
420 dist-upload-escudero:
421 version=`./bzr version --short` && \
422 tarball=../bzr-$$version.tar.gz && \
423- zipball=../bzr-$$version.zip && \
424- scp $$zipball $$zipball.sig $$tarball $$tarball.sig \
425+ scp $$tarball $$tarball.sig \
426 escudero.ubuntu.com:/srv/bazaar.canonical.com/www/releases/src \
427 && \
428 echo verifying over http... && \
429- curl http://bazaar-vcs.org/releases/src/bzr-$$version.zip \
430- | diff -s - $$zipball && \
431- curl http://bazaar-vcs.org/releases/src/bzr-$$version.zip.sig \
432- | diff -s - $$zipball.sig
433 curl http://bazaar-vcs.org/releases/src/bzr-$$version.tar.gz \
434 | diff -s - $$tarball && \
435 curl http://bazaar-vcs.org/releases/src/bzr-$$version.tar.gz.sig \
436
437=== modified file 'NEWS'
438--- NEWS 2009-09-02 18:07:58 +0000
439+++ NEWS 2009-11-03 09:40:55 +0000
440@@ -2,44 +2,409 @@
441 Bazaar Release Notes
442 ####################
443
444-
445 .. contents:: List of Releases
446 :depth: 1
447
448-In Development
449-##############
450-
451-Compatibility Breaks
452-********************
453-
454-New Features
455-************
456-
457-Bug Fixes
458-*********
459-
460-* ``bzr check`` in pack-0.92, 1.6 and 1.9 format repositories will no
461- longer report incorrect errors about ``Missing inventory ('TREE_ROOT', ...)``
462- (Robert Collins, #416732)
463+
464+bzr 2.1.0b3 (not released yet)
465+##############################
466+
467+:Codename:
468+:2.1.0b3: ???
469+
470+Compatibility Breaks
471+********************
472+
473+New Features
474+************
475+
476+Bug Fixes
477+*********
478+
479+* Hooks daughter classes should always call the base constructor.
480+ (Alexander Belchenko, Vincent Ladeuil, #389648)
481+
482+Improvements
483+************
484+
485+Documentation
486+*************
487+
488+API Changes
489+***********
490+
491+Internals
492+*********
493+
494+Testing
495+*******
496+
497+* KnownFailure is now signalled to ``ExtendedTestResult`` using the same
498+ method that Python 2.7 uses - ``addExpectedFailure``. (Robert Collins)
499+
500+* TestNotApplicable is now handled within the TestCase.run method rather
501+ than being looked for within ``ExtendedTestResult.addError``. This
502+ provides better handling with other ``TestResult`` objects, degrading to
503+ sucess rather than error. (Robert Collins)
504+
505+* The private method ``_testConcluded`` on ``ExtendedTestResult`` has been
506+ removed - it was empty and unused. (Robert Collins)
507+
508+* UnavailableFeature is now handled within the TestCase.run method rather
509+ than being looked for within addError. If the Result object does not
510+ have an addNotSupported method, addSkip is attempted instead, and
511+ failing that addSuccess. (Robert Collins)
512+
513+* When a TestResult does not have an addSkip method, skipped tests are now
514+ reported as successful tests, rather than as errors. This change is
515+ to make it possible to get a clean test run with a less capable
516+ TestResult. (Robert Collins)
517+
518+
519+
520+bzr 2.0.3 (not released yet)
521+############################
522+
523+:Codename: template
524+:2.0.3: ???
525+
526+Compatibility Breaks
527+********************
528+
529+New Features
530+************
531+
532+Bug Fixes
533+*********
534+
535+Improvements
536+************
537+
538+Documentation
539+*************
540+
541+API Changes
542+***********
543+
544+Internals
545+*********
546+
547+Testing
548+*******
549+
550+
551+bzr 2.1.0b2
552+###########
553+
554+:Codename: a load off my mind
555+:2.1.0b2: 2009-11-02
556+
557+This is our second feature-filled release since 2.0, pushing us down the
558+path to a 2.1.0. Once again, all bugfixes in 2.0.2 are present in 2.1.0b2.
559+
560+Key highlights in this release are: improved handling of
561+failures-during-cleanup for commit, fixing a long-standing bug with
562+``bzr+http`` and shared repositories, and a new StaticTuple datatype,
563+allowing us to reduce memory consumption (50%) and garbage collector
564+overhead (40% faster) for many operations.
565+
566+Bug Fixes
567+*********
568+
569+* ``bzr+http`` servers no longer give spurious jail break errors when
570+ serving branches inside a shared repository. (Andrew Bennetts, #348308)
571+
572+* Errors during commit are handled more robustly so that knock-on errors
573+ are less likely to occur, and will not obscure the original error if
574+ they do occur. This fixes some causes of ``TooManyConcurrentRequests``
575+ and similar errors. (Andrew Bennetts, #429747, #243391)
576+
577+* TreeTransform.adjust_path updates the limbo paths of descendants of adjusted
578+ files. (Aaron Bentley)
579+
580+* Unicode paths are now handled correctly and consistently by the smart
581+ server. (Andrew Bennetts, Michael Hudson, #458762)
582+
583+Improvements
584+************
585+
586+* When reading index files, we now use a ``StaticTuple`` rather than a
587+ plain ``tuple`` object. This generally gives a 20% decrease in peak
588+ memory, and can give a performance boost up to 40% on large projects.
589+ (John Arbash Meinel)
590+
591+* Peak memory under certain operations has been reduced significantly.
592+ (eg, 'bzr branch launchpad standalone' is cut in half)
593+ (John Arbash Meinel)
594+
595+Documentation
596+*************
597+
598+* Filtered views user documentation upgraded to refer to format 2a
599+ instead of pre-2.0 formats. (Ian Clatworthy)
600+
601+API Changes
602+***********
603+
604+* Remove deprecated ``CLIUIFactory``. (Martin Pool)
605+
606+* ``UIFactory`` now has new ``show_error``, ``show_message`` and
607+ ``show_warning`` methods, which can be hooked by non-text UIs.
608+ (Martin Pool)
609+
610+Internals
611+*********
612+
613+* Added ``bzrlib._simple_set_pyx``. This is a hybrid between a Set and a
614+ Dict (it only holds keys, but you can lookup the object located at a
615+ given key). It has significantly reduced memory consumption versus the
616+ builtin objects (1/2 the size of Set, 1/3rd the size of Dict). This is
617+ used as the interning structure for StaticTuple objects.
618+ (John Arbash Meinel)
619+
620+* ``bzrlib._static_tuple_c.StaticTuple`` is now available and used by
621+ the btree index parser and the chk map parser. This class functions
622+ similarly to ``tuple`` objects. However, it can only point to a limited
623+ collection of types. (Currently StaticTuple, str, unicode, None, bool,
624+ int, long, float, but not subclasses). This allows us to remove it from
625+ the garbage collector (it cannot be in a cycle), it also allows us to
626+ intern the objects. In testing, this can reduce peak memory by 20-40%,
627+ and significantly improve performance by removing objects from being
628+ inspected by the garbage collector. (John Arbash Meinel)
629+
630+* ``GroupCompressBlock._ensure_content()`` will now release the
631+ ``zlib.decompressobj()`` when the first request is for all of the
632+ content. (Previously it would only be released if you made a request for
633+ part of the content, and then all of it later.) This turns out to be a
634+ significant memory savings, as a ``zstream`` carries around approx 260kB
635+ of internal state and buffers. (For branching bzr.dev this drops peak
636+ memory from 382MB => 345MB.) (John Arbash Meinel)
637+
638+* When streaming content between ``2a`` format repositories, we now clear
639+ caches from earlier versioned files. (So 'revisions' is cleared when we
640+ start reading 'inventories', etc.) This can have a significant impact on
641+ peak memory for initial copies (~200MB). (John Arbash Meinel)
642+
643+
644+bzr 2.0.2
645+#########
646+
647+:Codename: after the scare
648+:2.0.2: 2009-11-02
649+
650+The second in our "let's keep the stable bugfixes flowing" series. As
651+expected this has a few (~9) bugfixes relative to 2.0.1, and no major api
652+changes or features.
653+
654+Bug Fixes
655+*********
656+
657+* Avoid "NoneType has no attribute st_mode" error when files disappear
658+ from a directory while it's being read. (Martin Pool, #446033)
659+
660+* Content filters are now applied correctly after revert.
661+ (Ian Clatworthy)
662+
663+* Diff parsing handles "Binary files differ" hunks. (Aaron Bentley, #436325)
664+
665+* Fetching from stacked pre-2a repository via a smart server no longer
666+ fails intermittently with "second push failed to complete".
667+ (Andrew Bennetts, #437626)
668+
669+* Fix typos left after test_selftest refactoring.
670+ (Vincent Ladeuil, Matt Nordhoff, #461149)
671+
672+* Fixed ``ObjectNotLocked`` errors during ``bzr log -r NNN somefile``.
673+ (Andrew Bennetts, #445171)
674+
675+* PreviewTree file names are not limited by the encoding of the temp
676+ directory's filesystem. (Aaron Bentley, #436794)
677+
678+Improvements
679+************
680+
681+* ``bzr log`` now read-locks branches exactly once, so makes better use of
682+ data caches. (Andrew Bennetts)
683+
684+Documentation
685+*************
686+
687+* Filtered views user documentation upgraded to refer to format 2a
688+ instead of pre-2.0 formats. (Ian Clatworthy)
689+
690+
691+bzr 2.1.0b1
692+###########
693+
694+:Codename: While the cat is away
695+:2.1.0b1: 2009-10-14
696+
697+This is the first development release in the new split "stable" and
698+"development" series. As such, the release is a snapshot of bzr.dev
699+without creating a release candidate first. This release includes a
700+fair amount of internal changes, with deprecated code being removed,
701+and several new feature developments. People looking for a stable code
702+base with only bugfixes should focus on the 2.0.1 release. All bugfixes
703+present in 2.0.1 are present in 2.1.0b1.
704+
705+Highlights include support for ``bzr+ssh://host/~/homedir`` style urls,
706+finer control over the plugin search path via extended BZR_PLUGIN_PATH
707+syntax, visible warnings when extension modules fail to load, and improved
708+error handling during unlocking.
709+
710+
711+New Features
712+************
713+
714+* Bazaar can now send mail through Apple OS X Mail.app.
715+ (Brian de Alwis)
716+
717+* ``bzr+ssh`` and ``bzr`` paths can now be relative to home directories
718+ specified in the URL. Paths starting with a path segment of ``~`` are
719+ relative to the home directory of the user running the server, and paths
720+ starting with ``~user`` are relative to the home directory of the named
721+ user. For example, for a user "bob" with a home directory of
722+ ``/home/bob``, these URLs are all equivalent:
723+
724+ * ``bzr+ssh://bob@host/~/repo``
725+ * ``bzr+ssh://bob@host/~bob/repo``
726+ * ``bzr+ssh://bob@host/home/bob/repo``
727+
728+ If ``bzr serve`` was invoked with a ``--directory`` argument, then no
729+ home directories outside that directory will be accessible via this
730+ method.
731+
732+ This is a feature of ``bzr serve``, so pre-2.1 clients will
733+ automatically benefit from this feature when ``bzr`` on the server is
734+ upgraded. (Andrew Bennetts, #109143)
735+
736+* Extensions can now be compiled if either Cython or Pyrex is available.
737+ Currently Pyrex is preferred, but that may change in the future.
738+ (Arkanes)
739+
740+* Give more control on BZR_PLUGIN_PATH by providing a way to refer to or
741+ disable the user, site and core plugin directories.
742+ (Vincent Ladeuil, #412930, #316192, #145612)
743+
744+Bug Fixes
745+*********
746+
747+* Bazaar's native protocol code now correctly handles EINTR, which most
748+ noticeably occurs if you break in to the debugger while connected to a
749+ bzr+ssh server. You can now can continue from the debugger (by typing
750+ 'c') and the process continues. However, note that pressing C-\ in the
751+ shell may still kill the SSH process, which is bug 162509, so you must
752+ sent a signal to the bzr process specifically, for example by typing
753+ ``kill -QUIT PID`` in another shell. (Martin Pool, #341535)
754+
755+* ``bzr add`` in a tree that has files with ``\r`` or ``\n`` in the
756+ filename will issue a warning and skip over those files.
757+ (Robert Collins, #3918)
758+
759+* ``bzr dpush`` now aborts if uncommitted changes (including pending merges)
760+ are present in the working tree. The configuration option ``dpush_strict``
761+ can be used to set the default for this behavior.
762+ (Vincent Ladeuil, #438158)
763+
764+* ``bzr merge`` and ``bzr remove-tree`` now requires --force if pending
765+ merges are present in the working tree.
766+ (Vincent Ladeuil, #426344)
767+
768+* Clearer message when Bazaar runs out of memory, instead of a ``MemoryError``
769+ traceback. (Martin Pool, #109115)
770+
771+* Don't give a warning on Windows when failing to import ``_readdir_pyx``
772+ as it is never built. (John Arbash Meinel, #430645)
773
774 * Don't restrict the command name used to run the test suite.
775 (Vincent Ladeuil, #419950)
776
777+* ftp transports were built differently when the kerberos python module was
778+ present leading to obscure failures related to ASCII/BINARY modes.
779+ (Vincent Ladeuil, #443041)
780+
781+* Network streams now decode adjacent records of the same type into a
782+ single stream, reducing layering churn. (Robert Collins)
783+
784+* PreviewTree behaves correctly when get_file_mtime is invoked on an unmodified
785+ file. (Aaron Bentley, #251532)
786+
787+* Registry objects should not use iteritems() when asked to use items().
788+ (Vincent Ladeuil, #430510)
789+
790+* Weave based repositories couldn't be cloned when committers were using
791+ domains or user ids embedding '.sig'. Now they can.
792+ (Matthew Fuller, Vincent Ladeuil, #430868)
793+
794 Improvements
795 ************
796
797+* Revision specifiers can now be given in a more DWIM form, without
798+ needing explicit prefixes for specifiers like tags or revision id's.
799+ See ``bzr help revisionspec`` for full details. (Matthew Fuller)
800+
801+* Bazaar gives a warning before exiting, and writes into ``.bzr.log``, if
802+ compiled extensions can't be loaded. This typically indicates a
803+ packaging or installation problem. In this case Bazaar will keep
804+ running using pure-Python versions, but this may be substantially
805+ slower. The warning can be disabled by setting
806+ ``ignore_missing_extensions = True`` in ``bazaar.conf``.
807+ See also <https://answers.launchpad.net/bzr/+faq/703>.
808+ (Martin Pool, #406113, #430529)
809+
810+* Secondary errors that occur during Branch.unlock and Repository.unlock
811+ no longer obscure the original error. These methods now use a new
812+ decorator, ``only_raises``. This fixes many causes of
813+ ``TooManyConcurrentRequests`` and similar errors.
814+ (Andrew Bennetts, #429747)
815+
816 Documentation
817 *************
818
819+* Describe the new shell-like test feature. (Vincent Ladeuil)
820+
821+* Help on hooks no longer says 'Not deprecated' for hooks that are
822+ currently supported. (Ian Clatworthy, #422415)
823+
824 API Changes
825 ***********
826
827+* ``bzrlib.user_encoding`` has been removed; use
828+ ``bzrlib.osutils.get_user_encoding`` instead. (Martin Pool)
829+
830 * ``bzrlib.tests`` now uses ``stopTestRun`` for its ``TestResult``
831 subclasses - the same as python's unittest module. (Robert Collins)
832+
833+* ``diff._get_trees_to_diff`` has been renamed to
834+ ``diff.get_trees_and_branches_to_diff``. It is now a public API, and it
835+ returns the old and new branches. (Gary van der Merwe)
836+
837+* ``bzrlib.trace.log_error``, ``error`` and ``info`` have been deprecated.
838+ (Martin Pool)
839+
840+* ``MutableTree.has_changes()`` does not require a tree parameter anymore. It
841+ now defaults to comparing to the basis tree. It now checks for pending
842+ merges too. ``Merger.check_basis`` has been deprecated and replaced by the
843+ corresponding has_changes() calls. ``Merge.compare_basis``,
844+ ``Merger.file_revisions`` and ``Merger.ensure_revision_trees`` have also
845+ been deprecated.
846+ (Vincent Ladeuil, #440631)
847+
848+* ``ProgressTask.note`` is deprecated.
849+ (Martin Pool)
850
851 Internals
852 *********
853
854+* Added ``-Drelock`` debug flag. It will ``note`` a message every time a
855+ repository or branch object is unlocked then relocked the same way.
856+ (Andrew Bennetts)
857+
858+* ``BTreeLeafParser.extract_key`` has been tweaked slightly to reduce
859+ mallocs while parsing the index (approx 3=>1 mallocs per key read).
860+ This results in a 10% speedup while reading an index.
861+ (John Arbash Meinel)
862+
863 * The ``bzrlib.lsprof`` module has a new class ``BzrProfiler`` which makes
864 profiling in some situations like callbacks and generators easier.
865 (Robert Collins)
866@@ -50,27 +415,195 @@
867 * Passing ``--lsprof-tests -v`` to bzr selftest will cause lsprof output to
868 be output for every test. Note that this is very verbose! (Robert Collins)
869
870+* Setting ``BZR_TEST_PDB=1`` when running selftest will cause a pdb
871+ post_mortem to be triggered when a test failure occurs. (Robert Collins)
872+
873+* Shell-like tests can now be written. Code in ``bzrlib/tests/script.py`` ,
874+ documentation in ``developers/testing.txt`` for details.
875+ (Vincent Ladeuil)
876+
877+* Some tests could end up with the same id, that was dormant for
878+ a long time.
879+ (Vincent Ladeuil, #442980)
880+
881+* Stop showing the number of tests due to missing features in the test
882+ progress bar. (Martin Pool)
883+
884 * Test parameterisation now does a shallow copy, not a deep copy of the test
885 to be parameterised. This is not expected to break external use of test
886 parameterisation, and is substantially faster. (Robert Collins)
887
888-
889-bzr 2.0rc2
890-##########
891-
892-Bug Fixes
893-*********
894+* Tests that try to open a bzr dir on an arbitrary transport will now
895+ fail unless they have explicitly permitted the transport via
896+ ``self.permit_url``. The standard test factories such as ``self.get_url``
897+ will permit the urls they provide automatically, so only exceptional
898+ tests should need to do this. (Robert Collins)
899+
900+* The break-in test no longer cares about clean shutdown of the child,
901+ instead it is happy if the debugger starts up. (Robert Collins)
902+
903+* The full test suite is expected to pass when the C extensions are not
904+ present. (Vincent Ladeuil, #430749)
905+
906+
907+bzr 2.0.1
908+#########
909+
910+:Codename: Stability First
911+:2.0.1: 2009-10-14
912+
913+The first of our new ongoing bugfix-only stable releases has arrived. It
914+includes a collection of 12 bugfixes applied to bzr 2.0.0, but does not
915+include any of the feature development in the 2.1.0 series.
916+
917+
918+Bug Fixes
919+*********
920+
921+* ``bzr add`` in a tree that has files with ``\r`` or ``\n`` in the
922+ filename will issue a warning and skip over those files.
923+ (Robert Collins, #3918)
924+
925+* bzr will attempt to authenticate with SSH servers that support
926+ ``keyboard-interactive`` auth but not ``password`` auth when using
927+ Paramiko. (Andrew Bennetts, #433846)
928+
929+* Fixed fetches from a stacked branch on a smart server that were failing
930+ with some combinations of remote and local formats. This was causing
931+ "unknown object type identifier 60" errors. (Andrew Bennetts, #427736)
932+
933+* Fixed ``ObjectNotLocked`` errors when doing some log and diff operations
934+ on branches via a smart server. (Andrew Bennetts, #389413)
935+
936+* Handle things like ``bzr add foo`` and ``bzr rm foo`` when the tree is
937+ at the root of a drive. ``osutils._cicp_canonical_relpath`` always
938+ assumed that ``abspath()`` returned a path that did not have a trailing
939+ ``/``, but that is not true when working at the root of the filesystem.
940+ (John Arbash Meinel, Jason Spashett, #322807)
941+
942+* Hide deprecation warnings for 'final' releases for python2.6.
943+ (John Arbash Meinel, #440062)
944+
945+* Improve the time for ``bzr log DIR`` for 2a format repositories.
946+ We had been using the same code path as for <2a formats, which required
947+ iterating over all objects in all revisions.
948+ (John Arbash Meinel, #374730)
949+
950+* Make sure that we unlock the tree if we fail to create a TreeTransform
951+ object when doing a merge, and there is limbo, or pending-deletions
952+ directory. (Gary van der Merwe, #427773)
953+
954+* Occasional IndexError on renamed files have been fixed. Operations that
955+ set a full inventory in the working tree will now go via the
956+ apply_inventory_delta code path which is simpler and easier to
957+ understand than dirstates set_state_from_inventory method. This may
958+ have a small performance impact on operations built on _write_inventory,
959+ but such operations are already doing full tree scans, so no radical
960+ performance change should be observed. (Robert Collins, #403322)
961+
962+* Retrieving file text or mtime from a _PreviewTree has good performance when
963+ there are many changes. (Aaron Bentley)
964+
965+* The CHK index pages now use an unlimited cache size. With a limited
966+ cache and a large project, the random access of chk pages could cause us
967+ to download the entire cix file many times.
968+ (John Arbash Meinel, #402623)
969+
970+* When a file kind becomes unversionable after being added, a sensible
971+ error will be shown instead of a traceback. (Robert Collins, #438569)
972+
973+Documentation
974+*************
975+
976+* Improved README. (Ian Clatworthy)
977+
978+* Improved upgrade documentation for Launchpad branches.
979+ (Barry Warsaw)
980+
981+
982+bzr 2.0.0
983+#########
984+
985+:2.0.0: 2009-09-22
986+:Codename: Instant Karma
987+
988+This release of Bazaar makes the 2a (previously 'brisbane-core') format
989+the default when new branches or repositories are created. This format is
990+substantially smaller and faster for many operations. Most of the work in
991+this release focuses on bug fixes and stabilization, covering both 2a and
992+previous formats. (See the Upgrade Guide for information on migrating
993+existing projects.)
994+
995+This release also improves the documentation content and presentation,
996+including adding Windows HtmlHelp manuals.
997+
998+The Bazaar team decided that 2.0 will be a long-term supported release,
999+with bugfix-only 2.0.x releases based on it, continuing for at least six
1000+months or until the following stable release.
1001+
1002+Changes from 2.0.0rc2 to final
1003+******************************
1004+
1005+* Officially branded as 2.0.0 rather than 2.0 to clarify between things
1006+ that "want to happen on the 2.0.x stable series" versus things that want
1007+ to "land in 2.0.0". (Changes how bzrlib._format_version_tuple() handles
1008+ micro = 0.) (John Arbash Meinel)
1009+
1010+
1011+bzr 2.0.0rc2
1012+############
1013+
1014+:2.0.0rc2: 2009-09-10
1015+
1016+New Features
1017+************
1018+
1019+* Added post_commit hook for mutable trees. This allows the keywords
1020+ plugin to expand keywords on files changed by the commit.
1021+ (Ian Clatworthy, #408841)
1022+
1023+Bug Fixes
1024+*********
1025+
1026+* Bazaar's native protocol code now correctly handles EINTR, which most
1027+ noticeably occurs if you break in to the debugger while connected to a
1028+ bzr+ssh server. You can now can continue from the debugger (by typing
1029+ 'c') and the process continues. However, note that pressing C-\ in the
1030+ shell may still kill the SSH process, which is bug 162509, so you must
1031+ sent a signal to the bzr process specifically, for example by typing
1032+ ``kill -QUIT PID`` in another shell. (Martin Pool, #341535)
1033
1034 * ``bzr check`` in pack-0.92, 1.6 and 1.9 format repositories will no
1035 longer report incorrect errors about ``Missing inventory ('TREE_ROOT', ...)``
1036 (Robert Collins, #416732)
1037
1038+* ``bzr info -v`` on a 2a format still claimed that it was a "Development
1039+ format" (John Arbash Meinel, #424392)
1040+
1041 * ``bzr log stacked-branch`` shows the full log including
1042 revisions that are in the fallback repository. (Regressed in 2.0rc1).
1043 (John Arbash Meinel, #419241)
1044
1045-* Fix a segmentation fault when computing the ``merge_sort`` of a graph
1046- that has a ghost in the mainline ancestry.
1047+* Clearer message when Bazaar runs out of memory, instead of a ``MemoryError``
1048+ traceback. (Martin Pool, #109115)
1049+
1050+* Conversion to 2a will create a single pack for all the new revisions (as
1051+ long as it ran without interruption). This improves both ``bzr upgrade``
1052+ and ``bzr pull`` or ``bzr merge`` from local branches in older formats.
1053+ The autopack logic that occurs every 100 revisions during local
1054+ conversions was not returning that pack's identifier, which resulted in
1055+ the partial packs created during the conversion not being consolidated
1056+ at the end of the conversion process. (Robert Collins, #423818)
1057+
1058+* Fetches from 2a to 2a are now again requested in 'groupcompress' order.
1059+ Groups that are seen as 'underutilized' will be repacked on-the-fly.
1060+ This means that when the source is fully packed, there is minimal
1061+ overhead during the fetch, but if the source is poorly packed the result
1062+ is a fairly well packed repository (not as good as 'bzr pack' but
1063+ good-enough.) (Robert Collins, John Arbash Meinel, #402652)
1064+
1065+* Fix a potential segmentation fault when doing 'log' of a branch that had
1066+ ghosts in its mainline. (Evaluating None as a tuple is bad.)
1067 (John Arbash Meinel, #419241)
1068
1069 * ``groupcompress`` sort order is now more stable, rather than relying on
1070@@ -81,28 +614,41 @@
1071 bugfix vs 2.0rc1, and all 2.0rc1 users should upgrade to 2.0rc2 before
1072 converting repositories. (Robert Collins, #422849)
1073
1074+* Network streams now decode adjacent records of the same type into a
1075+ single stream, reducing layering churn. (Robert Collins)
1076+
1077+* Prevent some kinds of incomplete data from being committed to a 2a
1078+ repository, such as revisions without inventories, a missing chk_bytes
1079+ record for an inventory, or a missing text referenced by an inventory.
1080+ (Andrew Bennetts, #423506, #406687)
1081+
1082 Documentation
1083 *************
1084
1085+* Fix assertion error about "_remember_remote_is_before" when pushing to
1086+ older smart servers.
1087+ (Andrew Bennetts, #418931)
1088+
1089+* Help on hooks no longer says 'Not deprecated' for hooks that are
1090+ currently supported. (Ian Clatworthy, #422415)
1091+
1092+* PDF and CHM (Windows HtmlHelp) formats are now supported for the
1093+ user documentation. The HTML documentation is better broken up into
1094+ topics. (Ian Clatworthy)
1095+
1096+* The developer and foreign language documents are now separated
1097+ out so that searching in the HTML and CHM files produces more
1098+ useful results. (Ian Clatworthy)
1099+
1100 * The main table of contents now provides links to the new Migration Docs
1101 and Plugins Guide. (Ian Clatworthy)
1102
1103
1104-bzr 2.0rc1
1105-##########
1106-
1107+bzr 2.0.0rc1
1108+############
1109
1110 :Codename: no worries
1111-:2.0rc1: 2009-08-26
1112-
1113-This release of Bazaar makes 2a 'brisbane-core' format the
1114-default. Most of the work in this release now focuses on bug
1115-fixes and stabilization, covering both 2a and previous formats.
1116-
1117-The Bazaar team decided that 2.0 will be a long-term supported
1118-release, with bugfix-only releases based on it continuing for at
1119-least six months or until the following stable release (we said
1120-that previously, but that's worth repeating).
1121+:2.0.0rc1: 2009-08-26
1122
1123 Compatibility Breaks
1124 ********************
1125@@ -110,7 +656,7 @@
1126 * The default format for bzr is now ``2a``. This format brings many
1127 significant performance and size improvements. bzr can pull from
1128 any existing repository into a ``2a`` one, but can only transfer
1129- into ``rich-root`` repositories from ``2a``. The Upgrade guide
1130+ from ``2a`` into ``rich-root`` repositories. The Upgrade guide
1131 has more information about this change. (Robert Collins)
1132
1133 * On Windows auto-detection of Putty's plink.exe is disabled.
1134@@ -175,7 +721,7 @@
1135 * ``bzr shelve`` and ``bzr unshelve`` now work on windows.
1136 (Robert Collins, #305006)
1137
1138-* Commit of specific files no longer prevents using the the iter_changes
1139+* Commit of specific files no longer prevents using the iter_changes
1140 codepath. On 2a repositories, commit of specific files should now be as
1141 fast, or slightly faster, than a full commit. (Robert Collins)
1142
1143@@ -202,8 +748,17 @@
1144 Testing
1145 *******
1146
1147-bzr 1.18.1 NOT RELEASED YET
1148-###########################
1149+bzr 1.18.1
1150+##########
1151+
1152+:Codename: nein nein nein!
1153+:1.18.1: 2009-09-09
1154+
1155+This release fixes two small but worthwhile bugs relevant to users on
1156+Microsoft Windows: some commands that failed on with locking errors will
1157+now work, and a bug that caused poor performance after committing a file
1158+with line-ending conversion has now been fixed. It also fixes a bug in
1159+pushing to older servers.
1160
1161 Bug Fixes
1162 *********
1163@@ -212,13 +767,17 @@
1164 conversion will commit too many copies a file.
1165 (Martin Pool, #415508)
1166
1167+* Fix assertion error about ``_remember_remote_is_before`` in
1168+ ``set_tags_bytes`` when pushing to older smart servers.
1169+ (Andrew Bennetts, Alexander Belchenko, #418931)
1170+
1171 Improvements
1172 ************
1173
1174-* ``bzr push`` locally on windows will no longer give a locking error with
1175+* ``bzr push`` locally on Windows will no longer give a locking error with
1176 dirstate based formats. (Robert Collins)
1177
1178-* ``bzr shelve`` and ``bzr unshelve`` now work on windows.
1179+* ``bzr shelve`` and ``bzr unshelve`` now work on Windows.
1180 (Robert Collins, #305006)
1181
1182 API Changes
1183@@ -583,8 +1142,8 @@
1184 knit format repositories. (Andrew Bennetts, #405653)
1185
1186
1187-bzr 1.17 "So late it's brunch" 2009-07-20
1188-#########################################
1189+bzr 1.17
1190+########
1191 :Codename: so-late-its-brunch
1192 :1.17rc1: 2009-07-13
1193 :1.17: 2009-07-20
1194@@ -833,8 +1392,10 @@
1195 this class and the UI. (Martin Pool)
1196
1197
1198-bzr 1.16.1 2009-06-26
1199-#####################
1200+bzr 1.16.1
1201+##########
1202+
1203+:Released: 2009-06-26
1204
1205 End user testing of the 2a format revealed two serious bugs. The first,
1206 #365615, caused bzr to raise AbsentContentFactory errors when autopacking.
1207@@ -889,8 +1450,8 @@
1208 (Robert Collins, #376748)
1209
1210
1211-bzr 1.16 "It's yesterday in California" 2009-06-18
1212-##################################################
1213+bzr 1.16
1214+########
1215 :Codename: yesterday-in-california
1216 :1.16rc1: 2009-06-11
1217 :1.16: 2009-06-18
1218@@ -929,7 +1490,7 @@
1219 ************
1220
1221 * A new repository format ``2a`` has been added. This is a beta release
1222- of the the brisbane-core (aka group-compress) project. This format now
1223+ of the brisbane-core (aka group-compress) project. This format now
1224 suitable for wider testing by advanced users willing to deal with some
1225 bugs. We would appreciate test reports, either positive or negative.
1226 Format 2a is substantially smaller and faster for many operations on
1227@@ -1658,7 +2219,7 @@
1228
1229 * Added ``bzrlib.inventory_delta`` module. This will be used for
1230 serializing and deserializing inventory deltas for more efficient
1231- streaming on the the network. (Robert Collins, Andrew Bennetts)
1232+ streaming on the network. (Robert Collins, Andrew Bennetts)
1233
1234 * ``Branch._get_config`` has been added, which splits out access to the
1235 specific config file from the branch. This is used to let RemoteBranch
1236@@ -2367,8 +2928,11 @@
1237 (Vincent Ladeuil)
1238
1239
1240-bzr 1.11 "Eyes up!" 2009-01-19
1241-##############################
1242+bzr 1.11
1243+########
1244+
1245+:Codename: "Eyes up!"
1246+:Released: 2009-01-19
1247
1248 This first monthly release of Bazaar for 2009 improves Bazaar's operation
1249 in Windows, Mac OS X, and other situations where file names are matched
1250@@ -2394,8 +2958,11 @@
1251
1252
1253
1254-bzr 1.11rc1 "Eyes up!" 2009-01-09
1255-#################################
1256+bzr 1.11rc1
1257+###########
1258+
1259+:Codename: "Eyes up!"
1260+:Released: 2009-01-09
1261
1262 Changes
1263 *******
1264@@ -2631,8 +3198,10 @@
1265
1266
1267
1268-bzr 1.10 2008-12-05
1269-###################
1270+bzr 1.10
1271+########
1272+
1273+:Released: 2008-12-05
1274
1275 Bazaar 1.10 has several performance improvements for copying revisions
1276 (especially for small updates to large projects). There has also been a
1277@@ -2657,8 +3226,10 @@
1278 topologically. (John Arbash Meinel, #304841)
1279
1280
1281-bzr 1.10rc1 2008-11-28
1282-######################
1283+bzr 1.10rc1
1284+###########
1285+
1286+:Released: 2008-11-28
1287
1288 This release of Bazaar focuses on performance improvements when pushing
1289 and pulling revisions, both locally and to remote networks. The popular
1290@@ -2778,8 +3349,10 @@
1291 * Doctests now only report the first failure. (Martin Pool)
1292
1293
1294-bzr 1.9 2008-11-07
1295-##################
1296+bzr 1.9
1297+#######
1298+
1299+:Released: 2008-11-07
1300
1301 This release of Bazaar adds a new repository format, ``1.9``, with smaller
1302 and more efficient index files. This format can be specified when
1303@@ -2801,8 +3374,10 @@
1304 (John Arbash Meinel, #293746)
1305
1306
1307-bzr 1.9rc1 2008-10-31
1308-#####################
1309+bzr 1.9rc1
1310+##########
1311+
1312+:Released: 2008-10-31
1313
1314 New Features
1315 ************
1316@@ -2919,8 +3494,10 @@
1317 configuration of authetication credentials.
1318
1319
1320-bzr 1.8 2008-10-16
1321-##################
1322+bzr 1.8
1323+#######
1324+
1325+:Released: 2008-10-16
1326
1327 Bazaar 1.8 includes several fixes that improve working tree performance,
1328 display of revision logs, and merges. The bzr testsuite now passes on OS
1329@@ -2941,8 +3518,10 @@
1330 that platform. (Alexander Belchenko, Martin Pool, #277481)
1331
1332
1333-bzr 1.8rc1 2008-10-07
1334-#####################
1335+bzr 1.8rc1
1336+##########
1337+
1338+:Released: 2008-10-07
1339
1340 Changes
1341 *******
1342@@ -3140,14 +3719,18 @@
1343 (Vincent Ladeuil)
1344
1345
1346-bzr 1.7.1 2008-10-01
1347-####################
1348+bzr 1.7.1
1349+#########
1350+
1351+:Released: 2008-10-01
1352
1353 No changes from 1.7.1rc1.
1354
1355
1356-bzr 1.7.1rc1 2008-09-24
1357-#######################
1358+bzr 1.7.1rc1
1359+############
1360+
1361+:Released: 2008-09-24
1362
1363 This release just includes an update to how the merge algorithm handles
1364 file paths when we encounter complex history.
1365@@ -3162,8 +3745,10 @@
1366 (John Arbash Meinel)
1367
1368
1369-bzr 1.7 2008-09-23
1370-##################
1371+bzr 1.7
1372+#######
1373+
1374+:Released: 2008-09-23
1375
1376 This release includes many bug fixes and a few performance and feature
1377 improvements. ``bzr rm`` will now scan for missing files and remove them,
1378@@ -3180,8 +3765,10 @@
1379 packaging qbzr. (Mark Hammond)
1380
1381
1382-bzr 1.7rc2 2008-09-17
1383-#####################
1384+bzr 1.7rc2
1385+##########
1386+
1387+:Released: 2008-09-17
1388
1389 A few bug fixes from 1.7rc1. The biggest change is a new
1390 ``RemoteBranch.get_stacked_on_url`` rpc. This allows clients that are
1391@@ -3205,8 +3792,10 @@
1392 (Andrew Bennetts)
1393
1394
1395-bzr 1.7rc1 2008-09-09
1396-#####################
1397+bzr 1.7rc1
1398+##########
1399+
1400+:Released: 2008-09-09
1401
1402 This release candidate for bzr 1.7 has several bug fixes and a few
1403 performance and feature improvements. ``bzr rm`` will now scan for
1404@@ -3403,16 +3992,20 @@
1405 clients now use this mechanism. (Neil Martinsen-Burrell)
1406
1407
1408-bzr 1.6.1 2008-09-05
1409-####################
1410+bzr 1.6.1
1411+#########
1412+
1413+:Released: 2008-09-05
1414
1415 A couple regressions were found in the 1.6 release. There was a
1416 performance issue when using ``bzr+ssh`` to branch large repositories,
1417 and some problems with stacking and ``rich-root`` capable repositories.
1418
1419
1420-bzr 1.6.1rc2 2008-09-03
1421-#######################
1422+bzr 1.6.1rc2
1423+############
1424+
1425+:Released: 2008-09-03
1426
1427 Bug Fixes
1428 *********
1429@@ -3423,8 +4016,10 @@
1430 (John Arbash Meinel, #264321)
1431
1432
1433-bzr 1.6.1rc1 2008-08-29
1434-#######################
1435+bzr 1.6.1rc1
1436+############
1437+
1438+:Released: 2008-08-29
1439
1440 This release fixes a few regressions found in the 1.6 client. Fetching
1441 changes was using an O(N^2) buffering algorithm, so for large projects it
1442@@ -3464,8 +4059,10 @@
1443 (John Arbash Meinel, #262333)
1444
1445
1446-bzr 1.6 2008-08-25
1447-##################
1448+bzr 1.6
1449+#######
1450+
1451+:Released: 2008-08-25
1452
1453 Finally, the long awaited bzr 1.6 has been released. This release includes
1454 new features like Stacked Branches, improved weave merge, and an updated
1455@@ -3478,8 +4075,10 @@
1456 TortoiseBzr in the standalone Windows installer.
1457
1458
1459-bzr 1.6rc5 2008-08-19
1460-#####################
1461+bzr 1.6rc5
1462+##########
1463+
1464+:Released: 2008-08-19
1465
1466 Bug Fixes
1467 *********
1468@@ -3491,8 +4090,10 @@
1469 (This change was reverted when merged to bzr.dev)
1470
1471
1472-bzr 1.6rc4 2008-08-18
1473-#####################
1474+bzr 1.6rc4
1475+##########
1476+
1477+:Released: 2008-08-18
1478
1479 Bug Fixes
1480 *********
1481@@ -3502,8 +4103,10 @@
1482 rather than preserving deltas. (John Arbash Meinel, #256757)
1483
1484
1485-bzr 1.6rc3 2008-08-14
1486-#####################
1487+bzr 1.6rc3
1488+##########
1489+
1490+:Released: 2008-08-14
1491
1492 Changes
1493 *******
1494@@ -3536,8 +4139,10 @@
1495 development which is substantially faster. (Robert Collins)
1496
1497
1498-bzr 1.6rc2 2008-08-13
1499-#####################
1500+bzr 1.6rc2
1501+##########
1502+
1503+:Released: 2008-08-13
1504
1505 This release candidate has a few minor bug fixes, and some regression
1506 fixes for Windows.
1507@@ -3575,8 +4180,10 @@
1508 will get the same results. (John Arbash Meinel, #232188)
1509
1510
1511-bzr 1.6rc1 2008-08-06
1512-#####################
1513+bzr 1.6rc1
1514+##########
1515+
1516+:Released: 2008-08-06
1517
1518 This release candidate for bzr 1.6 solidifies the new branch stacking
1519 feature. Bazaar now recommends that users upgrade all knit repositories,
1520@@ -3712,8 +4319,10 @@
1521 (Ian Clatworthy)
1522
1523
1524-bzr 1.6beta3 2008-07-17
1525-#######################
1526+bzr 1.6beta3
1527+############
1528+
1529+:Released: 2008-07-17
1530
1531 This release adds a new 'stacked branches' feature allowing branches to
1532 share storage without being in the same repository or on the same machine.
1533@@ -3885,8 +4494,10 @@
1534 (Robert Collins)
1535
1536
1537-bzr 1.6beta2 2008-06-10
1538-#######################
1539+bzr 1.6beta2
1540+############
1541+
1542+:Released: 2008-06-10
1543
1544 This release contains further progress towards our 1.6 goals of shallow
1545 repositories, and contains a fix for some user-affecting bugs in the
1546@@ -3969,9 +4580,10 @@
1547 * Knit record serialisation is now stricter on what it will accept, to
1548 guard against potential internal bugs, or broken input. (Robert Collins)
1549
1550-bzr 1.6beta1 2008-06-02
1551-#######################
1552+bzr 1.6beta1
1553+############
1554
1555+:Released: 2008-06-02
1556
1557 Commands that work on the revision history such as push, pull, missing,
1558 uncommit and log are now substantially faster. This release adds a
1559@@ -4189,8 +4801,10 @@
1560 (Martin Pool)
1561
1562
1563-bzr 1.5 2008-05-16
1564-##################
1565+bzr 1.5
1566+#######
1567+
1568+:Released: 2008-05-16
1569
1570 This release of Bazaar includes several updates to the documentation, and fixes
1571 to prepare for making rich root support the default format. Many bugs have been
1572@@ -4211,8 +4825,10 @@
1573 (Ian Clatworthy)
1574
1575
1576-bzr 1.5rc1 2008-05-09
1577-#####################
1578+bzr 1.5rc1
1579+##########
1580+
1581+:Released: 2008-05-09
1582
1583 Changes
1584 *******
1585@@ -4327,7 +4943,7 @@
1586 exception. (Andrew Bennetts)
1587
1588 * New ``--debugflag``/``-E`` option to ``bzr selftest`` for setting
1589- options for debugging tests, these are complementary to the the -D
1590+ options for debugging tests, these are complementary to the -D
1591 options. The ``-Dselftest_debug`` global option has been replaced by the
1592 ``-E=allow_debug`` option for selftest. (Andrew Bennetts)
1593
1594@@ -4382,8 +4998,10 @@
1595 (Martin Pool)
1596
1597
1598-bzr 1.4 2008-04-28
1599-##################
1600+bzr 1.4
1601+#######
1602+
1603+:Released: 2008-04-28
1604
1605 This release of Bazaar includes handy improvements to the speed of log and
1606 status, new options for several commands, improved documentation, and better
1607@@ -4402,8 +5020,10 @@
1608 (John Arbash Meinel, Andrew Bennetts, #214894)
1609
1610
1611-bzr 1.4rc2 2008-04-21
1612-#####################
1613+bzr 1.4rc2
1614+##########
1615+
1616+:Released: 2008-04-21
1617
1618 Bug Fixes
1619 *********
1620@@ -4426,8 +5046,10 @@
1621 (Robert Collins, John Arbash Meinel)
1622
1623
1624-bzr 1.4rc1 2008-04-11
1625-#####################
1626+bzr 1.4rc1
1627+##########
1628+
1629+:Released: 2008-04-11
1630
1631 Changes
1632 *******
1633@@ -4714,14 +5336,18 @@
1634 ``Graph.get_parent_map`` returns a dict of key:parents. (Robert Collins)
1635
1636
1637-bzr 1.3.1 2008-04-09
1638-####################
1639+bzr 1.3.1
1640+#########
1641+
1642+:Released: 2008-04-09
1643
1644 No changes from 1.3.1rc1.
1645
1646
1647-bzr 1.3.1rc1 2008-04-04
1648-#######################
1649+bzr 1.3.1rc1
1650+############
1651+
1652+:Released: 2008-04-04
1653
1654 Bug Fixes
1655 *********
1656@@ -4732,8 +5358,10 @@
1657 (#208418, Andrew Bennetts, Martin Pool, Robert Collins)
1658
1659
1660-bzr 1.3 2008-03-20
1661-##################
1662+bzr 1.3
1663+#######
1664+
1665+:Released: 2008-03-20
1666
1667 Bazaar has become part of the GNU project <http://www.gnu.org>
1668
1669@@ -4749,8 +5377,10 @@
1670 (#202778, Martin Pool)
1671
1672
1673-bzr 1.3rc1 2008-03-16
1674-#####################
1675+bzr 1.3rc1
1676+##########
1677+
1678+:Released: 2008-03-16
1679
1680 Notes When Upgrading
1681 ********************
1682@@ -4936,8 +5566,10 @@
1683 format. (Robert Collins)
1684
1685
1686-bzr 1.2 2008-02-15
1687-##################
1688+bzr 1.2
1689+#######
1690+
1691+:Released: 2008-02-15
1692
1693 Bug Fixes
1694 *********
1695@@ -4945,8 +5577,10 @@
1696 * Fix failing test in Launchpad plugin. (Martin Pool)
1697
1698
1699-bzr 1.2rc1 2008-02-13
1700-#####################
1701+bzr 1.2rc1
1702+##########
1703+
1704+:Released: 2008-02-13
1705
1706 Notes When Upgrading
1707 ********************
1708@@ -5147,13 +5781,17 @@
1709 revision names etc. (Robert Collins)
1710
1711
1712-bzr 1.1 2008-01-15
1713-##################
1714+bzr 1.1
1715+#######
1716+
1717+:Released: 2008-01-15
1718
1719 (no changes from 1.1rc1)
1720
1721-bzr 1.1rc1 2008-01-05
1722-#####################
1723+bzr 1.1rc1
1724+##########
1725+
1726+:Released: 2008-01-05
1727
1728 Changes
1729 *******
1730@@ -5363,8 +6001,10 @@
1731 replaced by the new helper methods added in this release. (Robert Collins)
1732
1733
1734-bzr 1.0 2007-12-14
1735-##################
1736+bzr 1.0
1737+#######
1738+
1739+:Released: 2007-12-14
1740
1741 Documentation
1742 *************
1743@@ -5381,8 +6021,10 @@
1744 (Ian Clatworthy)
1745
1746
1747-bzr 1.0rc3 2007-12-11
1748-#####################
1749+bzr 1.0rc3
1750+##########
1751+
1752+:Released: 2007-12-11
1753
1754 Changes
1755 *******
1756@@ -5423,8 +6065,10 @@
1757 (Vincent Ladeuil)
1758
1759
1760-bzr 1.0rc2 2007-12-07
1761-#####################
1762+bzr 1.0rc2
1763+##########
1764+
1765+:Released: 2007-12-07
1766
1767 Improvements
1768 ************
1769@@ -5498,8 +6142,10 @@
1770 ``started`` methods. (Matt Nordhoff)
1771
1772
1773-bzr 1.0rc1 2007-11-30
1774-#####################
1775+bzr 1.0rc1
1776+##########
1777+
1778+:Released: 2007-11-30
1779
1780 Notes When Upgrading
1781 ********************
1782@@ -5775,8 +6421,10 @@
1783 * InventoryEntry.diff is now deprecated. Please use diff.DiffTree instead.
1784
1785
1786-bzr 0.92 2007-11-05
1787-###################
1788+bzr 0.92
1789+########
1790+
1791+:Released: 2007-11-05
1792
1793 Changes
1794 *******
1795@@ -5784,8 +6432,10 @@
1796 * New uninstaller on Win32. (Alexander Belchenko)
1797
1798
1799-bzr 0.92rc1 2007-10-29
1800-######################
1801+bzr 0.92rc1
1802+###########
1803+
1804+:Released: 2007-10-29
1805
1806 Changes
1807 *******
1808@@ -6104,8 +6754,10 @@
1809 raises a Python warning. (Martin Pool)
1810
1811
1812-bzr 0.91 2007-09-26
1813-###################
1814+bzr 0.91
1815+########
1816+
1817+:Released: 2007-09-26
1818
1819 Bug Fixes
1820 *********
1821@@ -6126,15 +6778,19 @@
1822 (Andrew Bennetts)
1823
1824
1825-bzr 0.91rc2 2007-09-11
1826-######################
1827+bzr 0.91rc2
1828+###########
1829+
1830+:Released: 2007-09-11
1831
1832 * Replaced incorrect tarball for previous release; a debug statement was left
1833 in bzrlib/remote.py.
1834
1835
1836-bzr 0.91rc1 2007-09-11
1837-######################
1838+bzr 0.91rc1
1839+###########
1840+
1841+:Released: 2007-09-11
1842
1843 Changes
1844 *******
1845@@ -6461,8 +7117,10 @@
1846 [] to revert all files is deprecated. (Aaron Bentley)
1847
1848
1849-bzr 0.90 2007-08-28
1850-###################
1851+bzr 0.90
1852+########
1853+
1854+:Released: 2007-08-28
1855
1856 Improvements
1857 ************
1858@@ -6485,8 +7143,10 @@
1859 and call ``create_repository`` on that. (Martin Pool)
1860
1861
1862-bzr 0.90rc1 2007-08-14
1863-######################
1864+bzr 0.90rc1
1865+###########
1866+
1867+:Released: 2007-08-14
1868
1869 Bugfixes
1870 ********
1871@@ -6758,8 +7418,10 @@
1872 parameter. Varargs-style parameters are deprecated. (Aaron Bentley)
1873
1874
1875-bzr 0.18 2007-07-17
1876-####################
1877+bzr 0.18
1878+########
1879+
1880+:Released: 2007-07-17
1881
1882 Bugfixes
1883 ********
1884@@ -6767,8 +7429,10 @@
1885 * Fix 'bzr add' crash under Win32 (Kuno Meyer)
1886
1887
1888-bzr 0.18rc1 2007-07-10
1889-#######################
1890+bzr 0.18rc1
1891+###########
1892+
1893+:Released: 2007-07-10
1894
1895 Bugfixes
1896 ********
1897@@ -7019,8 +7683,10 @@
1898 (Vincent Ladeuil, #110448)
1899
1900
1901-bzr 0.17 2007-06-18
1902-####################
1903+bzr 0.17
1904+########
1905+
1906+:Released: 2007-06-18
1907
1908 Bugfixes
1909 ********
1910@@ -7032,8 +7698,10 @@
1911 (Aaron Bentley, Ian Clatworthy, #120930)
1912
1913
1914-bzr 0.17rc1 2007-06-12
1915-#######################
1916+bzr 0.17rc1
1917+###########
1918+
1919+:Released: 2007-06-12
1920
1921 Notes When Upgrading
1922 ********************
1923@@ -7134,8 +7802,10 @@
1924 your repository. (Previously Branch6 only supported revisions in your
1925 mainline). (John Arbash Meinel, #115343)
1926
1927-bzr 0.16 2007-05-07
1928-####################
1929+bzr 0.16
1930+########
1931+
1932+:Released: 2007-05-07
1933
1934 Bugfixes
1935 ********
1936@@ -7165,8 +7835,10 @@
1937 diff`` and ``bzr status`` significantly improving the speed of
1938 both. (John Arbash Meinel)
1939
1940-bzr 0.16rc2 2007-04-30
1941-#######################
1942+bzr 0.16rc2
1943+###########
1944+
1945+:Released: 2007-04-30
1946
1947 Bugfixes
1948 ********
1949@@ -7189,8 +7861,10 @@
1950 * ``WorkingTree4._iter_changes`` should not descend into unversioned
1951 directories. (John Arbash Meinel, #110399)
1952
1953-bzr 0.16rc1 2007-04-26
1954-#######################
1955+bzr 0.16rc1
1956+###########
1957+
1958+:Released: 2007-04-26
1959
1960 Notes When Upgrading
1961 ********************
1962@@ -7497,8 +8171,10 @@
1963 implementation of new auth schemes for both http and proxy.
1964 (Vincent Ladeuil)
1965
1966-bzr 0.15 2007-04-01
1967-###################
1968+bzr 0.15
1969+########
1970+
1971+:Released: 2007-04-01
1972
1973 Bugfixes
1974 ********
1975@@ -7510,8 +8186,10 @@
1976 checking out a branch that contains an old-format working tree.
1977 (Martin Pool)
1978
1979-bzr 0.15rc3 2007-03-26
1980-#######################
1981+bzr 0.15rc3
1982+###########
1983+
1984+:Released: 2007-03-26
1985
1986 Changes
1987 *******
1988@@ -7586,8 +8264,10 @@
1989 * Correctly handles mutiple permanent http redirections.
1990 (vila, #88780)
1991
1992-bzr 0.15rc2 2007-03-14
1993-#######################
1994+bzr 0.15rc2
1995+###########
1996+
1997+:Released: 2007-03-14
1998
1999 Notes When Upgrading
2000 ********************
2001@@ -7640,8 +8320,10 @@
2002 (Wouter van Heyst, #53483)
2003
2004
2005-bzr 0.15rc1 2007-03-07
2006-#######################
2007+bzr 0.15rc1
2008+###########
2009+
2010+:Released: 2007-03-07
2011
2012 Surprises
2013 *********
2014@@ -7871,8 +8553,10 @@
2015 before the rest of the suite. (Martin Pool)
2016
2017
2018-bzr 0.14 2007-01-23
2019-####################
2020+bzr 0.14
2021+########
2022+
2023+:Released: 2007-01-23
2024
2025 Improvements
2026 ************
2027@@ -7891,8 +8575,10 @@
2028 it is in is below a repository. (James Westby, #77306)
2029
2030
2031-bzr 0.14rc1 2007-01-16
2032-#######################
2033+bzr 0.14rc1
2034+###########
2035+
2036+:Released: 2007-01-16
2037
2038 Improvements
2039 ************
2040@@ -8026,14 +8712,18 @@
2041 (Alexander Belchenko, #68124)
2042
2043
2044-bzr 0.13 2006-12-05
2045-####################
2046+bzr 0.13
2047+########
2048+
2049+:Released: 2006-12-05
2050
2051 No changes from 0.13rc
2052
2053
2054-bzr 0.13rc1 2006-11-27
2055-#######################
2056+bzr 0.13rc1
2057+###########
2058+
2059+:Released: 2006-11-27
2060
2061 Improvements
2062 ************
2063@@ -8158,8 +8848,10 @@
2064 * TestingHTTPRequestHandler really handles the Range header
2065 (previously it was ignoring it and returning the whole file,).
2066
2067-bzr 0.12 2006-10-30
2068-####################
2069+bzr 0.12
2070+########
2071+
2072+:Released: 2006-10-30
2073
2074 Internals
2075 *********
2076@@ -8168,8 +8860,10 @@
2077 and remove benchmarks that take longer than 10min to run.
2078 (John Arbash Meinel)
2079
2080-bzr 0.12rc1 2006-10-23
2081-#######################
2082+bzr 0.12rc1
2083+###########
2084+
2085+:Released: 2006-10-23
2086
2087 Improvements
2088 ************
2089@@ -8290,13 +8984,17 @@
2090 option to set the BzrDir, Repository and Branch formats of the
2091 created objects. (Robert Collins, John Arbash Meinel)
2092
2093-bzr 0.11 2006-10-02
2094-####################
2095+bzr 0.11
2096+########
2097+
2098+:Released: 2006-10-02
2099
2100 * Smart server transport test failures on windows fixed. (Lukáš Lalinský).
2101
2102-bzr 0.11rc2 2006-09-27
2103-#######################
2104+bzr 0.11rc2
2105+###########
2106+
2107+:Released: 2006-09-27
2108
2109 Bug Fixes
2110 *********
2111@@ -8306,8 +9004,10 @@
2112 * Commit performance regression fixed. (Aaron Bentley, Robert Collins, John
2113 Arbash Meinel).
2114
2115-bzr 0.11rc1 2006-09-25
2116-#######################
2117+bzr 0.11rc1
2118+###########
2119+
2120+:Released: 2006-09-25
2121
2122 Improvements
2123 ************
2124@@ -8500,8 +9200,10 @@
2125 allow upgrades to a richer interface than the VFS one provided by
2126 Transport. (Andrew Bennetts, Martin Pool)
2127
2128-bzr 0.10 2006-08-29
2129-####################
2130+bzr 0.10
2131+########
2132+
2133+:Released: 2006-08-29
2134
2135 Improvements
2136 ************
2137@@ -8578,8 +9280,10 @@
2138 need to be installed. This should help make the life of packagers
2139 easier. (John Arbash Meinel)
2140
2141-bzr 0.9.0 2006-08-11
2142-#####################
2143+bzr 0.9.0
2144+#########
2145+
2146+:Released: 2006-08-11
2147
2148 Surprises
2149 *********
2150@@ -8846,16 +9550,20 @@
2151
2152 * "RevisionTree" is now in bzrlib/revisiontree.py. (Robert Collins)
2153
2154-bzr 0.8.2 2006-05-17
2155-#####################
2156+bzr 0.8.2
2157+#########
2158+
2159+:Released: 2006-05-17
2160
2161 Bug Fixes
2162 *********
2163
2164 * setup.py failed to install launchpad plugin. (Martin Pool)
2165
2166-bzr 0.8.1 2006-05-16
2167-#####################
2168+bzr 0.8.1
2169+#########
2170+
2171+:Released: 2006-05-16
2172
2173 Bug Fixes
2174 *********
2175@@ -8908,8 +9616,10 @@
2176 * Fix test case for bzr info in upgrading a standalone branch to metadir,
2177 uses bzrlib api now. (Olaf Conradi)
2178
2179-bzr 0.8 2006-05-08
2180-###################
2181+bzr 0.8
2182+#######
2183+
2184+:Released: 2006-05-08
2185
2186 Notes When Upgrading
2187 ********************
2188@@ -9170,8 +9880,10 @@
2189 * ``run_bzr`` and ``run_bzr_captured`` now accept a 'stdin="foo"'
2190 parameter which will provide String("foo") to the command as its stdin.
2191
2192-bzr 0.7 2006-01-09
2193-##################
2194+bzr 0.7
2195+#######
2196+
2197+:Released: 2006-01-09
2198
2199 Changes
2200 *******
2201@@ -9466,8 +10178,10 @@
2202 * ``bzrlib.osutils.safe_unicode`` now exists to provide parameter coercion
2203 for functions that need unicode strings. (Robert Collins)
2204
2205-bzr 0.6 2005-10-28
2206-##################
2207+bzr 0.6
2208+#######
2209+
2210+:Released: 2005-10-28
2211
2212 Improvements
2213 ************
2214@@ -9682,8 +10396,10 @@
2215 [-1] in the revision-history. (Andres Salomon)
2216
2217
2218-bzr 0.1.1 2005-10-12
2219-####################
2220+bzr 0.1.1
2221+#########
2222+
2223+:Released: 2005-10-12
2224
2225 Bug Fixes
2226 *********
2227@@ -9700,8 +10416,10 @@
2228 * Avoid some unnecessary http operations in branch and pull.
2229
2230
2231-bzr 0.1 2005-10-11
2232-##################
2233+bzr 0.1
2234+#######
2235+
2236+:Released: 2005-10-11
2237
2238 Notes
2239 *****
2240@@ -9830,8 +10548,10 @@
2241 of tests to run, e.g. ``bzr selftest test_weave``
2242
2243
2244-bzr 0.0.9 2005-09-23
2245-####################
2246+bzr 0.0.9
2247+#########
2248+
2249+:Released: 2005-09-23
2250
2251 Bug Fixes
2252 *********
2253@@ -9872,8 +10592,11 @@
2254 another (used by pull, merged, etc.)
2255
2256
2257-bzr 0.0.8 2005-09-20
2258-####################
2259+bzr 0.0.8
2260+#########
2261+
2262+:Released: 2005-09-20
2263+
2264
2265 Improvements
2266 ************
2267@@ -9923,8 +10646,10 @@
2268 * Quieten warnings about locking; patch from Matt Lavin.
2269
2270
2271-bzr-0.0.7 2005-09-02
2272-####################
2273+bzr-0.0.7
2274+#########
2275+
2276+:Released: 2005-09-02
2277
2278 New Features
2279 ************
2280@@ -9978,8 +10703,10 @@
2281
2282
2283
2284-bzr-0.0.6 2005-08-18
2285-####################
2286+bzr-0.0.6
2287+#########
2288+
2289+:Released: 2005-08-18
2290
2291 New Features
2292 ************
2293@@ -10064,8 +10791,10 @@
2294 * Fix bugs in committing only selected files or within a subdirectory.
2295
2296
2297-bzr-0.0.5 2005-06-15
2298-#####################
2299+bzr-0.0.5
2300+#########
2301+
2302+:Released: 2005-06-15
2303
2304 Changes
2305 *******
2306@@ -10206,8 +10935,10 @@
2307 2.4 is now only recommended.
2308
2309
2310-bzr-0.0.4 2005-04-22
2311-#####################
2312+bzr-0.0.4
2313+#########
2314+
2315+:Released: 2005-04-22
2316
2317 Enhancements
2318 ************
2319@@ -10275,8 +11006,10 @@
2320 from QuantumG.
2321
2322
2323-bzr-0.0.3 2005-04-06
2324-#####################
2325+bzr-0.0.3
2326+#########
2327+
2328+:Released: 2005-04-06
2329
2330 Enhancements
2331 ************
2332@@ -10330,8 +11063,11 @@
2333 * Win32 fixes from Steve Brown.
2334
2335
2336-bzr-0.0.2 "black cube" 2005-03-31
2337-###################################
2338+bzr-0.0.2
2339+#########
2340+
2341+:Codename: "black cube"
2342+:Released: 2005-03-31
2343
2344 Enhancements
2345 ************
2346@@ -10359,8 +11095,10 @@
2347 the root directory only.
2348
2349
2350-bzr-0.0.1 2005-03-26
2351-#####################
2352+bzr-0.0.1
2353+#########
2354+
2355+:Released: 2005-03-26
2356
2357 Enhancements
2358 ************
2359@@ -10389,8 +11127,10 @@
2360 supported).
2361
2362
2363-bzr-0.0.0.69 2005-03-22
2364-########################
2365+bzr-0.0.0.69
2366+############
2367+
2368+:Released: 2005-03-22
2369
2370 Enhancements
2371 ************
2372@@ -10400,5 +11140,38 @@
2373 * Storage of local versions: init, add, remove, rm, info, log,
2374 diff, status, etc.
2375
2376+
2377+bzr ?.?.? (not released yet)
2378+############################
2379+
2380+:Codename: template
2381+:2.0.2: ???
2382+
2383+Compatibility Breaks
2384+********************
2385+
2386+New Features
2387+************
2388+
2389+Bug Fixes
2390+*********
2391+
2392+Improvements
2393+************
2394+
2395+Documentation
2396+*************
2397+
2398+API Changes
2399+***********
2400+
2401+Internals
2402+*********
2403+
2404+Testing
2405+*******
2406+
2407+
2408+
2409 ..
2410 vim: tw=74 ft=rst ff=unix
2411
2412=== modified file 'README'
2413--- README 2008-03-16 14:01:20 +0000
2414+++ README 2009-11-03 09:40:55 +0000
2415@@ -3,72 +3,44 @@
2416 =================
2417
2418 Bazaar (``bzr``) is a decentralized revision control system, designed to be
2419-easy for developers and end users alike. Bazaar is part of the GNU project to
2420-develop a complete free operating system.
2421-
2422-To install Bazaar from source, follow the instructions in the INSTALL
2423-file. Otherwise, you may want to check your distribution package manager
2424-for ready-to-install packages, or http://bazaar-vcs.org/DistroDownloads.
2425-
2426-To learn how to use Bazaar, check the documentation in the doc/ directory.
2427-Once installed, you can also run 'bzr help'. An always up-to-date and more
2428-complete set of documents can be found in the Bazaar website, at:
2429-
2430- http://bazaar-vcs.org/Documentation
2431+easy for developers and end users alike. Bazaar is part of the GNU project
2432+to develop a complete free operating system.
2433+
2434+To install Bazaar, follow the instructions given at
2435+http://bazaar-vcs.org/Download. Ready-to-install packages are available
2436+for most popular operating systems or you can install from source.
2437+
2438+To learn how to use Bazaar, see the official documentation at:
2439+
2440+ http://doc.bazaar-vcs.org/en/
2441+
2442+For additional training materials including screencasts and slides,
2443+visit our community wiki documentation page at:
2444+
2445+ http://bazaar-vcs.org/Documentation/
2446
2447 Bazaar is written in Python, and is sponsored by Canonical Limited, the
2448 founders of Ubuntu and Launchpad. Bazaar is Free Software, and is released
2449 under the GNU General Public License.
2450
2451-Bazaar was formerly known as Bazaar-NG. It's the successor to ``baz``, a fork
2452-of GNU arch, but shares no code. (To upgrade from Baz, use the ``baz-import``
2453-command in the bzrtools plugin.)
2454-
2455 Bazaar highlights
2456 =================
2457
2458-* Easy to use and intuitive.
2459-
2460- Only five commands are needed to do all basic operations, and all
2461- commands have documentation accessible via 'bzr help command'.
2462- Bazaar's interface is also easy to learn for CVS and Subversion users.
2463-
2464-* Robust and reliable.
2465-
2466- Bazaar is developed under an extensive test suite. Branches can be
2467- checked and verified for integrity at any time, and revisions can be
2468- signed with PGP/GnuPG.
2469-
2470-* Publish branches with HTTP.
2471-
2472- Branches can be hosted on an HTTP server with no need for special
2473- software on the server side. Branches can be uploaded by bzr itself
2474- over SSH (SFTP), or with rsync.
2475-
2476-* Adapts to multiple environments.
2477-
2478- Bazaar runs on Linux and Windows, fully supports Unicode filenames,
2479- and suits different development models, including centralized.
2480-
2481-* Easily extended and customized.
2482-
2483- A rich Python interface is provided for extending and embedding,
2484- including a plugin interface. There are already many available plugins,
2485- most of them registered at http://bazaar-vcs.org/PluginRegistry.
2486-
2487-* Smart merging.
2488-
2489- Changes will never be merged more than once, conflicts will be
2490- minimized, and identical changes are dealt with well.
2491-
2492-* Vibrant and active community.
2493-
2494- Help with Bazaar is obtained easily, via the mailing list, or the IRC
2495- channel.
2496-
2497-
2498-Registration and Feedback
2499-=========================
2500+Bazaar directly supports both central version control (like cvs/svn) and
2501+distributed version control (like git/hg). Developers can organize their
2502+workspace in whichever way they want on a per project basis including:
2503+
2504+* checkouts (like svn)
2505+* feature branches (like hg)
2506+* shared working tree (like git).
2507+
2508+It also directly supports and encourages a large number of development best
2509+practices like refactoring and pre-commit regression testing. Users can
2510+choose between our command line tool and our cross-platform GUI application.
2511+For further details, see our website at http://bazaar-vcs.org/en.
2512+
2513+Feedback
2514+========
2515
2516 If you encounter any problems with Bazaar, need help understanding it, or would
2517 like to offer suggestions or feedback, please get in touch with us:
2518@@ -76,7 +48,7 @@
2519 * Ask a question through our web support interface, at
2520 https://answers.launchpad.net/bzr/
2521
2522-* Report bugs at https://bugs.edge.launchpad.net/bzr/+filebug
2523+* Report bugs at https://bugs.launchpad.net/bzr/+filebug
2524
2525 * Write to us at bazaar@lists.canonical.com
2526 You can join the list at <https://lists.ubuntu.com/mailman/listinfo/bazaar>.
2527@@ -85,12 +57,8 @@
2528
2529 * Talk to us in irc://irc.ubuntu.com/bzr
2530
2531-* And see http://bazaar-vcs.org/BzrSupport for more.
2532-
2533-If you would like to help us improve Bazaar by telling us about yourself and
2534-what we could do better, please register and complete the online survey here:
2535-http://www.surveymonkey.com/s.aspx?sm=L94RvLswhKdktrxiHWiX3g_3d_3d.
2536-Registration is completely optional.
2537-
2538-Enjoy,
2539+Our mission is to make a version control tool that developers LOVE to use
2540+and that casual contributors feel confident with. Please let us know how
2541+we're going.
2542+
2543 The Bazaar Team
2544
2545=== modified file 'bzrlib/__init__.py'
2546--- bzrlib/__init__.py 2009-08-30 21:34:42 +0000
2547+++ bzrlib/__init__.py 2009-11-03 09:40:55 +0000
2548@@ -31,16 +31,10 @@
2549 import bzrlib.lazy_regex
2550 bzrlib.lazy_regex.install_lazy_compile()
2551
2552-from bzrlib.osutils import get_user_encoding
2553-
2554
2555 IGNORE_FILENAME = ".bzrignore"
2556
2557
2558-# XXX: Deprecated as of bzr-1.17 use osutils.get_user_encoding() directly
2559-user_encoding = get_user_encoding()
2560-
2561-
2562 __copyright__ = "Copyright 2005, 2006, 2007, 2008, 2009 Canonical Ltd."
2563
2564 # same format as sys.version_info: "A tuple containing the five components of
2565@@ -50,10 +44,11 @@
2566 # Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a
2567 # releaselevel of 'dev' for unreleased under-development code.
2568
2569-version_info = (2, 1, 0, 'dev', 0)
2570+version_info = (2, 1, 0, 'dev', 3)
2571
2572 # API compatibility version: bzrlib is currently API compatible with 1.15.
2573-api_minimum_version = (1, 17, 0)
2574+api_minimum_version = (2, 1, 0)
2575+
2576
2577 def _format_version_tuple(version_info):
2578 """Turn a version number 2, 3 or 5-tuple into a short string.
2579@@ -65,23 +60,29 @@
2580 zero for final releases.
2581
2582 >>> print _format_version_tuple((1, 0, 0, 'final', 0))
2583- 1.0
2584+ 1.0.0
2585 >>> print _format_version_tuple((1, 2, 0, 'dev', 0))
2586- 1.2dev
2587+ 1.2.0dev
2588+ >>> print bzrlib._format_version_tuple((1, 2, 0, 'dev', 1))
2589+ 1.2.0dev1
2590 >>> print _format_version_tuple((1, 1, 1, 'candidate', 2))
2591 1.1.1rc2
2592 >>> print bzrlib._format_version_tuple((2, 1, 0, 'beta', 1))
2593- 2.1b1
2594+ 2.1.0b1
2595 >>> print _format_version_tuple((1, 4, 0))
2596- 1.4
2597+ 1.4.0
2598 >>> print _format_version_tuple((1, 4))
2599 1.4
2600+ >>> print bzrlib._format_version_tuple((2, 1, 0, 'final', 1))
2601+ Traceback (most recent call last):
2602+ ...
2603+ ValueError: version_info (2, 1, 0, 'final', 1) not valid
2604 >>> print _format_version_tuple((1, 4, 0, 'wibble', 0))
2605 Traceback (most recent call last):
2606 ...
2607 ValueError: version_info (1, 4, 0, 'wibble', 0) not valid
2608 """
2609- if len(version_info) == 2 or version_info[2] == 0:
2610+ if len(version_info) == 2:
2611 main_version = '%d.%d' % version_info[:2]
2612 else:
2613 main_version = '%d.%d.%d' % version_info[:3]
2614@@ -96,6 +97,8 @@
2615 sub_string = ''
2616 elif release_type == 'dev' and sub == 0:
2617 sub_string = 'dev'
2618+ elif release_type == 'dev':
2619+ sub_string = 'dev' + str(sub)
2620 elif release_type in ('alpha', 'beta'):
2621 sub_string = release_type[0] + str(sub)
2622 elif release_type == 'candidate':
2623@@ -103,7 +106,6 @@
2624 else:
2625 raise ValueError("version_info %r not valid" % (version_info,))
2626
2627- version_string = '%d.%d.%d.%s.%d' % tuple(version_info)
2628 return main_version + sub_string
2629
2630
2631
2632=== modified file 'bzrlib/_bencode_pyx.pyx'
2633--- bzrlib/_bencode_pyx.pyx 2009-06-05 01:48:32 +0000
2634+++ bzrlib/_bencode_pyx.pyx 2009-11-03 09:40:55 +0000
2635@@ -58,6 +58,13 @@
2636 void D_UPDATE_TAIL(Decoder, int n)
2637 void E_UPDATE_TAIL(Encoder, int n)
2638
2639+# To maintain compatibility with older versions of pyrex, we have to use the
2640+# relative import here, rather than 'bzrlib._static_tuple_c'
2641+from _static_tuple_c cimport StaticTuple, StaticTuple_CheckExact, \
2642+ import_static_tuple_c
2643+
2644+import_static_tuple_c()
2645+
2646
2647 cdef class Decoder:
2648 """Bencode decoder"""
2649@@ -371,7 +378,8 @@
2650 self._encode_int(x)
2651 elif PyLong_CheckExact(x):
2652 self._encode_long(x)
2653- elif PyList_CheckExact(x) or PyTuple_CheckExact(x):
2654+ elif (PyList_CheckExact(x) or PyTuple_CheckExact(x)
2655+ or StaticTuple_CheckExact(x)):
2656 self._encode_list(x)
2657 elif PyDict_CheckExact(x):
2658 self._encode_dict(x)
2659
2660=== modified file 'bzrlib/_btree_serializer_pyx.pyx'
2661--- bzrlib/_btree_serializer_pyx.pyx 2009-06-22 12:52:39 +0000
2662+++ bzrlib/_btree_serializer_pyx.pyx 2009-11-03 09:40:55 +0000
2663@@ -1,4 +1,4 @@
2664-# Copyright (C) 2008 Canonical Ltd
2665+# Copyright (C) 2008, 2009 Canonical Ltd
2666 #
2667 # This program is free software; you can redistribute it and/or modify
2668 # it under the terms of the GNU General Public License as published by
2669@@ -38,11 +38,16 @@
2670 Py_ssize_t PyString_Size(object p)
2671 Py_ssize_t PyString_GET_SIZE_ptr "PyString_GET_SIZE" (PyObject *)
2672 char * PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *)
2673+ char * PyString_AS_STRING(object)
2674+ Py_ssize_t PyString_GET_SIZE(object)
2675 int PyString_AsStringAndSize_ptr(PyObject *, char **buf, Py_ssize_t *len)
2676 void PyString_InternInPlace(PyObject **)
2677 int PyTuple_CheckExact(object t)
2678+ object PyTuple_New(Py_ssize_t n_entries)
2679+ void PyTuple_SET_ITEM(object, Py_ssize_t offset, object) # steals the ref
2680 Py_ssize_t PyTuple_GET_SIZE(object t)
2681 PyObject *PyTuple_GET_ITEM_ptr_object "PyTuple_GET_ITEM" (object tpl, int index)
2682+ void Py_INCREF(object)
2683 void Py_DECREF_ptr "Py_DECREF" (PyObject *)
2684
2685 cdef extern from "string.h":
2686@@ -52,6 +57,12 @@
2687 # void *memrchr(void *s, int c, size_t n)
2688 int strncmp(char *s1, char *s2, size_t n)
2689
2690+# It seems we need to import the definitions so that the pyrex compiler has
2691+# local names to access them.
2692+from _static_tuple_c cimport StaticTuple, \
2693+ import_static_tuple_c, StaticTuple_New, \
2694+ StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact
2695+
2696
2697 # TODO: Find some way to import this from _dirstate_helpers
2698 cdef void* _my_memrchr(void *s, int c, size_t n):
2699@@ -68,6 +79,7 @@
2700 pos = pos - 1
2701 return NULL
2702
2703+
2704 # TODO: Import this from _dirstate_helpers when it is merged
2705 cdef object safe_string_from_size(char *s, Py_ssize_t size):
2706 if size < 0:
2707@@ -91,6 +103,10 @@
2708 Py_DECREF_ptr(py_str)
2709 return result
2710
2711+from bzrlib import _static_tuple_c
2712+# This sets up the StaticTuple C_API functionality
2713+import_static_tuple_c()
2714+
2715
2716 cdef class BTreeLeafParser:
2717 """Parse the leaf nodes of a BTree index.
2718@@ -130,6 +146,7 @@
2719 self._cur_str = NULL
2720 self._end_str = NULL
2721 self._header_found = 0
2722+ # keys are tuples
2723
2724 cdef extract_key(self, char * last):
2725 """Extract a key.
2726@@ -139,15 +156,14 @@
2727 """
2728 cdef char *temp_ptr
2729 cdef int loop_counter
2730- # keys are tuples
2731- loop_counter = 0
2732- key_segments = []
2733- while loop_counter < self.key_length:
2734- loop_counter = loop_counter + 1
2735+ cdef StaticTuple key
2736+
2737+ key = StaticTuple_New(self.key_length)
2738+ for loop_counter from 0 <= loop_counter < self.key_length:
2739 # grab a key segment
2740 temp_ptr = <char*>memchr(self._start, c'\0', last - self._start)
2741 if temp_ptr == NULL:
2742- if loop_counter == self.key_length:
2743+ if loop_counter + 1 == self.key_length:
2744 # capture to last
2745 temp_ptr = last
2746 else:
2747@@ -157,15 +173,20 @@
2748 last - self._start)))
2749 raise AssertionError(failure_string)
2750 # capture the key string
2751- # TODO: Consider using PyIntern_FromString, the only caveat is that
2752- # it assumes a NULL-terminated string, so we have to check if
2753- # temp_ptr[0] == c'\0' or some other char.
2754- key_element = safe_interned_string_from_size(self._start,
2755+ if (self.key_length == 1
2756+ and (temp_ptr - self._start) == 45
2757+ and strncmp(self._start, 'sha1:', 5) == 0):
2758+ key_element = safe_string_from_size(self._start,
2759+ temp_ptr - self._start)
2760+ else:
2761+ key_element = safe_interned_string_from_size(self._start,
2762 temp_ptr - self._start)
2763 # advance our pointer
2764 self._start = temp_ptr + 1
2765- PyList_Append(key_segments, key_element)
2766- return tuple(key_segments)
2767+ Py_INCREF(key_element)
2768+ StaticTuple_SET_ITEM(key, loop_counter, key_element)
2769+ key = StaticTuple_Intern(key)
2770+ return key
2771
2772 cdef int process_line(self) except -1:
2773 """Process a line in the bytes."""
2774@@ -174,6 +195,7 @@
2775 cdef char *ref_ptr
2776 cdef char *next_start
2777 cdef int loop_counter
2778+ cdef Py_ssize_t str_len
2779
2780 self._start = self._cur_str
2781 # Find the next newline
2782@@ -186,14 +208,13 @@
2783 # And the next string is right after it
2784 self._cur_str = last + 1
2785 # The last character is right before the '\n'
2786- last = last
2787
2788 if last == self._start:
2789 # parsed it all.
2790 return 0
2791 if last < self._start:
2792 # Unexpected error condition - fail
2793- return -1
2794+ raise AssertionError("last < self._start")
2795 if 0 == self._header_found:
2796 # The first line in a leaf node is the header "type=leaf\n"
2797 if strncmp("type=leaf", self._start, last - self._start) == 0:
2798@@ -202,36 +223,48 @@
2799 else:
2800 raise AssertionError('Node did not start with "type=leaf": %r'
2801 % (safe_string_from_size(self._start, last - self._start)))
2802- return -1
2803
2804 key = self.extract_key(last)
2805 # find the value area
2806 temp_ptr = <char*>_my_memrchr(self._start, c'\0', last - self._start)
2807 if temp_ptr == NULL:
2808 # Invalid line
2809- return -1
2810+ raise AssertionError("Failed to find the value area")
2811 else:
2812- # capture the value string
2813- value = safe_string_from_size(temp_ptr + 1, last - temp_ptr - 1)
2814+ # Because of how conversions were done, we ended up with *lots* of
2815+ # values that are identical. These are all of the 0-length nodes
2816+ # that are referred to by the TREE_ROOT (and likely some other
2817+ # directory nodes.) For example, bzr has 25k references to
2818+ # something like '12607215 328306 0 0', which ends up consuming 1MB
2819+ # of memory, just for those strings.
2820+ str_len = last - temp_ptr - 1
2821+ if (str_len > 4
2822+ and strncmp(" 0 0", last - 4, 4) == 0):
2823+ # This drops peak mem for bzr.dev from 87.4MB => 86.2MB
2824+ # For Launchpad 236MB => 232MB
2825+ value = safe_interned_string_from_size(temp_ptr + 1, str_len)
2826+ else:
2827+ value = safe_string_from_size(temp_ptr + 1, str_len)
2828 # shrink the references end point
2829 last = temp_ptr
2830+
2831 if self.ref_list_length:
2832- ref_lists = []
2833+ ref_lists = StaticTuple_New(self.ref_list_length)
2834 loop_counter = 0
2835 while loop_counter < self.ref_list_length:
2836 ref_list = []
2837 # extract a reference list
2838 loop_counter = loop_counter + 1
2839 if last < self._start:
2840- return -1
2841+ raise AssertionError("last < self._start")
2842 # find the next reference list end point:
2843 temp_ptr = <char*>memchr(self._start, c'\t', last - self._start)
2844 if temp_ptr == NULL:
2845 # Only valid for the last list
2846 if loop_counter != self.ref_list_length:
2847 # Invalid line
2848- return -1
2849- raise AssertionError("invalid key")
2850+ raise AssertionError(
2851+ "invalid key, loop_counter != self.ref_list_length")
2852 else:
2853 # scan to the end of the ref list area
2854 ref_ptr = last
2855@@ -248,18 +281,20 @@
2856 if temp_ptr == NULL:
2857 # key runs to the end
2858 temp_ptr = ref_ptr
2859+
2860 PyList_Append(ref_list, self.extract_key(temp_ptr))
2861- PyList_Append(ref_lists, tuple(ref_list))
2862+ ref_list = StaticTuple_Intern(StaticTuple(*ref_list))
2863+ Py_INCREF(ref_list)
2864+ StaticTuple_SET_ITEM(ref_lists, loop_counter - 1, ref_list)
2865 # prepare for the next reference list
2866 self._start = next_start
2867- ref_lists = tuple(ref_lists)
2868- node_value = (value, ref_lists)
2869+ node_value = StaticTuple(value, ref_lists)
2870 else:
2871 if last != self._start:
2872 # unexpected reference data present
2873- return -1
2874- node_value = (value, ())
2875- PyList_Append(self.keys, (key, node_value))
2876+ raise AssertionError("unexpected reference data present")
2877+ node_value = StaticTuple(value, StaticTuple())
2878+ PyList_Append(self.keys, StaticTuple(key, node_value))
2879 return 0
2880
2881 def parse(self):
2882@@ -294,7 +329,6 @@
2883 cdef Py_ssize_t flat_len
2884 cdef Py_ssize_t key_len
2885 cdef Py_ssize_t node_len
2886- cdef PyObject * val
2887 cdef char * value
2888 cdef Py_ssize_t value_len
2889 cdef char * out
2890@@ -303,13 +337,12 @@
2891 cdef int first_ref_list
2892 cdef int first_reference
2893 cdef int i
2894- cdef PyObject *ref_bit
2895 cdef Py_ssize_t ref_bit_len
2896
2897- if not PyTuple_CheckExact(node):
2898- raise TypeError('We expected a tuple() for node not: %s'
2899+ if not PyTuple_CheckExact(node) and not StaticTuple_CheckExact(node):
2900+ raise TypeError('We expected a tuple() or StaticTuple() for node not: %s'
2901 % type(node))
2902- node_len = PyTuple_GET_SIZE(node)
2903+ node_len = len(node)
2904 have_reference_lists = reference_lists
2905 if have_reference_lists:
2906 if node_len != 4:
2907@@ -318,8 +351,17 @@
2908 elif node_len < 3:
2909 raise ValueError('Without ref_lists, we need at least 3 entries not: %s'
2910 % len(node))
2911- # I don't expect that we can do faster than string.join()
2912- string_key = '\0'.join(<object>PyTuple_GET_ITEM_ptr_object(node, 1))
2913+ # TODO: We can probably do better than string.join(), namely
2914+ # when key has only 1 item, we can just grab that string
2915+ # And when there are 2 items, we could do a single malloc + len() + 1
2916+ # also, doing .join() requires a PyObject_GetAttrString call, which
2917+ # we could also avoid.
2918+ # TODO: Note that pyrex 0.9.6 generates fairly crummy code here, using the
2919+ # python object interface, versus 0.9.8+ which uses a helper that
2920+ # checks if this supports the sequence interface.
2921+ # We *could* do more work on our own, and grab the actual items
2922+ # lists. For now, just ask people to use a better compiler. :)
2923+ string_key = '\0'.join(node[1])
2924
2925 # TODO: instead of using string joins, precompute the final string length,
2926 # and then malloc a single string and copy everything in.
2927@@ -336,7 +378,7 @@
2928 refs_len = 0
2929 if have_reference_lists:
2930 # Figure out how many bytes it will take to store the references
2931- ref_lists = <object>PyTuple_GET_ITEM_ptr_object(node, 3)
2932+ ref_lists = node[3]
2933 next_len = len(ref_lists) # TODO: use a Py function
2934 if next_len > 0:
2935 # If there are no nodes, we don't need to do any work
2936@@ -350,31 +392,31 @@
2937 # references
2938 refs_len = refs_len + (next_len - 1)
2939 for reference in ref_list:
2940- if not PyTuple_CheckExact(reference):
2941+ if (not PyTuple_CheckExact(reference)
2942+ and not StaticTuple_CheckExact(reference)):
2943 raise TypeError(
2944 'We expect references to be tuples not: %s'
2945 % type(reference))
2946- next_len = PyTuple_GET_SIZE(reference)
2947+ next_len = len(reference)
2948 if next_len > 0:
2949 # We will need (len - 1) '\x00' characters to
2950 # separate the reference key
2951 refs_len = refs_len + (next_len - 1)
2952- for i from 0 <= i < next_len:
2953- ref_bit = PyTuple_GET_ITEM_ptr_object(reference, i)
2954- if not PyString_CheckExact_ptr(ref_bit):
2955+ for ref_bit in reference:
2956+ if not PyString_CheckExact(ref_bit):
2957 raise TypeError('We expect reference bits'
2958 ' to be strings not: %s'
2959 % type(<object>ref_bit))
2960- refs_len = refs_len + PyString_GET_SIZE_ptr(ref_bit)
2961+ refs_len = refs_len + PyString_GET_SIZE(ref_bit)
2962
2963 # So we have the (key NULL refs NULL value LF)
2964 key_len = PyString_Size(string_key)
2965- val = PyTuple_GET_ITEM_ptr_object(node, 2)
2966- if not PyString_CheckExact_ptr(val):
2967+ val = node[2]
2968+ if not PyString_CheckExact(val):
2969 raise TypeError('Expected a plain str for value not: %s'
2970- % type(<object>val))
2971- value = PyString_AS_STRING_ptr(val)
2972- value_len = PyString_GET_SIZE_ptr(val)
2973+ % type(val))
2974+ value = PyString_AS_STRING(val)
2975+ value_len = PyString_GET_SIZE(val)
2976 flat_len = (key_len + 1 + refs_len + 1 + value_len + 1)
2977 line = PyString_FromStringAndSize(NULL, flat_len)
2978 # Get a pointer to the new buffer
2979@@ -396,14 +438,14 @@
2980 out[0] = c'\r'
2981 out = out + 1
2982 first_reference = 0
2983- next_len = PyTuple_GET_SIZE(reference)
2984+ next_len = len(reference)
2985 for i from 0 <= i < next_len:
2986 if i != 0:
2987 out[0] = c'\x00'
2988 out = out + 1
2989- ref_bit = PyTuple_GET_ITEM_ptr_object(reference, i)
2990- ref_bit_len = PyString_GET_SIZE_ptr(ref_bit)
2991- memcpy(out, PyString_AS_STRING_ptr(ref_bit), ref_bit_len)
2992+ ref_bit = reference[i]
2993+ ref_bit_len = PyString_GET_SIZE(ref_bit)
2994+ memcpy(out, PyString_AS_STRING(ref_bit), ref_bit_len)
2995 out = out + ref_bit_len
2996 out[0] = c'\0'
2997 out = out + 1
2998
2999=== modified file 'bzrlib/_chk_map_py.py'
3000--- bzrlib/_chk_map_py.py 2009-04-09 20:23:07 +0000
3001+++ bzrlib/_chk_map_py.py 2009-11-03 09:40:55 +0000
3002@@ -19,6 +19,8 @@
3003 import zlib
3004 import struct
3005
3006+from bzrlib.static_tuple import StaticTuple
3007+
3008 _LeafNode = None
3009 _InternalNode = None
3010 _unknown = None
3011@@ -93,7 +95,7 @@
3012 value_lines = lines[pos:pos+num_value_lines]
3013 pos += num_value_lines
3014 value = '\n'.join(value_lines)
3015- items[tuple(elements[:-1])] = value
3016+ items[StaticTuple.from_sequence(elements[:-1])] = value
3017 if len(items) != length:
3018 raise AssertionError("item count (%d) mismatch for key %s,"
3019 " bytes %r" % (length, key, bytes))
3020@@ -141,7 +143,7 @@
3021 for line in lines[5:]:
3022 line = common_prefix + line
3023 prefix, flat_key = line.rsplit('\x00', 1)
3024- items[prefix] = (flat_key,)
3025+ items[prefix] = StaticTuple(flat_key,)
3026 if len(items) == 0:
3027 raise AssertionError("We didn't find any item for %s" % key)
3028 result._items = items
3029@@ -155,4 +157,3 @@
3030 result._node_width = len(prefix)
3031 result._search_prefix = common_prefix
3032 return result
3033-
3034
3035=== modified file 'bzrlib/_chk_map_pyx.pyx'
3036--- bzrlib/_chk_map_pyx.pyx 2009-06-22 12:52:39 +0000
3037+++ bzrlib/_chk_map_pyx.pyx 2009-11-03 09:40:54 +0000
3038@@ -29,9 +29,8 @@
3039
3040 cdef extern from "Python.h":
3041 ctypedef int Py_ssize_t # Required for older pyrex versions
3042- struct _PyObject:
3043+ ctypedef struct PyObject:
3044 pass
3045- ctypedef _PyObject PyObject
3046 int PyTuple_CheckExact(object p)
3047 Py_ssize_t PyTuple_GET_SIZE(object t)
3048 int PyString_CheckExact(object)
3049@@ -52,6 +51,18 @@
3050 char *PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *s)
3051 object PyString_FromStringAndSize(char*, Py_ssize_t)
3052
3053+# cimport all of the definitions we will need to access
3054+from _static_tuple_c cimport StaticTuple,\
3055+ import_static_tuple_c, StaticTuple_New, \
3056+ StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact
3057+
3058+cdef extern from "_static_tuple_c.h":
3059+ # Defined explicitly rather than cimport-ing. Trying to use cimport, the
3060+ # type for PyObject is a different class that happens to have the same
3061+ # name...
3062+ PyObject * StaticTuple_GET_ITEM_ptr "StaticTuple_GET_ITEM" (StaticTuple,
3063+ Py_ssize_t)
3064+
3065 cdef extern from "zlib.h":
3066 ctypedef unsigned long uLong
3067 ctypedef unsigned int uInt
3068@@ -60,8 +71,14 @@
3069 uLong crc32(uLong crc, Bytef *buf, uInt len)
3070
3071
3072+# Set up the StaticTuple C_API functionality
3073+import_static_tuple_c()
3074+
3075+cdef object _LeafNode
3076 _LeafNode = None
3077+cdef object _InternalNode
3078 _InternalNode = None
3079+cdef object _unknown
3080 _unknown = None
3081
3082 # We shouldn't just copy this from _dirstate_helpers_pyx
3083@@ -91,9 +108,9 @@
3084 cdef char *c_out
3085 cdef PyObject *bit
3086
3087- if not PyTuple_CheckExact(key):
3088- raise TypeError('key %r is not a tuple' % (key,))
3089- num_bits = PyTuple_GET_SIZE(key)
3090+ if not StaticTuple_CheckExact(key):
3091+ raise TypeError('key %r is not a StaticTuple' % (key,))
3092+ num_bits = len(key)
3093 # 4 bytes per crc32, and another 1 byte between bits
3094 num_out_bytes = (9 * num_bits) - 1
3095 out = PyString_FromStringAndSize(NULL, num_out_bytes)
3096@@ -105,7 +122,7 @@
3097 # We use the _ptr variant, because GET_ITEM returns a borrowed
3098 # reference, and Pyrex assumes that returned 'object' are a new
3099 # reference
3100- bit = PyTuple_GET_ITEM_ptr(key, i)
3101+ bit = StaticTuple_GET_ITEM_ptr(key, i)
3102 if not PyString_CheckExact_ptr(bit):
3103 raise TypeError('Bit %d of %r is not a string' % (i, key))
3104 c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
3105@@ -129,9 +146,9 @@
3106 cdef char *c_out
3107 cdef PyObject *bit
3108
3109- if not PyTuple_CheckExact(key):
3110- raise TypeError('key %r is not a tuple' % (key,))
3111- num_bits = PyTuple_GET_SIZE(key)
3112+ if not StaticTuple_CheckExact(key):
3113+ raise TypeError('key %r is not a StaticTuple' % (key,))
3114+ num_bits = len(key)
3115 # 4 bytes per crc32, and another 1 byte between bits
3116 num_out_bytes = (5 * num_bits) - 1
3117 out = PyString_FromStringAndSize(NULL, num_out_bytes)
3118@@ -140,10 +157,10 @@
3119 if i > 0:
3120 c_out[0] = c'\x00'
3121 c_out = c_out + 1
3122- bit = PyTuple_GET_ITEM_ptr(key, i)
3123+ bit = StaticTuple_GET_ITEM_ptr(key, i)
3124 if not PyString_CheckExact_ptr(bit):
3125- raise TypeError('Bit %d of %r is not a string: %r' % (i, key,
3126- <object>bit))
3127+ raise TypeError('Bit %d of %r is not a string: %r'
3128+ % (i, key, <object>bit))
3129 c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
3130 c_len = PyString_GET_SIZE_ptr(bit)
3131 crc_val = crc32(0, c_bit, c_len)
3132@@ -195,6 +212,7 @@
3133 cdef char *prefix, *value_start, *prefix_tail
3134 cdef char *next_null, *last_null, *line_start
3135 cdef char *c_entry, *entry_start
3136+ cdef StaticTuple entry_bits
3137
3138 if _LeafNode is None:
3139 from bzrlib import chk_map
3140@@ -265,12 +283,14 @@
3141 if next_line == NULL:
3142 raise ValueError('missing trailing newline')
3143 cur = next_line + 1
3144- entry_bits = PyTuple_New(width)
3145+ entry_bits = StaticTuple_New(width)
3146 for i from 0 <= i < num_prefix_bits:
3147+ # TODO: Use PyList_GetItem, or turn prefix_bits into a
3148+ # tuple/StaticTuple
3149 entry = prefix_bits[i]
3150 # SET_ITEM 'steals' a reference
3151 Py_INCREF(entry)
3152- PyTuple_SET_ITEM(entry_bits, i, entry)
3153+ StaticTuple_SET_ITEM(entry_bits, i, entry)
3154 value = PyString_FromStringAndSize(value_start, next_line - value_start)
3155 # The next entry bit needs the 'tail' from the prefix, and first part
3156 # of the line
3157@@ -288,7 +308,7 @@
3158 memcpy(c_entry + prefix_tail_len, line_start, next_null - line_start)
3159 Py_INCREF(entry)
3160 i = num_prefix_bits
3161- PyTuple_SET_ITEM(entry_bits, i, entry)
3162+ StaticTuple_SET_ITEM(entry_bits, i, entry)
3163 while next_null != last_null: # We have remaining bits
3164 i = i + 1
3165 if i > width:
3166@@ -301,11 +321,12 @@
3167 entry = PyString_FromStringAndSize(entry_start,
3168 next_null - entry_start)
3169 Py_INCREF(entry)
3170- PyTuple_SET_ITEM(entry_bits, i, entry)
3171+ StaticTuple_SET_ITEM(entry_bits, i, entry)
3172 if len(entry_bits) != width:
3173 raise AssertionError(
3174 'Incorrect number of elements (%d vs %d)'
3175 % (len(entry_bits)+1, width + 1))
3176+ entry_bits = StaticTuple_Intern(entry_bits)
3177 PyDict_SetItem(items, entry_bits, value)
3178 if len(items) != length:
3179 raise ValueError("item count (%d) mismatch for key %s,"
3180@@ -343,6 +364,8 @@
3181 _unknown = chk_map._unknown
3182 result = _InternalNode(search_key_func=search_key_func)
3183
3184+ if not StaticTuple_CheckExact(key):
3185+ raise TypeError('key %r is not a StaticTuple' % (key,))
3186 if not PyString_CheckExact(bytes):
3187 raise TypeError('bytes must be a plain string not %s' % (type(bytes),))
3188
3189@@ -384,7 +407,8 @@
3190 memcpy(c_item_prefix + prefix_length, cur, next_null - cur)
3191 flat_key = PyString_FromStringAndSize(next_null + 1,
3192 next_line - next_null - 1)
3193- PyDict_SetItem(items, item_prefix, (flat_key,))
3194+ flat_key = StaticTuple(flat_key).intern()
3195+ PyDict_SetItem(items, item_prefix, flat_key)
3196 cur = next_line + 1
3197 assert len(items) > 0
3198 result._items = items
3199@@ -398,4 +422,3 @@
3200 result._node_width = len(item_prefix)
3201 result._search_prefix = PyString_FromStringAndSize(prefix, prefix_length)
3202 return result
3203-
3204
3205=== modified file 'bzrlib/_dirstate_helpers_pyx.pyx'
3206--- bzrlib/_dirstate_helpers_pyx.pyx 2009-08-28 05:00:33 +0000
3207+++ bzrlib/_dirstate_helpers_pyx.pyx 2009-11-03 09:40:54 +0000
3208@@ -1202,7 +1202,9 @@
3209 content_change = 0
3210 target_exec = False
3211 else:
3212- raise Exception, "unknown kind %s" % path_info[2]
3213+ if path is None:
3214+ path = self.pathjoin(old_dirname, old_basename)
3215+ raise errors.BadFileKindError(path, path_info[2])
3216 if source_minikind == c'd':
3217 if path is None:
3218 old_path = path = self.pathjoin(old_dirname, old_basename)
3219
3220=== added file 'bzrlib/_export_c_api.h'
3221--- bzrlib/_export_c_api.h 1970-01-01 00:00:00 +0000
3222+++ bzrlib/_export_c_api.h 2009-11-03 09:40:54 +0000
3223@@ -0,0 +1,104 @@
3224+/* Copyright (C) 2009 Canonical Ltd
3225+ *
3226+ * This program is free software; you can redistribute it and/or modify
3227+ * it under the terms of the GNU General Public License as published by
3228+ * the Free Software Foundation; either version 2 of the License, or
3229+ * (at your option) any later version.
3230+ *
3231+ * This program is distributed in the hope that it will be useful,
3232+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3233+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3234+ * GNU General Public License for more details.
3235+ *
3236+ * You should have received a copy of the GNU General Public License
3237+ * along with this program; if not, write to the Free Software
3238+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3239+ */
3240+
3241+
3242+/* This file contains helper functions for exporting a C API for a CPython
3243+ * extension module.
3244+ */
3245+
3246+#ifndef _EXPORT_C_API_H_
3247+#define _EXPORT_C_API_H_
3248+
3249+static const char *_C_API_NAME = "_C_API";
3250+
3251+/**
3252+ * Add a C function to the modules _C_API
3253+ * This wraps the function in a PyCObject, and inserts that into a dict.
3254+ * The key of the dict is the function name, and the description is the
3255+ * signature of the function.
3256+ * This is generally called during a modules init_MODULE function.
3257+ *
3258+ * @param module A Python module (the one being initialized)
3259+ * @param funcname The name of the function being exported
3260+ * @param func A pointer to the function
3261+ * @param signature The C signature of the function
3262+ * @return 0 if everything is successful, -1 if there is a problem. An
3263+ * exception should also be set
3264+ */
3265+static int
3266+_export_function(PyObject *module, char *funcname, void *func, char *signature)
3267+{
3268+ PyObject *d = NULL;
3269+ PyObject *c_obj = NULL;
3270+
3271+ /* (char *) is because python2.4 declares this api as 'char *' rather than
3272+ * const char* which it really is.
3273+ */
3274+ d = PyObject_GetAttrString(module, (char *)_C_API_NAME);
3275+ if (!d) {
3276+ PyErr_Clear();
3277+ d = PyDict_New();
3278+ if (!d)
3279+ goto bad;
3280+ Py_INCREF(d);
3281+ if (PyModule_AddObject(module, (char *)_C_API_NAME, d) < 0)
3282+ goto bad;
3283+ }
3284+ c_obj = PyCObject_FromVoidPtrAndDesc(func, signature, 0);
3285+ if (!c_obj)
3286+ goto bad;
3287+ if (PyDict_SetItemString(d, funcname, c_obj) < 0)
3288+ goto bad;
3289+ Py_DECREF(d);
3290+ return 0;
3291+bad:
3292+ Py_XDECREF(c_obj);
3293+ Py_XDECREF(d);
3294+ return -1;
3295+}
3296+
3297+/* Note:
3298+ * It feels like more could be done here. Specifically, if you look at
3299+ * _static_tuple_c.h you can see some boilerplate where we have:
3300+ * #ifdef STATIC_TUPLE_MODULE // are we exporting or importing
3301+ * static RETVAL FUNCNAME PROTO;
3302+ * #else
3303+ * static RETVAL (*FUNCNAME) PROTO;
3304+ * #endif
3305+ *
3306+ * And then in _static_tuple_c.c we have
3307+ * int setup_c_api()
3308+ * {
3309+ * _export_function(module, #FUNCNAME, FUNCNAME, #PROTO);
3310+ * }
3311+ *
3312+ * And then in _static_tuple_c.h import_##MODULE
3313+ * struct function_definition functions[] = {
3314+ * {#FUNCNAME, (void **)&FUNCNAME, #RETVAL #PROTO},
3315+ * ...
3316+ * {NULL}};
3317+ *
3318+ * And some similar stuff for types. However, this would mean that we would
3319+ * need a way for the C preprocessor to build up a list of definitions to be
3320+ * generated, and then expand that list at the appropriate time.
3321+ * I would guess there would be a way to do this, but probably not without a
3322+ * lot of magic, and the end result probably wouldn't be very pretty to
3323+ * maintain. Perhaps python's dynamic nature has left me jaded about writing
3324+ * boilerplate....
3325+ */
3326+
3327+#endif // _EXPORT_C_API_H_
3328
3329=== added file 'bzrlib/_import_c_api.h'
3330--- bzrlib/_import_c_api.h 1970-01-01 00:00:00 +0000
3331+++ bzrlib/_import_c_api.h 2009-11-03 09:40:54 +0000
3332@@ -0,0 +1,189 @@
3333+/* Copyright (C) 2009 Canonical Ltd
3334+ *
3335+ * This program is free software; you can redistribute it and/or modify
3336+ * it under the terms of the GNU General Public License as published by
3337+ * the Free Software Foundation; either version 2 of the License, or
3338+ * (at your option) any later version.
3339+ *
3340+ * This program is distributed in the hope that it will be useful,
3341+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
3342+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3343+ * GNU General Public License for more details.
3344+ *
3345+ * You should have received a copy of the GNU General Public License
3346+ * along with this program; if not, write to the Free Software
3347+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3348+ */
3349+
3350+#ifndef _IMPORT_C_API_H_
3351+#define _IMPORT_C_API_H_
3352+
3353+/**
3354+ * Helper functions to eliminate some of the boilerplate when importing a C API
3355+ * from a CPython extension module.
3356+ *
3357+ * For more information see _export_c_api.h
3358+ */
3359+
3360+static const char *_C_API_NAME = "_C_API";
3361+
3362+/**
3363+ * Import a function from the _C_API_NAME dict that is part of module.
3364+ *
3365+ * @param module The Python module we are importing from
3366+ * the attribute _C_API_NAME will be used as a dictionary
3367+ * containing the function pointer we are looking for.
3368+ * @param funcname Name of the function we want to import
3369+ * @param func A pointer to the function handle where we will store the
3370+ * function.
3371+ * @param signature The C signature of the function. This is validated
3372+ * against the signature stored in the C api, to make sure
3373+ * there is no versioning skew.
3374+ */
3375+static int _import_function(PyObject *module, const char *funcname,
3376+ void **func, const char *signature)
3377+{
3378+ PyObject *d = NULL;
3379+ PyObject *c_obj = NULL;
3380+ const char *desc = NULL;
3381+
3382+ /* (char *) because Python2.4 defines this as (char *) rather than
3383+ * (const char *)
3384+ */
3385+ d = PyObject_GetAttrString(module, (char *)_C_API_NAME);
3386+ if (!d) {
3387+ // PyObject_GetAttrString sets an appropriate exception
3388+ goto bad;
3389+ }
3390+ c_obj = PyDict_GetItemString(d, funcname);
3391+ if (!c_obj) {
3392+ // PyDict_GetItemString does not set an exception
3393+ PyErr_Format(PyExc_AttributeError,
3394+ "Module %s did not export a function named %s\n",
3395+ PyModule_GetName(module), funcname);
3396+ goto bad;
3397+ }
3398+ desc = (char *)PyCObject_GetDesc(c_obj);
3399+ if (!desc || strcmp(desc, signature) != 0) {
3400+ if (desc == NULL) {
3401+ desc = "<null>";
3402+ }
3403+ PyErr_Format(PyExc_TypeError,
3404+ "C function %s.%s has wrong signature (expected %s, got %s)",
3405+ PyModule_GetName(module), funcname, signature, desc);
3406+ goto bad;
3407+ }
3408+ *func = PyCObject_AsVoidPtr(c_obj);
3409+ Py_DECREF(d);
3410+ return 0;
3411+bad:
3412+ Py_XDECREF(d);
3413+ return -1;
3414+}
3415+
3416+
3417+/**
3418+ * Get a pointer to an exported PyTypeObject.
3419+ *
3420+ * @param module The Python module we are importing from
3421+ * @param class_name Attribute of the module that should reference the
3422+ * Type object. Note that a PyTypeObject is the python
3423+ * description of the type, not the raw C structure.
3424+ * @return A Pointer to the requested type object. On error NULL will be
3425+ * returned and an exception will be set.
3426+ */
3427+static PyTypeObject *
3428+_import_type(PyObject *module, const char *class_name)
3429+{
3430+ PyObject *type = NULL;
3431+
3432+ type = PyObject_GetAttrString(module, (char *)class_name);
3433+ if (!type) {
3434+ goto bad;
3435+ }
3436+ if (!PyType_Check(type)) {
3437+ PyErr_Format(PyExc_TypeError,
3438+ "%s.%s is not a type object",
3439+ PyModule_GetName(module), class_name);
3440+ goto bad;
3441+ }
3442+ return (PyTypeObject *)type;
3443+bad:
3444+ Py_XDECREF(type);
3445+ return NULL;
3446+}
3447+
3448+
3449+struct function_description
3450+{
3451+ const char *name;
3452+ void **pointer;
3453+ const char *signature;
3454+};
3455+
3456+struct type_description
3457+{
3458+ const char *name;
3459+ PyTypeObject **pointer;
3460+};
3461+
3462+/**
3463+ * Helper for importing several functions and types in a data-driven manner.
3464+ *
3465+ * @param module The name of the module we will be importing
3466+ * @param functions A list of function_description objects, describing the
3467+ * functions being imported.
3468+ * The list should be terminated with {NULL} to indicate
3469+ * there are no more functions to import.
3470+ * @param types A list of type_description objects describing type
3471+ * objects that we want to import. The list should be
3472+ * terminated with {NULL} to indicate there are no more
3473+ * types to import.
3474+ * @return 0 on success, -1 on error and an exception should be set.
3475+ */
3476+
3477+static int
3478+_import_extension_module(const char *module_name,
3479+ struct function_description *functions,
3480+ struct type_description *types)
3481+{
3482+ PyObject *module = NULL;
3483+ struct function_description *cur_func;
3484+ struct type_description *cur_type;
3485+ int ret_code;
3486+
3487+ module = PyImport_ImportModule((char *)module_name);
3488+ if (!module)
3489+ goto bad;
3490+ if (functions != NULL) {
3491+ cur_func = functions;
3492+ while (cur_func->name != NULL) {
3493+ ret_code = _import_function(module, cur_func->name,
3494+ cur_func->pointer,
3495+ cur_func->signature);
3496+ if (ret_code < 0)
3497+ goto bad;
3498+ cur_func++;
3499+ }
3500+ }
3501+ if (types != NULL) {
3502+ PyTypeObject *type_p = NULL;
3503+ cur_type = types;
3504+ while (cur_type->name != NULL) {
3505+ type_p = _import_type(module, cur_type->name);
3506+ if (type_p == NULL)
3507+ goto bad;
3508+ *(cur_type->pointer) = type_p;
3509+ cur_type++;
3510+ }
3511+ }
3512+
3513+ Py_XDECREF(module);
3514+ return 0;
3515+bad:
3516+ Py_XDECREF(module);
3517+ return -1;
3518+}
3519+
3520+
3521+#endif // _IMPORT_C_API_H_
3522
3523=== modified file 'bzrlib/_known_graph_py.py'
3524--- bzrlib/_known_graph_py.py 2009-08-25 18:45:40 +0000
3525+++ bzrlib/_known_graph_py.py 2009-11-03 09:40:55 +0000
3526@@ -281,3 +281,26 @@
3527 in tsort.merge_sort(as_parent_map, tip_key,
3528 mainline_revisions=None,
3529 generate_revno=True)]
3530+
3531+ def get_parent_keys(self, key):
3532+ """Get the parents for a key
3533+
3534+ Returns a list containg the parents keys. If the key is a ghost,
3535+ None is returned. A KeyError will be raised if the key is not in
3536+ the graph.
3537+
3538+ :param keys: Key to check (eg revision_id)
3539+ :return: A list of parents
3540+ """
3541+ return self._nodes[key].parent_keys
3542+
3543+ def get_child_keys(self, key):
3544+ """Get the children for a key
3545+
3546+ Returns a list containg the children keys. A KeyError will be raised
3547+ if the key is not in the graph.
3548+
3549+ :param keys: Key to check (eg revision_id)
3550+ :return: A list of children
3551+ """
3552+ return self._nodes[key].child_keys
3553
3554=== modified file 'bzrlib/_known_graph_pyx.pyx'
3555--- bzrlib/_known_graph_pyx.pyx 2009-09-02 13:32:52 +0000
3556+++ bzrlib/_known_graph_pyx.pyx 2009-11-03 09:40:54 +0000
3557@@ -88,6 +88,18 @@
3558 PyList_Append(keys, child.key)
3559 return keys
3560
3561+ property parent_keys:
3562+ def __get__(self):
3563+ if self.parents is None:
3564+ return None
3565+
3566+ cdef _KnownGraphNode parent
3567+
3568+ keys = []
3569+ for parent in self.parents:
3570+ PyList_Append(keys, parent.key)
3571+ return keys
3572+
3573 cdef clear_references(self):
3574 self.parents = None
3575 self.children = None
3576@@ -549,6 +561,29 @@
3577 # shown a specific impact, yet.
3578 sorter = _MergeSorter(self, tip_key)
3579 return sorter.topo_order()
3580+
3581+ def get_parent_keys(self, key):
3582+ """Get the parents for a key
3583+
3584+ Returns a list containg the parents keys. If the key is a ghost,
3585+ None is returned. A KeyError will be raised if the key is not in
3586+ the graph.
3587+
3588+ :param keys: Key to check (eg revision_id)
3589+ :return: A list of parents
3590+ """
3591+ return self._nodes[key].parent_keys
3592+
3593+ def get_child_keys(self, key):
3594+ """Get the children for a key
3595+
3596+ Returns a list containg the children keys. A KeyError will be raised
3597+ if the key is not in the graph.
3598+
3599+ :param keys: Key to check (eg revision_id)
3600+ :return: A list of children
3601+ """
3602+ return self._nodes[key].child_keys
3603
3604
3605 cdef class _MergeSortNode:
3606
3607=== modified file 'bzrlib/_patiencediff_c.c'
3608--- bzrlib/_patiencediff_c.c 2009-03-23 14:59:43 +0000
3609+++ bzrlib/_patiencediff_c.c 2009-11-03 09:40:55 +0000
3610@@ -298,7 +298,7 @@
3611 apos = SENTINEL;
3612 /* loop through all lines in the linked list */
3613 for (i = h[equiv].a_pos; i != SENTINEL; i = lines_a[i].next) {
3614- /* the index is lower than alo, the the next line */
3615+ /* the index is lower than alo, continue to the next line */
3616 if (i < alo) {
3617 h[equiv].a_pos = i;
3618 continue;
3619@@ -319,7 +319,7 @@
3620 /* check for duplicates of this line in lines_b[blo:bhi] */
3621 /* loop through all lines in the linked list */
3622 for (i = h[equiv].b_pos; i != SENTINEL; i = lines_b[i].next) {
3623- /* the index is lower than blo, the the next line */
3624+ /* the index is lower than blo, continue to the next line */
3625 if (i < blo) {
3626 h[equiv].b_pos = i;
3627 continue;
3628
3629=== modified file 'bzrlib/_readdir_pyx.pyx'
3630--- bzrlib/_readdir_pyx.pyx 2009-07-27 04:24:36 +0000
3631+++ bzrlib/_readdir_pyx.pyx 2009-11-03 09:40:54 +0000
3632@@ -343,8 +343,10 @@
3633 raise OSError(errno, "lstat: " + strerror(errno),
3634 path + "/" + entry.d_name)
3635 else:
3636- kind = _missing
3637- statvalue = None
3638+ # the file seems to have disappeared after being
3639+ # seen by readdir - perhaps a transient temporary
3640+ # file. there's no point returning it.
3641+ continue
3642 # We append a 5-tuple that can be modified in-place by the C
3643 # api:
3644 # inode to sort on (to replace with top_path)
3645
3646=== added file 'bzrlib/_simple_set_pyx.pxd'
3647--- bzrlib/_simple_set_pyx.pxd 1970-01-01 00:00:00 +0000
3648+++ bzrlib/_simple_set_pyx.pxd 2009-11-03 09:40:54 +0000
3649@@ -0,0 +1,91 @@
3650+# Copyright (C) 2009 Canonical Ltd
3651+#
3652+# This program is free software; you can redistribute it and/or modify
3653+# it under the terms of the GNU General Public License as published by
3654+# the Free Software Foundation; either version 2 of the License, or
3655+# (at your option) any later version.
3656+#
3657+# This program is distributed in the hope that it will be useful,
3658+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3659+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3660+# GNU General Public License for more details.
3661+#
3662+# You should have received a copy of the GNU General Public License
3663+# along with this program; if not, write to the Free Software
3664+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3665+
3666+"""Interface definition of a class like PySet but without caching the hash.
3667+
3668+This is generally useful when you want to 'intern' objects, etc. Note that this
3669+differs from Set in that we:
3670+ 1) Don't have all of the .intersection, .difference, etc functions
3671+ 2) Do return the object from the set via queries
3672+ eg. SimpleSet.add(key) => saved_key and SimpleSet[key] => saved_key
3673+"""
3674+
3675+cdef extern from "Python.h":
3676+ ctypedef struct PyObject:
3677+ pass
3678+
3679+
3680+cdef public api class SimpleSet [object SimpleSetObject, type SimpleSet_Type]:
3681+ """A class similar to PySet, but with simpler implementation.
3682+
3683+ The main advantage is that this class uses only 2N memory to store N
3684+ objects rather than 4N memory. The main trade-off is that we do not cache
3685+ the hash value of saved objects. As such, it is assumed that computing the
3686+ hash will be cheap (such as strings or tuples of strings, etc.)
3687+
3688+ This also differs in that you can get back the objects that are stored
3689+ (like a dict), but we also don't implement the complete list of 'set'
3690+ operations (difference, intersection, etc).
3691+ """
3692+ # Data structure definition:
3693+ # This is a basic hash table using open addressing.
3694+ # http://en.wikipedia.org/wiki/Open_addressing
3695+ # Basically that means we keep an array of pointers to Python objects
3696+ # (called a table). Each location in the array is called a 'slot'.
3697+ #
3698+ # An empty slot holds a NULL pointer, a slot where there was an item
3699+ # which was then deleted will hold a pointer to _dummy, and a filled slot
3700+ # points at the actual object which fills that slot.
3701+ #
3702+ # The table is always a power of two, and the default location where an
3703+ # object is inserted is at hash(object) & (table_size - 1)
3704+ #
3705+ # If there is a collision, then we search for another location. The
3706+ # specific algorithm is in _lookup. We search until we:
3707+ # find the object
3708+ # find an equivalent object (by tp_richcompare(obj1, obj2, Py_EQ))
3709+ # find a NULL slot
3710+ #
3711+ # When an object is deleted, we set its slot to _dummy. this way we don't
3712+ # have to track whether there was a collision, and find the corresponding
3713+ # keys. (The collision resolution algorithm makes that nearly impossible
3714+ # anyway, because it depends on the upper bits of the hash.)
3715+ # The main effect of this, is that if we find _dummy, then we can insert
3716+ # an object there, but we have to keep searching until we find NULL to
3717+ # know that the object is not present elsewhere.
3718+
3719+ cdef Py_ssize_t _used # active
3720+ cdef Py_ssize_t _fill # active + dummy
3721+ cdef Py_ssize_t _mask # Table contains (mask+1) slots, a power of 2
3722+ cdef PyObject **_table # Pyrex/Cython doesn't support arrays to 'object'
3723+ # so we manage it manually
3724+
3725+ cdef PyObject *_get(self, object key) except? NULL
3726+ cdef object _add(self, key)
3727+ cdef int _discard(self, key) except -1
3728+ cdef int _insert_clean(self, PyObject *key) except -1
3729+ cdef Py_ssize_t _resize(self, Py_ssize_t min_unused) except -1
3730+
3731+
3732+# TODO: might want to export the C api here, though it is all available from
3733+# the class object...
3734+cdef api SimpleSet SimpleSet_New()
3735+cdef api object SimpleSet_Add(object self, object key)
3736+cdef api int SimpleSet_Contains(object self, object key) except -1
3737+cdef api int SimpleSet_Discard(object self, object key) except -1
3738+cdef api PyObject *SimpleSet_Get(SimpleSet self, object key) except? NULL
3739+cdef api Py_ssize_t SimpleSet_Size(object self) except -1
3740+cdef api int SimpleSet_Next(object self, Py_ssize_t *pos, PyObject **key)
3741
3742=== added file 'bzrlib/_simple_set_pyx.pyx'
3743--- bzrlib/_simple_set_pyx.pyx 1970-01-01 00:00:00 +0000
3744+++ bzrlib/_simple_set_pyx.pyx 2009-11-03 09:40:54 +0000
3745@@ -0,0 +1,590 @@
3746+# Copyright (C) 2009 Canonical Ltd
3747+#
3748+# This program is free software; you can redistribute it and/or modify
3749+# it under the terms of the GNU General Public License as published by
3750+# the Free Software Foundation; either version 2 of the License, or
3751+# (at your option) any later version.
3752+#
3753+# This program is distributed in the hope that it will be useful,
3754+# but WITHOUT ANY WARRANTY; without even the implied warranty of
3755+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3756+# GNU General Public License for more details.
3757+#
3758+# You should have received a copy of the GNU General Public License
3759+# along with this program; if not, write to the Free Software
3760+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
3761+
3762+"""Definition of a class that is similar to Set with some small changes."""
3763+
3764+cdef extern from "python-compat.h":
3765+ pass
3766+
3767+cdef extern from "Python.h":
3768+ ctypedef unsigned long size_t
3769+ ctypedef long (*hashfunc)(PyObject*) except -1
3770+ ctypedef object (*richcmpfunc)(PyObject *, PyObject *, int)
3771+ ctypedef int (*visitproc)(PyObject *, void *)
3772+ ctypedef int (*traverseproc)(PyObject *, visitproc, void *)
3773+ int Py_EQ
3774+ void Py_INCREF(PyObject *)
3775+ void Py_DECREF(PyObject *)
3776+ ctypedef struct PyTypeObject:
3777+ hashfunc tp_hash
3778+ richcmpfunc tp_richcompare
3779+ traverseproc tp_traverse
3780+
3781+ PyTypeObject *Py_TYPE(PyObject *)
3782+ # Note: *Don't* use hash(), Pyrex 0.9.8.5 thinks it returns an 'int', and
3783+ # thus silently truncates to 32-bits on 64-bit machines.
3784+ long PyObject_Hash(PyObject *) except -1
3785+
3786+ void *PyMem_Malloc(size_t nbytes)
3787+ void PyMem_Free(void *)
3788+ void memset(void *, int, size_t)
3789+
3790+
3791+# Dummy is an object used to mark nodes that have been deleted. Since
3792+# collisions require us to move a node to an alternative location, if we just
3793+# set an entry to NULL on delete, we won't find any relocated nodes.
3794+# We have to use _dummy_obj because we need to keep a refcount to it, but we
3795+# also use _dummy as a pointer, because it avoids having to put <PyObject*> all
3796+# over the code base.
3797+cdef object _dummy_obj
3798+cdef PyObject *_dummy
3799+_dummy_obj = object()
3800+_dummy = <PyObject *>_dummy_obj
3801+
3802+
3803+cdef object _NotImplemented
3804+_NotImplemented = NotImplemented
3805+
3806+
3807+cdef int _is_equal(PyObject *this, long this_hash, PyObject *other) except -1:
3808+ cdef long other_hash
3809+
3810+ if this == other:
3811+ return 1
3812+ other_hash = PyObject_Hash(other)
3813+ if other_hash != this_hash:
3814+ return 0
3815+
3816+ # This implements a subset of the PyObject_RichCompareBool functionality.
3817+ # Namely it:
3818+ # 1) Doesn't try to do anything with old-style classes
3819+ # 2) Assumes that both objects have a tp_richcompare implementation, and
3820+ # that if that is not enough to compare equal, then they are not
3821+ # equal. (It doesn't try to cast them both to some intermediate form
3822+ # that would compare equal.)
3823+ res = Py_TYPE(this).tp_richcompare(this, other, Py_EQ)
3824+ if res is _NotImplemented:
3825+ res = Py_TYPE(other).tp_richcompare(other, this, Py_EQ)
3826+ if res is _NotImplemented:
3827+ return 0
3828+ if res:
3829+ return 1
3830+ return 0
3831+
3832+
3833+cdef public api class SimpleSet [object SimpleSetObject, type SimpleSet_Type]:
3834+ """This class can be used to track canonical forms for objects.
3835+
3836+ It is similar in function to the interned dictionary that is used by
3837+ strings. However:
3838+
3839+ 1) It assumes that hash(obj) is cheap, so does not need to inline a copy
3840+ of it
3841+ 2) It only stores one reference to the object, rather than 2 (key vs
3842+ key:value)
3843+
3844+ As such, it uses 1/3rd the amount of memory to store a pointer to the
3845+ interned object.
3846+ """
3847+ # Attributes are defined in the .pxd file
3848+ DEF DEFAULT_SIZE=1024
3849+
3850+ def __init__(self):
3851+ cdef Py_ssize_t size, n_bytes
3852+
3853+ size = DEFAULT_SIZE
3854+ self._mask = size - 1
3855+ self._used = 0
3856+ self._fill = 0
3857+ n_bytes = sizeof(PyObject*) * size;
3858+ self._table = <PyObject **>PyMem_Malloc(n_bytes)
3859+ if self._table == NULL:
3860+ raise MemoryError()
3861+ memset(self._table, 0, n_bytes)
3862+
3863+ def __dealloc__(self):
3864+ if self._table != NULL:
3865+ PyMem_Free(self._table)
3866+ self._table = NULL
3867+
3868+ property used:
3869+ def __get__(self):
3870+ return self._used
3871+
3872+ property fill:
3873+ def __get__(self):
3874+ return self._fill
3875+
3876+ property mask:
3877+ def __get__(self):
3878+ return self._mask
3879+
3880+ def _memory_size(self):
3881+ """Return the number of bytes of memory consumed by this class."""
3882+ return sizeof(self) + (sizeof(PyObject*)*(self._mask + 1))
3883+
3884+ def __len__(self):
3885+ return self._used
3886+
3887+ def _test_lookup(self, key):
3888+ cdef PyObject **slot
3889+
3890+ slot = _lookup(self, key)
3891+ if slot[0] == NULL:
3892+ res = '<null>'
3893+ elif slot[0] == _dummy:
3894+ res = '<dummy>'
3895+ else:
3896+ res = <object>slot[0]
3897+ return <int>(slot - self._table), res
3898+
3899+ def __contains__(self, key):
3900+ """Is key present in this SimpleSet."""
3901+ cdef PyObject **slot
3902+
3903+ slot = _lookup(self, key)
3904+ if slot[0] == NULL or slot[0] == _dummy:
3905+ return False
3906+ return True
3907+
3908+ cdef PyObject *_get(self, object key) except? NULL:
3909+ """Return the object (or nothing) define at the given location."""
3910+ cdef PyObject **slot
3911+
3912+ slot = _lookup(self, key)
3913+ if slot[0] == NULL or slot[0] == _dummy:
3914+ return NULL
3915+ return slot[0]
3916+
3917+ def __getitem__(self, key):
3918+ """Return a stored item that is equivalent to key."""
3919+ cdef PyObject *py_val
3920+
3921+ py_val = self._get(key)
3922+ if py_val == NULL:
3923+ raise KeyError("Key %s is not present" % key)
3924+ val = <object>(py_val)
3925+ return val
3926+
3927+ cdef int _insert_clean(self, PyObject *key) except -1:
3928+ """Insert a key into self.table.
3929+
3930+ This is only meant to be used during times like '_resize',
3931+ as it makes a lot of assuptions about keys not already being present,
3932+ and there being no dummy entries.
3933+ """
3934+ cdef size_t i, n_lookup
3935+ cdef long the_hash
3936+ cdef PyObject **table, **slot
3937+ cdef Py_ssize_t mask
3938+
3939+ mask = self._mask
3940+ table = self._table
3941+
3942+ the_hash = PyObject_Hash(key)
3943+ i = the_hash
3944+ for n_lookup from 0 <= n_lookup <= <size_t>mask: # Don't loop forever
3945+ slot = &table[i & mask]
3946+ if slot[0] == NULL:
3947+ slot[0] = key
3948+ self._fill = self._fill + 1
3949+ self._used = self._used + 1
3950+ return 1
3951+ i = i + 1 + n_lookup
3952+ raise RuntimeError('ran out of slots.')
3953+
3954+ def _py_resize(self, min_used):
3955+ """Do not use this directly, it is only exposed for testing."""
3956+ return self._resize(min_used)
3957+
3958+ cdef Py_ssize_t _resize(self, Py_ssize_t min_used) except -1:
3959+ """Resize the internal table.
3960+
3961+ The final table will be big enough to hold at least min_used entries.
3962+ We will copy the data from the existing table over, leaving out dummy
3963+ entries.
3964+
3965+ :return: The new size of the internal table
3966+ """
3967+ cdef Py_ssize_t new_size, n_bytes, remaining
3968+ cdef PyObject **new_table, **old_table, **slot
3969+
3970+ new_size = DEFAULT_SIZE
3971+ while new_size <= min_used and new_size > 0:
3972+ new_size = new_size << 1
3973+ # We rolled over our signed size field
3974+ if new_size <= 0:
3975+ raise MemoryError()
3976+ # Even if min_used == self._mask + 1, and we aren't changing the actual
3977+ # size, we will still run the algorithm so that dummy entries are
3978+ # removed
3979+ # TODO: Test this
3980+ # if new_size < self._used:
3981+ # raise RuntimeError('cannot shrink SimpleSet to something'
3982+ # ' smaller than the number of used slots.')
3983+ n_bytes = sizeof(PyObject*) * new_size;
3984+ new_table = <PyObject **>PyMem_Malloc(n_bytes)
3985+ if new_table == NULL:
3986+ raise MemoryError()
3987+
3988+ old_table = self._table
3989+ self._table = new_table
3990+ memset(self._table, 0, n_bytes)
3991+ self._mask = new_size - 1
3992+ self._used = 0
3993+ remaining = self._fill
3994+ self._fill = 0
3995+
3996+ # Moving everything to the other table is refcount neutral, so we don't
3997+ # worry about it.
3998+ slot = old_table
3999+ while remaining > 0:
4000+ if slot[0] == NULL: # unused slot
4001+ pass
4002+ elif slot[0] == _dummy: # dummy slot
4003+ remaining = remaining - 1
4004+ else: # active slot
4005+ remaining = remaining - 1
4006+ self._insert_clean(slot[0])
4007+ slot = slot + 1
4008+ PyMem_Free(old_table)
4009+ return new_size
4010+
4011+ def add(self, key):
4012+ """Similar to set.add(), start tracking this key.
4013+
4014+ There is one small difference, which is that we return the object that
4015+ is stored at the given location. (which is closer to the
4016+ dict.setdefault() functionality.)
4017+ """
4018+ return self._add(key)
4019+
4020+ cdef object _add(self, key):
4021+ cdef PyObject **slot, *py_key
4022+ cdef int added
4023+
4024+ py_key = <PyObject *>key
4025+ if (Py_TYPE(py_key).tp_richcompare == NULL
4026+ or Py_TYPE(py_key).tp_hash == NULL):
4027+ raise TypeError('Types added to SimpleSet must implement'
4028+ ' both tp_richcompare and tp_hash')
4029+ added = 0
4030+ # We need at least one empty slot
4031+ assert self._used < self._mask
4032+ slot = _lookup(self, key)
4033+ if (slot[0] == NULL):
4034+ Py_INCREF(py_key)
4035+ self._fill = self._fill + 1
4036+ self._used = self._used + 1
4037+ slot[0] = py_key
4038+ added = 1
4039+ elif (slot[0] == _dummy):
4040+ Py_INCREF(py_key)
4041+ self._used = self._used + 1
4042+ slot[0] = py_key
4043+ added = 1
4044+ # No else: clause. If _lookup returns a pointer to
4045+ # a live object, then we already have a value at this location.
4046+ retval = <object>(slot[0])
4047+ # PySet and PyDict use a 2-3rds full algorithm, we'll follow suit
4048+ if added and (self._fill * 3) >= ((self._mask + 1) * 2):
4049+ # However, we always work for a load factor of 2:1
4050+ self._resize(self._used * 2)
4051+ # Even if we resized and ended up moving retval into a different slot,
4052+ # it is still the value that is held at the slot equivalent to 'key',
4053+ # so we can still return it
4054+ return retval
4055+
4056+ def discard(self, key):
4057+ """Remove key from the set, whether it exists or not.
4058+
4059+ :return: False if the item did not exist, True if it did
4060+ """
4061+ if self._discard(key):
4062+ return True
4063+ return False
4064+
4065+ cdef int _discard(self, key) except -1:
4066+ cdef PyObject **slot, *py_key
4067+
4068+ slot = _lookup(self, key)
4069+ if slot[0] == NULL or slot[0] == _dummy:
4070+ return 0
4071+ self._used = self._used - 1
4072+ Py_DECREF(slot[0])
4073+ slot[0] = _dummy
4074+ # PySet uses the heuristic: If more than 1/5 are dummies, then resize
4075+ # them away
4076+ # if ((so->_fill - so->_used) * 5 < so->mask)
4077+ # However, we are planning on using this as an interning structure, in
4078+ # which we will be putting a lot of objects. And we expect that large
4079+ # groups of them are going to have the same lifetime.
4080+ # Dummy entries hurt a little bit because they cause the lookup to keep
4081+ # searching, but resizing is also rather expensive
4082+ # For now, we'll just use their algorithm, but we may want to revisit
4083+ # it
4084+ if ((self._fill - self._used) * 5 > self._mask):
4085+ self._resize(self._used * 2)
4086+ return 1
4087+
4088+ def __iter__(self):
4089+ return _SimpleSet_iterator(self)
4090+
4091+
4092+cdef class _SimpleSet_iterator:
4093+ """Iterator over the SimpleSet structure."""
4094+
4095+ cdef Py_ssize_t pos
4096+ cdef SimpleSet set
4097+ cdef Py_ssize_t _used # track if things have been mutated while iterating
4098+ cdef Py_ssize_t len # number of entries left
4099+
4100+ def __init__(self, obj):
4101+ self.set = obj
4102+ self.pos = 0
4103+ self._used = self.set._used
4104+ self.len = self.set._used
4105+
4106+ def __iter__(self):
4107+ return self
4108+
4109+ def __next__(self):
4110+ cdef Py_ssize_t mask, i
4111+ cdef PyObject *key
4112+
4113+ if self.set is None:
4114+ raise StopIteration
4115+ if self.set._used != self._used:
4116+ # Force this exception to continue to be raised
4117+ self._used = -1
4118+ raise RuntimeError("Set size changed during iteration")
4119+ if not SimpleSet_Next(self.set, &self.pos, &key):
4120+ self.set = None
4121+ raise StopIteration
4122+ # we found something
4123+ the_key = <object>key # INCREF
4124+ self.len = self.len - 1
4125+ return the_key
4126+
4127+ def __length_hint__(self):
4128+ if self.set is not None and self._used == self.set._used:
4129+ return self.len
4130+ return 0
4131+
4132+
4133+
4134+cdef api SimpleSet SimpleSet_New():
4135+ """Create a new SimpleSet object."""
4136+ return SimpleSet()
4137+
4138+
4139+cdef SimpleSet _check_self(object self):
4140+ """Check that the parameter is not None.
4141+
4142+ Pyrex/Cython will do type checking, but only to ensure that an object is
4143+ either the right type or None. You can say "object foo not None" for pure
4144+ python functions, but not for C functions.
4145+ So this is just a helper for all the apis that need to do the check.
4146+ """
4147+ cdef SimpleSet true_self
4148+ if self is None:
4149+ raise TypeError('self must not be None')
4150+ true_self = self
4151+ return true_self
4152+
4153+
4154+cdef PyObject **_lookup(SimpleSet self, object key) except NULL:
4155+ """Find the slot where 'key' would fit.
4156+
4157+ This is the same as a dicts 'lookup' function.
4158+
4159+ :param key: An object we are looking up
4160+ :param hash: The hash for key
4161+ :return: The location in self.table where key should be put.
4162+ location == NULL is an exception, but (*location) == NULL just
4163+ indicates the slot is empty and can be used.
4164+ """
4165+ # This uses Quadratic Probing:
4166+ # http://en.wikipedia.org/wiki/Quadratic_probing
4167+ # with c1 = c2 = 1/2
4168+ # This leads to probe locations at:
4169+ # h0 = hash(k1)
4170+ # h1 = h0 + 1
4171+ # h2 = h0 + 3 = h1 + 1 + 1
4172+ # h3 = h0 + 6 = h2 + 1 + 2
4173+ # h4 = h0 + 10 = h2 + 1 + 3
4174+ # Note that all of these are '& mask', but that is computed *after* the
4175+ # offset.
4176+ # This differs from the algorithm used by Set and Dict. Which, effectively,
4177+ # use double-hashing, and a step size that starts large, but dwindles to
4178+ # stepping one-by-one.
4179+ # This gives more 'locality' in that if you have a collision at offset X,
4180+ # the first fallback is X+1, which is fast to check. However, that means
4181+ # that an object w/ hash X+1 will also check there, and then X+2 next.
4182+ # However, for objects with differing hashes, their chains are different.
4183+ # The former checks X, X+1, X+3, ... the latter checks X+1, X+2, X+4, ...
4184+ # So different hashes diverge quickly.
4185+ # A bigger problem is that we *only* ever use the lowest bits of the hash
4186+ # So all integers (x + SIZE*N) will resolve into the same bucket, and all
4187+ # use the same collision resolution. We may want to try to find a way to
4188+ # incorporate the upper bits of the hash with quadratic probing. (For
4189+ # example, X, X+1, X+3+some_upper_bits, X+6+more_upper_bits, etc.)
4190+ cdef size_t i, n_lookup
4191+ cdef Py_ssize_t mask
4192+ cdef long key_hash
4193+ cdef PyObject **table, **slot, *cur, **free_slot, *py_key
4194+
4195+ py_key = <PyObject *>key
4196+ # Note: avoid using hash(obj) because of a bug w/ pyrex 0.9.8.5 and 64-bit
4197+ # (it treats hash() as returning an 'int' rather than a 'long')
4198+ key_hash = PyObject_Hash(py_key)
4199+ i = <size_t>key_hash
4200+ mask = self._mask
4201+ table = self._table
4202+ free_slot = NULL
4203+ for n_lookup from 0 <= n_lookup <= <size_t>mask: # Don't loop forever
4204+ slot = &table[i & mask]
4205+ cur = slot[0]
4206+ if cur == NULL:
4207+ # Found a blank spot
4208+ if free_slot != NULL:
4209+ # Did we find an earlier _dummy entry?
4210+ return free_slot
4211+ else:
4212+ return slot
4213+ if cur == py_key:
4214+ # Found an exact pointer to the key
4215+ return slot
4216+ if cur == _dummy:
4217+ if free_slot == NULL:
4218+ free_slot = slot
4219+ elif _is_equal(py_key, key_hash, cur):
4220+ # Both py_key and cur belong in this slot, return it
4221+ return slot
4222+ i = i + 1 + n_lookup
4223+ raise AssertionError('should never get here')
4224+
4225+
4226+cdef api PyObject **_SimpleSet_Lookup(object self, object key) except NULL:
4227+ """Find the slot where 'key' would fit.
4228+
4229+ This is the same as a dicts 'lookup' function. This is a private
4230+ api because mutating what you get without maintaing the other invariants
4231+ is a 'bad thing'.
4232+
4233+ :param key: An object we are looking up
4234+ :param hash: The hash for key
4235+ :return: The location in self._table where key should be put
4236+ should never be NULL, but may reference a NULL (PyObject*)
4237+ """
4238+ return _lookup(_check_self(self), key)
4239+
4240+
4241+cdef api object SimpleSet_Add(object self, object key):
4242+ """Add a key to the SimpleSet (set).
4243+
4244+ :param self: The SimpleSet to add the key to.
4245+ :param key: The key to be added. If the key is already present,
4246+ self will not be modified
4247+ :return: The current key stored at the location defined by 'key'.
4248+ This may be the same object, or it may be an equivalent object.
4249+ (consider dict.setdefault(key, key))
4250+ """
4251+ return _check_self(self)._add(key)
4252+
4253+
4254+cdef api int SimpleSet_Contains(object self, object key) except -1:
4255+ """Is key present in self?"""
4256+ return (key in _check_self(self))
4257+
4258+
4259+cdef api int SimpleSet_Discard(object self, object key) except -1:
4260+ """Remove the object referenced at location 'key'.
4261+
4262+ :param self: The SimpleSet being modified
4263+ :param key: The key we are checking on
4264+ :return: 1 if there was an object present, 0 if there was not, and -1 on
4265+ error.
4266+ """
4267+ return _check_self(self)._discard(key)
4268+
4269+
4270+cdef api PyObject *SimpleSet_Get(SimpleSet self, object key) except? NULL:
4271+ """Get a pointer to the object present at location 'key'.
4272+
4273+ This returns an object which is equal to key which was previously added to
4274+ self. This returns a borrowed reference, as it may also return NULL if no
4275+ value is present at that location.
4276+
4277+ :param key: The value we are looking for
4278+ :return: The object present at that location
4279+ """
4280+ return _check_self(self)._get(key)
4281+
4282+
4283+cdef api Py_ssize_t SimpleSet_Size(object self) except -1:
4284+ """Get the number of active entries in 'self'"""
4285+ return _check_self(self)._used
4286+
4287+
4288+cdef api int SimpleSet_Next(object self, Py_ssize_t *pos, PyObject **key):
4289+ """Walk over items in a SimpleSet.
4290+
4291+ :param pos: should be initialized to 0 by the caller, and will be updated
4292+ by this function
4293+ :param key: Will return a borrowed reference to key
4294+ :return: 0 if nothing left, 1 if we are returning a new value
4295+ """
4296+ cdef Py_ssize_t i, mask
4297+ cdef SimpleSet true_self
4298+ cdef PyObject **table
4299+ true_self = _check_self(self)
4300+ i = pos[0]
4301+ if (i < 0):
4302+ return 0
4303+ mask = true_self._mask
4304+ table= true_self._table
4305+ while (i <= mask and (table[i] == NULL or table[i] == _dummy)):
4306+ i = i + 1
4307+ pos[0] = i + 1
4308+ if (i > mask):
4309+ return 0 # All done
4310+ if (key != NULL):
4311+ key[0] = table[i]
4312+ return 1
4313+
4314+
4315+cdef int SimpleSet_traverse(SimpleSet self, visitproc visit, void *arg):
4316+ """This is an implementation of 'tp_traverse' that hits the whole table.
4317+
4318+ Cython/Pyrex don't seem to let you define a tp_traverse, and they only
4319+ define one for you if you have an 'object' attribute. Since they don't
4320+ support C arrays of objects, we access the PyObject * directly.
4321+ """
4322+ cdef Py_ssize_t pos
4323+ cdef PyObject *next_key
4324+ cdef int ret
4325+
4326+ pos = 0
4327+ while SimpleSet_Next(self, &pos, &next_key):
4328+ ret = visit(next_key, arg)
4329+ if ret:
4330+ return ret
4331+ return 0
4332+
4333+# It is a little bit ugly to do this, but it works, and means that Meliae can
4334+# dump the total memory consumed by all child objects.
4335+(<PyTypeObject *>SimpleSet).tp_traverse = <traverseproc>SimpleSet_traverse
4336
4337=== added file 'bzrlib/_static_tuple_c.c'
4338--- bzrlib/_static_tuple_c.c 1970-01-01 00:00:00 +0000
4339+++ bzrlib/_static_tuple_c.c 2009-11-03 09:40:55 +0000
4340@@ -0,0 +1,941 @@
4341+/* Copyright (C) 2009 Canonical Ltd
4342+ *
4343+ * This program is free software; you can redistribute it and/or modify
4344+ * it under the terms of the GNU General Public License as published by
4345+ * the Free Software Foundation; either version 2 of the License, or
4346+ * (at your option) any later version.
4347+ *
4348+ * This program is distributed in the hope that it will be useful,
4349+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
4350+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4351+ * GNU General Public License for more details.
4352+ *
4353+ * You should have received a copy of the GNU General Public License
4354+ * along with this program; if not, write to the Free Software
4355+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
4356+ */
4357+
4358+/* Must be defined before importing _static_tuple_c.h so that we get the right
4359+ * linkage.
4360+ */
4361+#define STATIC_TUPLE_MODULE
4362+
4363+#include <Python.h>
4364+#include "python-compat.h"
4365+
4366+#include "_static_tuple_c.h"
4367+#include "_export_c_api.h"
4368+
4369+/* Pyrex 0.9.6.4 exports _simple_set_pyx_api as
4370+ * import__simple_set_pyx(), while Pyrex 0.9.8.5 and Cython 0.11.3 export them
4371+ * as import_bzrlib___simple_set_pyx(). As such, we just #define one to be
4372+ * equivalent to the other in our internal code.
4373+ */
4374+#define import__simple_set_pyx import_bzrlib___simple_set_pyx
4375+#include "_simple_set_pyx_api.h"
4376+
4377+#if defined(__GNUC__)
4378+# define inline __inline__
4379+#elif defined(_MSC_VER)
4380+# define inline __inline
4381+#else
4382+# define inline
4383+#endif
4384+
4385+
4386+/* The one and only StaticTuple with no values */
4387+static StaticTuple *_empty_tuple = NULL;
4388+static PyObject *_interned_tuples = NULL;
4389+
4390+
4391+static inline int
4392+_StaticTuple_is_interned(StaticTuple *self)
4393+{
4394+ return self->flags & STATIC_TUPLE_INTERNED_FLAG;
4395+}
4396+
4397+
4398+
4399+static PyObject *
4400+StaticTuple_as_tuple(StaticTuple *self)
4401+{
4402+ PyObject *tpl = NULL, *obj = NULL;
4403+ int i, len;
4404+
4405+ len = self->size;
4406+ tpl = PyTuple_New(len);
4407+ if (!tpl) {
4408+ /* Malloc failure */
4409+ return NULL;
4410+ }
4411+ for (i = 0; i < len; ++i) {
4412+ obj = (PyObject *)self->items[i];
4413+ Py_INCREF(obj);
4414+ PyTuple_SET_ITEM(tpl, i, obj);
4415+ }
4416+ return tpl;
4417+}
4418+
4419+
4420+static char StaticTuple_as_tuple_doc[] = "as_tuple() => tuple";
4421+
4422+static StaticTuple *
4423+StaticTuple_Intern(StaticTuple *self)
4424+{
4425+ PyObject *canonical_tuple = NULL;
4426+
4427+ if (_interned_tuples == NULL || _StaticTuple_is_interned(self)) {
4428+ Py_INCREF(self);
4429+ return self;
4430+ }
4431+ /* SimpleSet_Add returns whatever object is present at self
4432+ * or the new object if it needs to add it.
4433+ */
4434+ canonical_tuple = SimpleSet_Add(_interned_tuples, (PyObject *)self);
4435+ if (!canonical_tuple) {
4436+ // Some sort of exception, propogate it.
4437+ return NULL;
4438+ }
4439+ if (canonical_tuple != (PyObject *)self) {
4440+ // There was already a tuple with that value
4441+ return (StaticTuple *)canonical_tuple;
4442+ }
4443+ self->flags |= STATIC_TUPLE_INTERNED_FLAG;
4444+ // The two references in the dict do not count, so that the StaticTuple
4445+ // object does not become immortal just because it was interned.
4446+ Py_REFCNT(self) -= 1;
4447+ return self;
4448+}
4449+
4450+static char StaticTuple_Intern_doc[] = "intern() => unique StaticTuple\n"
4451+ "Return a 'canonical' StaticTuple object.\n"
4452+ "Similar to intern() for strings, this makes sure there\n"
4453+ "is only one StaticTuple object for a given value\n."
4454+ "Common usage is:\n"
4455+ " key = StaticTuple('foo', 'bar').intern()\n";
4456+
4457+
4458+static void
4459+StaticTuple_dealloc(StaticTuple *self)
4460+{
4461+ int i, len;
4462+
4463+ if (_StaticTuple_is_interned(self)) {
4464+ /* revive dead object temporarily for Discard */
4465+ Py_REFCNT(self) = 2;
4466+ if (SimpleSet_Discard(_interned_tuples, (PyObject*)self) != 1)
4467+ Py_FatalError("deletion of interned StaticTuple failed");
4468+ self->flags &= ~STATIC_TUPLE_INTERNED_FLAG;
4469+ }
4470+ len = self->size;
4471+ for (i = 0; i < len; ++i) {
4472+ Py_XDECREF(self->items[i]);
4473+ }
4474+ Py_TYPE(self)->tp_free((PyObject *)self);
4475+}
4476+
4477+
4478+/* Similar to PyTuple_New() */
4479+static StaticTuple *
4480+StaticTuple_New(Py_ssize_t size)
4481+{
4482+ StaticTuple *stuple;
4483+ if (size < 0) {
4484+ PyErr_BadInternalCall();
4485+ return NULL;
4486+ }
4487+
4488+ if (size < 0 || size > 255) {
4489+ /* Too big or too small */
4490+ PyErr_SetString(PyExc_ValueError, "StaticTuple(...)"
4491+ " takes from 0 to 255 items");
4492+ return NULL;
4493+ }
4494+ if (size == 0 && _empty_tuple != NULL) {
4495+ Py_INCREF(_empty_tuple);
4496+ return _empty_tuple;
4497+ }
4498+ /* Note that we use PyObject_NewVar because we want to allocate a variable
4499+ * width entry. However we *aren't* truly a PyVarObject because we don't
4500+ * use a long for ob_size. Instead we use a plain 'size' that is an int,
4501+ * and will be overloaded with flags in the future.
4502+ * As such we do the alloc, and then have to clean up anything it does
4503+ * incorrectly.
4504+ */
4505+ stuple = PyObject_NewVar(StaticTuple, &StaticTuple_Type, size);
4506+ if (stuple == NULL) {
4507+ return NULL;
4508+ }
4509+ stuple->size = size;
4510+ stuple->flags = 0;
4511+ stuple->_unused0 = 0;
4512+ stuple->_unused1 = 0;
4513+ if (size > 0) {
4514+ memset(stuple->items, 0, sizeof(PyObject *) * size);
4515+ }
4516+#if STATIC_TUPLE_HAS_HASH
4517+ stuple->hash = -1;
4518+#endif
4519+ return stuple;
4520+}
4521+
4522+
4523+static StaticTuple *
4524+StaticTuple_FromSequence(PyObject *sequence)
4525+{
4526+ StaticTuple *new = NULL;
4527+ PyObject *as_tuple = NULL;
4528+ PyObject *item;
4529+ Py_ssize_t i, size;
4530+
4531+ if (StaticTuple_CheckExact(sequence)) {
4532+ Py_INCREF(sequence);
4533+ return (StaticTuple *)sequence;
4534+ }
4535+ if (!PySequence_Check(sequence)) {
4536+ as_tuple = PySequence_Tuple(sequence);
4537+ if (as_tuple == NULL)
4538+ goto done;
4539+ sequence = as_tuple;
4540+ }
4541+ size = PySequence_Size(sequence);
4542+ if (size == -1) {
4543+ goto done;
4544+ }
4545+ new = StaticTuple_New(size);
4546+ if (new == NULL) {
4547+ goto done;
4548+ }
4549+ for (i = 0; i < size; ++i) {
4550+ // This returns a new reference, which we then 'steal' with
4551+ // StaticTuple_SET_ITEM
4552+ item = PySequence_GetItem(sequence, i);
4553+ if (item == NULL) {
4554+ Py_DECREF(new);
4555+ new = NULL;
4556+ goto done;
4557+ }
4558+ StaticTuple_SET_ITEM(new, i, item);
4559+ }
4560+done:
4561+ Py_XDECREF(as_tuple);
4562+ return (StaticTuple *)new;
4563+}
4564+
4565+static StaticTuple *
4566+StaticTuple_from_sequence(PyObject *self, PyObject *args, PyObject *kwargs)
4567+{
4568+ PyObject *sequence;
4569+ if (!PyArg_ParseTuple(args, "O", &sequence))
4570+ return NULL;
4571+ return StaticTuple_FromSequence(sequence);
4572+}
4573+
4574+
4575+/* Check that all items we point to are 'valid' */
4576+static int
4577+StaticTuple_check_items(StaticTuple *self)
4578+{
4579+ int i;
4580+ PyObject *obj;
4581+
4582+ for (i = 0; i < self->size; ++i) {
4583+ obj = self->items[i];
4584+ if (obj == NULL) {
4585+ PyErr_SetString(PyExc_RuntimeError, "StaticTuple(...)"
4586+ " should not have a NULL entry.");
4587+ return 0;
4588+ }
4589+ if (PyString_CheckExact(obj)
4590+ || StaticTuple_CheckExact(obj)
4591+ || obj == Py_None
4592+ || PyBool_Check(obj)
4593+ || PyInt_CheckExact(obj)
4594+ || PyLong_CheckExact(obj)
4595+ || PyFloat_CheckExact(obj)
4596+ || PyUnicode_CheckExact(obj)
4597+ ) continue;
4598+ PyErr_Format(PyExc_TypeError, "StaticTuple(...)"
4599+ " requires that all items are one of"
4600+ " str, StaticTuple, None, bool, int, long, float, or unicode"
4601+ " not %s.", Py_TYPE(obj)->tp_name);
4602+ return 0;
4603+ }
4604+ return 1;
4605+}
4606+
4607+static PyObject *
4608+StaticTuple_new_constructor(PyTypeObject *type, PyObject *args, PyObject *kwds)
4609+{
4610+ StaticTuple *self;
4611+ PyObject *obj = NULL;
4612+ Py_ssize_t i, len = 0;
4613+
4614+ if (type != &StaticTuple_Type) {
4615+ PyErr_SetString(PyExc_TypeError, "we only support creating StaticTuple");
4616+ return NULL;
4617+ }
4618+ if (!PyTuple_CheckExact(args)) {
4619+ PyErr_SetString(PyExc_TypeError, "args must be a tuple");
4620+ return NULL;
4621+ }
4622+ len = PyTuple_GET_SIZE(args);
4623+ self = (StaticTuple *)StaticTuple_New(len);
4624+ if (self == NULL) {
4625+ return NULL;
4626+ }
4627+ for (i = 0; i < len; ++i) {
4628+ obj = PyTuple_GET_ITEM(args, i);
4629+ Py_INCREF(obj);
4630+ self->items[i] = obj;
4631+ }
4632+ if (!StaticTuple_check_items(self)) {
4633+ type->tp_dealloc((PyObject *)self);
4634+ return NULL;
4635+ }
4636+ return (PyObject *)self;
4637+}
4638+
4639+static PyObject *
4640+StaticTuple_repr(StaticTuple *self)
4641+{
4642+ PyObject *as_tuple, *tuple_repr, *result;
4643+
4644+ as_tuple = StaticTuple_as_tuple(self);
4645+ if (as_tuple == NULL) {
4646+ return NULL;
4647+ }
4648+ tuple_repr = PyObject_Repr(as_tuple);
4649+ Py_DECREF(as_tuple);
4650+ if (tuple_repr == NULL) {
4651+ return NULL;
4652+ }
4653+ result = PyString_FromFormat("StaticTuple%s",
4654+ PyString_AsString(tuple_repr));
4655+ return result;
4656+}
4657+
4658+static long
4659+StaticTuple_hash(StaticTuple *self)
4660+{
4661+ /* adapted from tuplehash(), is the specific hash value considered
4662+ * 'stable'?
4663+ */
4664+ register long x, y;
4665+ Py_ssize_t len = self->size;
4666+ PyObject **p;
4667+ long mult = 1000003L;
4668+
4669+#if STATIC_TUPLE_HAS_HASH
4670+ if (self->hash != -1) {
4671+ return self->hash;
4672+ }
4673+#endif
4674+ x = 0x345678L;
4675+ p = self->items;
4676+ // TODO: We could set specific flags if we know that, for example, all the
4677+ // items are strings. I haven't seen a real-world benefit to that
4678+ // yet, though.
4679+ while (--len >= 0) {
4680+ y = PyObject_Hash(*p++);
4681+ if (y == -1) /* failure */
4682+ return -1;
4683+ x = (x ^ y) * mult;
4684+ /* the cast might truncate len; that doesn't change hash stability */
4685+ mult += (long)(82520L + len + len);
4686+ }
4687+ x += 97531L;
4688+ if (x == -1)
4689+ x = -2;
4690+#if STATIC_TUPLE_HAS_HASH
4691+ self->hash = x;
4692+#endif
4693+ return x;
4694+}
4695+
4696+static PyObject *
4697+StaticTuple_richcompare_to_tuple(StaticTuple *v, PyObject *wt, int op)
4698+{
4699+ PyObject *vt;
4700+ PyObject *result = NULL;
4701+
4702+ vt = StaticTuple_as_tuple((StaticTuple *)v);
4703+ if (vt == NULL) {
4704+ goto done;
4705+ }
4706+ if (!PyTuple_Check(wt)) {
4707+ PyErr_BadInternalCall();
4708+ goto done;
4709+ }
4710+ /* Now we have 2 tuples to compare, do it */
4711+ result = PyTuple_Type.tp_richcompare(vt, wt, op);
4712+done:
4713+ Py_XDECREF(vt);
4714+ return result;
4715+}
4716+
4717+/** Compare two objects to determine if they are equivalent.
4718+ * The basic flow is as follows
4719+ * 1) First make sure that both objects are StaticTuple instances. If they
4720+ * aren't then cast self to a tuple, and have the tuple do the comparison.
4721+ * 2) Special case comparison to Py_None, because it happens to occur fairly
4722+ * often in the test suite.
4723+ * 3) Special case when v and w are the same pointer. As we know the answer to
4724+ * all queries without walking individual items.
4725+ * 4) For all operations, we then walk the items to find the first paired
4726+ * items that are not equal.
4727+ * 5) If all items found are equal, we then check the length of self and
4728+ * other to determine equality.
4729+ * 6) If an item differs, then we apply "op" to those last two items. (eg.
4730+ * StaticTuple(A, B) > StaticTuple(A, C) iff B > C)
4731+ */
4732+
4733+static PyObject *
4734+StaticTuple_richcompare(PyObject *v, PyObject *w, int op)
4735+{
4736+ StaticTuple *v_st, *w_st;
4737+ Py_ssize_t vlen, wlen, min_len, i;
4738+ PyObject *v_obj, *w_obj;
4739+ richcmpfunc string_richcompare;
4740+
4741+ if (!StaticTuple_CheckExact(v)) {
4742+ /* This has never triggered, according to python-dev it seems this
4743+ * might trigger if '__op__' is defined but '__rop__' is not, sort of
4744+ * case. Such as "None == StaticTuple()"
4745+ */
4746+ fprintf(stderr, "self is not StaticTuple\n");
4747+ Py_INCREF(Py_NotImplemented);
4748+ return Py_NotImplemented;
4749+ }
4750+ v_st = (StaticTuple *)v;
4751+ if (StaticTuple_CheckExact(w)) {
4752+ /* The most common case */
4753+ w_st = (StaticTuple*)w;
4754+ } else if (PyTuple_Check(w)) {
4755+ /* One of v or w is a tuple, so we go the 'slow' route and cast up to
4756+ * tuples to compare.
4757+ */
4758+ /* TODO: This seems to be triggering more than I thought it would...
4759+ * We probably want to optimize comparing self to other when
4760+ * other is a tuple.
4761+ */
4762+ return StaticTuple_richcompare_to_tuple(v_st, w, op);
4763+ } else if (w == Py_None) {
4764+ // None is always less than the object
4765+ switch (op) {
4766+ case Py_NE:case Py_GT:case Py_GE:
4767+ Py_INCREF(Py_True);
4768+ return Py_True;
4769+ case Py_EQ:case Py_LT:case Py_LE:
4770+ Py_INCREF(Py_False);
4771+ return Py_False;
4772+ default: // Should never happen
4773+ return Py_NotImplemented;
4774+ }
4775+ } else {
4776+ /* We don't special case this comparison, we just let python handle
4777+ * it.
4778+ */
4779+ Py_INCREF(Py_NotImplemented);
4780+ return Py_NotImplemented;
4781+ }
4782+ /* Now we know that we have 2 StaticTuple objects, so let's compare them.
4783+ * This code is inspired from tuplerichcompare, except we know our
4784+ * objects are limited in scope, so we can inline some comparisons.
4785+ */
4786+ if (v == w) {
4787+ /* Identical pointers, we can shortcut this easily. */
4788+ switch (op) {
4789+ case Py_EQ:case Py_LE:case Py_GE:
4790+ Py_INCREF(Py_True);
4791+ return Py_True;
4792+ case Py_NE:case Py_LT:case Py_GT:
4793+ Py_INCREF(Py_False);
4794+ return Py_False;
4795+ }
4796+ }
4797+ if (op == Py_EQ
4798+ && _StaticTuple_is_interned(v_st)
4799+ && _StaticTuple_is_interned(w_st))
4800+ {
4801+ /* If both objects are interned, we know they are different if the
4802+ * pointer is not the same, which would have been handled by the
4803+ * previous if. No need to compare the entries.
4804+ */
4805+ Py_INCREF(Py_False);
4806+ return Py_False;
4807+ }
4808+
4809+ /* The only time we are likely to compare items of different lengths is in
4810+ * something like the interned_keys set. However, the hash is good enough
4811+ * that it is rare. Note that 'tuple_richcompare' also does not compare
4812+ * lengths here.
4813+ */
4814+ vlen = v_st->size;
4815+ wlen = w_st->size;
4816+ min_len = (vlen < wlen) ? vlen : wlen;
4817+ string_richcompare = PyString_Type.tp_richcompare;
4818+ for (i = 0; i < min_len; i++) {
4819+ PyObject *result = NULL;
4820+ v_obj = StaticTuple_GET_ITEM(v_st, i);
4821+ w_obj = StaticTuple_GET_ITEM(w_st, i);
4822+ if (v_obj == w_obj) {
4823+ /* Shortcut case, these must be identical */
4824+ continue;
4825+ }
4826+ if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj)) {
4827+ result = string_richcompare(v_obj, w_obj, Py_EQ);
4828+ } else if (StaticTuple_CheckExact(v_obj) &&
4829+ StaticTuple_CheckExact(w_obj))
4830+ {
4831+ /* Both are StaticTuple types, so recurse */
4832+ result = StaticTuple_richcompare(v_obj, w_obj, Py_EQ);
4833+ } else {
4834+ /* Fall back to generic richcompare */
4835+ result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
4836+ }
4837+ if (result == NULL) {
4838+ return NULL; /* There seems to be an error */
4839+ }
4840+ if (result == Py_False) {
4841+ // This entry is not identical, Shortcut for Py_EQ
4842+ if (op == Py_EQ) {
4843+ return result;
4844+ }
4845+ Py_DECREF(result);
4846+ break;
4847+ }
4848+ if (result != Py_True) {
4849+ /* We don't know *what* richcompare is returning, but it
4850+ * isn't something we recognize
4851+ */
4852+ PyErr_BadInternalCall();
4853+ Py_DECREF(result);
4854+ return NULL;
4855+ }
4856+ Py_DECREF(result);
4857+ }
4858+ if (i >= min_len) {
4859+ /* We walked off one of the lists, but everything compared equal so
4860+ * far. Just compare the size.
4861+ */
4862+ int cmp;
4863+ PyObject *res;
4864+ switch (op) {
4865+ case Py_LT: cmp = vlen < wlen; break;
4866+ case Py_LE: cmp = vlen <= wlen; break;
4867+ case Py_EQ: cmp = vlen == wlen; break;
4868+ case Py_NE: cmp = vlen != wlen; break;
4869+ case Py_GT: cmp = vlen > wlen; break;
4870+ case Py_GE: cmp = vlen >= wlen; break;
4871+ default: return NULL; /* cannot happen */
4872+ }
4873+ if (cmp)
4874+ res = Py_True;
4875+ else
4876+ res = Py_False;
4877+ Py_INCREF(res);
4878+ return res;
4879+ }
4880+ /* The last item differs, shortcut the Py_NE case */
4881+ if (op == Py_NE) {
4882+ Py_INCREF(Py_True);
4883+ return Py_True;
4884+ }
4885+ /* It is some other comparison, go ahead and do the real check. */
4886+ if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj))
4887+ {
4888+ return string_richcompare(v_obj, w_obj, op);
4889+ } else if (StaticTuple_CheckExact(v_obj) &&
4890+ StaticTuple_CheckExact(w_obj))
4891+ {
4892+ /* Both are StaticTuple types, so recurse */
4893+ return StaticTuple_richcompare(v_obj, w_obj, op);
4894+ } else {
4895+ return PyObject_RichCompare(v_obj, w_obj, op);
4896+ }
4897+}
4898+
4899+
4900+static Py_ssize_t
4901+StaticTuple_length(StaticTuple *self)
4902+{
4903+ return self->size;
4904+}
4905+
4906+
4907+static PyObject *
4908+StaticTuple__is_interned(StaticTuple *self)
4909+{
4910+ if (_StaticTuple_is_interned(self)) {
4911+ Py_INCREF(Py_True);
4912+ return Py_True;
4913+ }
4914+ Py_INCREF(Py_False);
4915+ return Py_False;
4916+}
4917+
4918+static char StaticTuple__is_interned_doc[] = "_is_interned() => True/False\n"
4919+ "Check to see if this tuple has been interned.\n";
4920+
4921+
4922+static PyObject *
4923+StaticTuple_reduce(StaticTuple *self)
4924+{
4925+ PyObject *result = NULL, *as_tuple = NULL;
4926+
4927+ result = PyTuple_New(2);
4928+ if (!result) {
4929+ return NULL;
4930+ }
4931+ as_tuple = StaticTuple_as_tuple(self);
4932+ if (as_tuple == NULL) {
4933+ Py_DECREF(result);
4934+ return NULL;
4935+ }
4936+ Py_INCREF(&StaticTuple_Type);
4937+ PyTuple_SET_ITEM(result, 0, (PyObject *)&StaticTuple_Type);
4938+ PyTuple_SET_ITEM(result, 1, as_tuple);
4939+ return result;
4940+}
4941+
4942+static char StaticTuple_reduce_doc[] = "__reduce__() => tuple\n";
4943+
4944+
4945+static PyObject *
4946+StaticTuple_add(PyObject *v, PyObject *w)
4947+{
4948+ Py_ssize_t i, len_v, len_w;
4949+ PyObject *item;
4950+ StaticTuple *result;
4951+ /* StaticTuples and plain tuples may be added (concatenated) to
4952+ * StaticTuples.
4953+ */
4954+ if (StaticTuple_CheckExact(v)) {
4955+ len_v = ((StaticTuple*)v)->size;
4956+ } else if (PyTuple_Check(v)) {
4957+ len_v = PyTuple_GET_SIZE(v);
4958+ } else {
4959+ Py_INCREF(Py_NotImplemented);
4960+ return Py_NotImplemented;
4961+ }
4962+ if (StaticTuple_CheckExact(w)) {
4963+ len_w = ((StaticTuple*)w)->size;
4964+ } else if (PyTuple_Check(w)) {
4965+ len_w = PyTuple_GET_SIZE(w);
4966+ } else {
4967+ Py_INCREF(Py_NotImplemented);
4968+ return Py_NotImplemented;
4969+ }
4970+ result = StaticTuple_New(len_v + len_w);
4971+ if (result == NULL)
4972+ return NULL;
4973+ for (i = 0; i < len_v; ++i) {
4974+ // This returns a new reference, which we then 'steal' with
4975+ // StaticTuple_SET_ITEM
4976+ item = PySequence_GetItem(v, i);
4977+ if (item == NULL) {
4978+ Py_DECREF(result);
4979+ return NULL;
4980+ }
4981+ StaticTuple_SET_ITEM(result, i, item);
4982+ }
4983+ for (i = 0; i < len_w; ++i) {
4984+ item = PySequence_GetItem(w, i);
4985+ if (item == NULL) {
4986+ Py_DECREF(result);
4987+ return NULL;
4988+ }
4989+ StaticTuple_SET_ITEM(result, i+len_v, item);
4990+ }
4991+ if (!StaticTuple_check_items(result)) {
4992+ Py_DECREF(result);
4993+ return NULL;
4994+ }
4995+ return (PyObject *)result;
4996+}
4997+
4998+static PyObject *
4999+StaticTuple_item(StaticTuple *self, Py_ssize_t offset)
5000+{
The diff has been truncated for viewing.