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
=== modified file '.bzrignore'
--- .bzrignore 2009-07-31 19:56:19 +0000
+++ .bzrignore 2009-11-03 09:40:55 +0000
@@ -5,10 +5,21 @@
5./.bzr.log5./.bzr.log
6# Generated files6# Generated files
7CHANGELOG7CHANGELOG
8# generated documents
8bzr.19bzr.1
9./doc/*.html10./doc/*.html
10./doc/_build/11./doc/*/_build/
12./doc/*/Makefile
13./doc/*/make.bat
11./tutorial.html14./tutorial.html
15./build_doc_website
16./html_docs
17./pretty_docs
18./api
19./doc/**/*.html
20./doc/developers/performance.png
21./doc/en/user-reference/*.txt
22./doc/en/release-notes/*.txt
12BRANCH-INFO23BRANCH-INFO
13# setup.py working directory24# setup.py working directory
14./build25./build
@@ -35,11 +46,7 @@
35./dist46./dist
36# performance history data file47# performance history data file
37./.perf_history48./.perf_history
38./html_docs49# Pyrex
39./pretty_docs
40./api
41doc/**/*.html
42doc/developers/performance.png
43bzrlib/_annotator_pyx.c50bzrlib/_annotator_pyx.c
44bzrlib/_bencode_pyx.c51bzrlib/_bencode_pyx.c
45bzrlib/_btree_serializer_pyx.c52bzrlib/_btree_serializer_pyx.c
@@ -51,16 +58,12 @@
51bzrlib/_known_graph_pyx.c58bzrlib/_known_graph_pyx.c
52bzrlib/_readdir_pyx.c59bzrlib/_readdir_pyx.c
53bzrlib/_rio_pyx.c60bzrlib/_rio_pyx.c
61bzrlib/_simple_set_pyx.c
62bzrlib/_simple_set_pyx.h
63bzrlib/_simple_set_pyx_api.h
54bzrlib/_walkdirs_win32.c64bzrlib/_walkdirs_win32.c
55doc/en/release-notes/NEWS.txt
56doc/en/developer-guide/HACKING.txt
57doc/en/user-reference/bzr_man.txt
58# built extension modules65# built extension modules
59bzrlib/_*.dll66bzrlib/_*.dll
60bzrlib/_*.so67bzrlib/_*.so
61bzrlib/_*.pyd68bzrlib/_*.pyd
62# generated help topics
63doc/en/user-reference/*.txt
64./doc/en/user-guide/latex_prepared
65./doc/en/user-guide/*.pdf
66./.ccache69./.ccache
6770
=== modified file 'Makefile'
--- Makefile 2009-08-27 00:53:27 +0000
+++ Makefile 2009-11-03 09:40:55 +0000
@@ -75,44 +75,161 @@
75# these are treated as phony so they'll always be rebuilt - it's pretty quick75# these are treated as phony so they'll always be rebuilt - it's pretty quick
76.PHONY: TAGS tags76.PHONY: TAGS tags
7777
78
78### Documentation ###79### Documentation ###
7980
80# set PRETTY to get docs that look like the Bazaar web site81# Default to plain documentation for maximum backwards compatibility.
81ifdef PRETTY82# (Post 2.0, the defaults will most likely be Sphinx-style instead.)
82rst2html := $(PYTHON) tools/rst2prettyhtml.py doc/bazaar-vcs.org.kid 83
83else84docs: docs-plain
84rst2html := $(PYTHON) tools/rst2html.py --link-stylesheet --footnote-references=superscript --halt=warning85
85endif86clean-docs: clean-plain
87
88html-docs: html-plain
89
90
91### Man-page Documentation ###
92
93MAN_DEPENDENCIES = bzrlib/builtins.py \
94 $(wildcard bzrlib/*.py) \
95 $(wildcard bzrlib/*/*.py) \
96 tools/generate_docs.py \
97 $(wildcard $(addsuffix /*.txt, bzrlib/help_topics/en))
98
99MAN_PAGES = man1/bzr.1
100man1/bzr.1: $(MAN_DEPENDENCIES)
101 $(PYTHON) tools/generate_docs.py -o $@ man
102
103
104### Sphinx-style Documentation ###
105
106# Build the documentation. To keep the dependencies down to a minimum
107# for distro packagers, we only build the html documentation by default.
108# Sphinx 0.6 or later is preferred for the best rendering, though
109# Sphinx 0.4 or later should work. See http://sphinx.pocoo.org/index.html
110# for installation instructions.
111docs-sphinx: html-sphinx
112
113# Clean out generated documentation
114clean-sphinx:
115 cd doc/en && make clean
116 cd doc/es && make clean
117 cd doc/ru && make clean
118 cd doc/developers && make clean
119
120SPHINX_DEPENDENCIES = \
121 doc/en/release-notes/index.txt \
122 doc/en/user-reference/index.txt \
123 doc/es/Makefile \
124 doc/es/make.bat \
125 doc/ru/Makefile \
126 doc/ru/make.bat \
127 doc/developers/Makefile \
128 doc/developers/make.bat
129
130doc/en/user-reference/index.txt: $(MAN_DEPENDENCIES)
131 $(PYTHON) tools/generate_docs.py -o $@ rstx
132
133doc/en/release-notes/index.txt: NEWS tools/generate_release_notes.py
134 $(PYTHON) tools/generate_release_notes.py NEWS $@
135
136doc/%/Makefile: doc/en/Makefile
137 $(PYTHON) -c "import shutil; shutil.copyfile('$<', '$@')"
138
139doc/%/make.bat: doc/en/make.bat
140 $(PYTHON) -c "import shutil; shutil.copyfile('$<', '$@')"
141
142# Build the html docs using Sphinx.
143html-sphinx: $(SPHINX_DEPENDENCIES)
144 cd doc/en && make html
145 cd doc/es && make html
146 cd doc/ru && make html
147 cd doc/developers && make html
148
149# Build the PDF docs using Sphinx. This requires numerous LaTeX
150# packages. See http://sphinx.pocoo.org/builders.html for details.
151# Note: We don't currently build PDFs for the Russian docs because
152# they require additional packages to be installed (to handle
153# Russian hyphenation rules, etc.)
154pdf-sphinx: $(SPHINX_DEPENDENCIES)
155 cd doc/en && make latex
156 cd doc/es && make latex
157 cd doc/developers && make latex
158 cd doc/en/_build/latex && make all-pdf
159 cd doc/es/_build/latex && make all-pdf
160 cd doc/developers/_build/latex && make all-pdf
161
162# Build the CHM (Windows Help) docs using Sphinx.
163# Note: HtmlHelp Workshop needs to be used on the generated hhp files
164# to generate the final chm files.
165chm-sphinx: $(SPHINX_DEPENDENCIES)
166 cd doc/en && make htmlhelp
167 cd doc/es && make htmlhelp
168 cd doc/ru && make htmlhelp
169 cd doc/developers && make htmlhelp
170
171
172### Documentation Website ###
173
174# Where to build the website
175DOC_WEBSITE_BUILD = build_doc_website
176
177# Build and package docs into a website, complete with downloads.
178doc-website: html-sphinx pdf-sphinx
179 $(PYTHON) tools/package_docs.py doc/en $(DOC_WEBSITE_BUILD)
180 $(PYTHON) tools/package_docs.py doc/es $(DOC_WEBSITE_BUILD)
181 $(PYTHON) tools/package_docs.py doc/ru $(DOC_WEBSITE_BUILD)
182 $(PYTHON) tools/package_docs.py doc/developers $(DOC_WEBSITE_BUILD)
183
184
185### Plain Documentation ###
186
187# While Sphinx is the preferred tool for building documentation, we still
188# support our "plain" html documentation so that Sphinx is not a hard
189# dependency for packagers on older platforms.
190
191rst2html = $(PYTHON) tools/rst2html.py --link-stylesheet --footnote-references=superscript --halt=warning
86192
87# translate txt docs to html193# translate txt docs to html
88derived_txt_files := \194derived_txt_files = \
89 doc/en/user-reference/bzr_man.txt \195 doc/en/user-reference/bzr_man.txt \
90 doc/en/release-notes/NEWS.txt196 doc/en/release-notes/NEWS.txt
91txt_files := \197txt_all = \
92 doc/en/tutorials/tutorial.txt \198 doc/en/tutorials/tutorial.txt \
93 doc/en/tutorials/using_bazaar_with_launchpad.txt \199 doc/en/tutorials/using_bazaar_with_launchpad.txt \
94 doc/en/tutorials/centralized_workflow.txt \200 doc/en/tutorials/centralized_workflow.txt \
201 $(wildcard doc/es/tutorials/*.txt) \
95 $(wildcard doc/ru/tutorials/*.txt) \202 $(wildcard doc/ru/tutorials/*.txt) \
96 $(wildcard doc/*/mini-tutorial/index.txt) \203 $(wildcard doc/*/mini-tutorial/index.txt) \
97 $(wildcard doc/*/user-guide/index.txt) \204 $(wildcard doc/*/user-guide/index-plain.txt) \
205 $(wildcard doc/es/guia-usario/*.txt) \
98 $(derived_txt_files) \206 $(derived_txt_files) \
99 doc/en/developer-guide/HACKING.txt \
100 doc/en/upgrade-guide/index.txt \207 doc/en/upgrade-guide/index.txt \
101 $(wildcard doc/es/guia-usario/*.txt) \
102 doc/es/mini-tutorial/index.txt \
103 doc/index.txt \208 doc/index.txt \
104 $(wildcard doc/index.*.txt)209 $(wildcard doc/index.*.txt)
105non_txt_files := \210txt_nohtml = \
211 doc/en/user-guide/index.txt \
212 doc/es/user-guide/index.txt \
213 doc/ru/user-guide/index.txt
214txt_files = $(filter-out $(txt_nohtml), $(txt_all))
215htm_files = $(patsubst %.txt, %.html, $(txt_files))
216
217non_txt_files = \
106 doc/default.css \218 doc/default.css \
107 $(wildcard doc/*/quick-reference/bzr-quick-reference.svg) \219 $(wildcard doc/*/bzr-en-quick-reference.svg) \
108 $(wildcard doc/*/quick-reference/bzr-quick-reference.png) \220 $(wildcard doc/*/bzr-en-quick-reference.png) \
109 $(wildcard doc/*/quick-reference/bzr-quick-reference.pdf) \221 $(wildcard doc/*/bzr-en-quick-reference.pdf) \
222 $(wildcard doc/*/bzr-es-quick-reference.svg) \
223 $(wildcard doc/*/bzr-es-quick-reference.png) \
224 $(wildcard doc/*/bzr-es-quick-reference.pdf) \
225 $(wildcard doc/*/bzr-ru-quick-reference.svg) \
226 $(wildcard doc/*/bzr-ru-quick-reference.png) \
227 $(wildcard doc/*/bzr-ru-quick-reference.pdf) \
110 $(wildcard doc/*/user-guide/images/*.png)228 $(wildcard doc/*/user-guide/images/*.png)
111htm_files := $(patsubst %.txt, %.html, $(txt_files))
112229
113# doc/developers/*.txt files that should *not* be individually230# doc/developers/*.txt files that should *not* be individually
114# converted to HTML231# converted to HTML
115dev_txt_nohtml := \232dev_txt_nohtml = \
116 doc/developers/add.txt \233 doc/developers/add.txt \
117 doc/developers/annotate.txt \234 doc/developers/annotate.txt \
118 doc/developers/bundle-creation.txt \235 doc/developers/bundle-creation.txt \
@@ -120,46 +237,37 @@
120 doc/developers/diff.txt \237 doc/developers/diff.txt \
121 doc/developers/directory-fingerprints.txt \238 doc/developers/directory-fingerprints.txt \
122 doc/developers/gc.txt \239 doc/developers/gc.txt \
240 doc/developers/implementation-notes.txt \
123 doc/developers/incremental-push-pull.txt \241 doc/developers/incremental-push-pull.txt \
242 doc/developers/index.txt \
124 doc/developers/initial-push-pull.txt \243 doc/developers/initial-push-pull.txt \
125 doc/developers/merge-scaling.txt \244 doc/developers/merge-scaling.txt \
245 doc/developers/miscellaneous-notes.txt \
126 doc/developers/missing.txt \246 doc/developers/missing.txt \
127 doc/developers/performance-roadmap-rationale.txt \247 doc/developers/performance-roadmap-rationale.txt \
128 doc/developers/performance-use-case-analysis.txt \248 doc/developers/performance-use-case-analysis.txt \
129 doc/developers/planned-change-integration.txt \249 doc/developers/planned-change-integration.txt \
130 doc/developers/planned-performance-changes.txt \250 doc/developers/planned-performance-changes.txt \
251 doc/developers/plans.txt \
252 doc/developers/process.txt \
131 doc/developers/revert.txt \253 doc/developers/revert.txt \
254 doc/developers/specifications.txt \
132 doc/developers/status.txt \255 doc/developers/status.txt \
133 doc/developers/uncommit.txt256 doc/developers/uncommit.txt
134257
135dev_txt_all := $(wildcard $(addsuffix /*.txt, doc/developers))258dev_txt_all = $(wildcard $(addsuffix /*.txt, doc/developers))
136dev_txt_files := $(filter-out $(dev_txt_nohtml), $(dev_txt_all))259dev_txt_files = $(filter-out $(dev_txt_nohtml), $(dev_txt_all))
137dev_htm_files := $(patsubst %.txt, %.html, $(dev_txt_files)) 260dev_htm_files = $(patsubst %.txt, %.html, $(dev_txt_files))
138261
139doc/%/user-guide/index.html: $(wildcard $(addsuffix /*.txt, doc/%/user-guide)) 262doc/en/user-guide/index-plain.html: $(wildcard $(addsuffix /*.txt, doc/en/user-guide))
140 $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@263 $(rst2html) --stylesheet=../../default.css $(dir $@)index-plain.txt $@
141264
142# Set the paper size for PDF files.265#doc/es/user-guide/index.html: $(wildcard $(addsuffix /*.txt, doc/es/user-guide))
143# Options: 'a4' (ISO A4 size), 'letter' (US Letter size)266# $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@
144PAPERSIZE = a4267#
145# TODO: Add generation for Russian PDF268#doc/ru/user-guide/index.html: $(wildcard $(addsuffix /*.txt, doc/ru/user-guide))
146PDF_DOCS := doc/en/user-guide/user-guide.$(PAPERSIZE).pdf269# $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@
147270#
148# Copy and modify the RST sources, and convert SVG images to PDF
149# files for use a images in the LaTeX-generated PDF.
150# Then generate the PDF output from the modified RST sources.
151doc/en/user-guide/user-guide.$(PAPERSIZE).pdf: $(wildcard $(addsuffix /*.txt, doc/en/user-guide))
152 mkdir -p doc/en/user-guide/latex_prepared
153 $(PYTHON) tools/prepare_for_latex.py \
154 --out-dir=doc/en/user-guide/latex_prepared \
155 --in-dir=doc/en/user-guide
156 cd doc/en/user-guide/latex_prepared && \
157 $(PYTHON) ../../../../tools/rst2pdf.py \
158 --documentoptions=10pt,$(PAPERSIZE)paper \
159 --input-encoding=UTF-8:strict --output-encoding=UTF-8:strict \
160 --strict --title="Bazaar User Guide" \
161 index.txt ../user-guide.$(PAPERSIZE).pdf
162
163doc/developers/%.html: doc/developers/%.txt271doc/developers/%.html: doc/developers/%.txt
164 $(rst2html) --stylesheet=../default.css $< $@272 $(rst2html) --stylesheet=../default.css $< $@
165273
@@ -172,55 +280,42 @@
172%.html: %.txt280%.html: %.txt
173 $(rst2html) --stylesheet=../../default.css $< $@281 $(rst2html) --stylesheet=../../default.css $< $@
174282
175MAN_DEPENDENCIES = bzrlib/builtins.py \
176 $(wildcard bzrlib/*.py) \
177 $(wildcard bzrlib/*/*.py) \
178 tools/generate_docs.py \
179 $(wildcard $(addsuffix /*.txt, bzrlib/help_topics/en))
180
181doc/en/user-reference/bzr_man.txt: $(MAN_DEPENDENCIES)283doc/en/user-reference/bzr_man.txt: $(MAN_DEPENDENCIES)
182 $(PYTHON) tools/generate_docs.py -o $@ rstx284 $(PYTHON) tools/generate_docs.py -o $@ rstx
183285
184doc/en/release-notes/NEWS.txt: NEWS286doc/en/release-notes/NEWS.txt: NEWS
185 $(PYTHON) -c "import shutil; shutil.copyfile('$<', '$@')"287 $(PYTHON) -c "import shutil; shutil.copyfile('$<', '$@')"
186288
187MAN_PAGES = man1/bzr.1
188man1/bzr.1: $(MAN_DEPENDENCIES)
189 $(PYTHON) tools/generate_docs.py -o $@ man
190
191upgrade_guide_dependencies = $(wildcard $(addsuffix /*.txt, doc/en/upgrade-guide)) 289upgrade_guide_dependencies = $(wildcard $(addsuffix /*.txt, doc/en/upgrade-guide))
192290
193doc/en/upgrade-guide/index.html: $(upgrade_guide_dependencies)291doc/en/upgrade-guide/index.html: $(upgrade_guide_dependencies)
194 $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@292 $(rst2html) --stylesheet=../../default.css $(dir $@)index.txt $@
195293
196# build a png of our performance task list
197#
198# this is no longer built by default; you can build it if you want to look at it
199doc/developers/performance.png: doc/developers/performance.dot
200 @echo Generating $@
201 @dot -Tpng $< -o$@ || echo "Dot not installed; skipping generation of $@"
202
203derived_web_docs = $(htm_files) $(dev_htm_files) 294derived_web_docs = $(htm_files) $(dev_htm_files)
204WEB_DOCS = $(derived_web_docs) $(non_txt_files)295WEB_DOCS = $(derived_web_docs) $(non_txt_files)
205ALL_DOCS = $(derived_web_docs) $(MAN_PAGES)296ALL_DOCS = $(derived_web_docs) $(MAN_PAGES)
206297
207# the main target to build all the docs298# the main target to build all the docs
208docs: $(ALL_DOCS)299docs-plain: $(ALL_DOCS)
209300
210# produce a tree containing just the final docs, ready for uploading to the web301# produce a tree containing just the final docs, ready for uploading to the web
211HTMLDIR := html_docs302HTMLDIR = html_docs
212html-docs: docs303html-plain: docs-plain
213 $(PYTHON) tools/win32/ostools.py copytree $(WEB_DOCS) $(HTMLDIR)304 $(PYTHON) tools/win32/ostools.py copytree $(WEB_DOCS) $(HTMLDIR)
214305
215# Produce PDF documents. Requires pdfLaTeX, rubber, and Inkscape.
216pdf-docs: $(PDF_DOCS)
217
218# clean produced docs306# clean produced docs
219clean-docs:307clean-plain:
220 $(PYTHON) tools/win32/ostools.py remove $(ALL_DOCS) \308 $(PYTHON) tools/win32/ostools.py remove $(ALL_DOCS) \
221 $(HTMLDIR) $(derived_txt_files)309 $(HTMLDIR) $(derived_txt_files)
222 rm -f doc/*/user-guide/*.pdf310
223 rm -rf doc/*/user-guide/latex_prepared311
312### Miscellaneous Documentation Targets ###
313
314# build a png of our performance task list
315# this is no longer built by default; you can build it if you want to look at it
316doc/developers/performance.png: doc/developers/performance.dot
317 @echo Generating $@
318 @dot -Tpng $< -o$@ || echo "Dot not installed; skipping generation of $@"
224319
225320
226### Windows Support ###321### Windows Support ###
@@ -230,7 +325,7 @@
230# These are files that need to be copied into the build location to boostrap325# These are files that need to be copied into the build location to boostrap
231# the build process.326# the build process.
232# Note that the path is relative to tools/win32327# Note that the path is relative to tools/win32
233BUILDOUT_FILES := buildout.cfg \328BUILDOUT_FILES = buildout.cfg \
234 buildout-templates/bin/build-installer.bat.in \329 buildout-templates/bin/build-installer.bat.in \
235 ostools.py bootstrap.py330 ostools.py bootstrap.py
236331
@@ -296,9 +391,12 @@
296 $(PYTHON) tools/win32/ostools.py remove bzr-*win32.exe391 $(PYTHON) tools/win32/ostools.py remove bzr-*win32.exe
297 $(PYTHON) tools/win32/ostools.py remove dist392 $(PYTHON) tools/win32/ostools.py remove dist
298393
394
395### Packaging Targets ###
396
299.PHONY: dist dist-upload-escudero check-dist-tarball397.PHONY: dist dist-upload-escudero check-dist-tarball
300398
301# build a distribution tarball and zip file.399# build a distribution source tarball
302#400#
303# this method of copying the pyrex generated files is a bit ugly; it would be401# this method of copying the pyrex generated files is a bit ugly; it would be
304# nicer to generate it from distutils.402# nicer to generate it from distutils.
@@ -308,15 +406,12 @@
308 expbasedir=`mktemp -t -d tmp_bzr_dist.XXXXXXXXXX` && \406 expbasedir=`mktemp -t -d tmp_bzr_dist.XXXXXXXXXX` && \
309 expdir=$$expbasedir/bzr-$$version && \407 expdir=$$expbasedir/bzr-$$version && \
310 tarball=$$PWD/../bzr-$$version.tar.gz && \408 tarball=$$PWD/../bzr-$$version.tar.gz && \
311 zipball=$$PWD/../bzr-$$version.zip && \
312 $(MAKE) clean && \409 $(MAKE) clean && \
313 $(MAKE) && \410 $(MAKE) && \
314 bzr export $$expdir && \411 bzr export $$expdir && \
315 cp bzrlib/*.c $$expdir/bzrlib/. && \412 cp bzrlib/*.c bzrlib/*.h $$expdir/bzrlib/. && \
316 tar cfz $$tarball -C $$expbasedir bzr-$$version && \413 tar cfz $$tarball -C $$expbasedir bzr-$$version && \
317 (cd $$expbasedir && zip -r $$zipball bzr-$$version) && \
318 gpg --detach-sign $$tarball && \414 gpg --detach-sign $$tarball && \
319 gpg --detach-sign $$zipball && \
320 rm -rf $$expbasedir415 rm -rf $$expbasedir
321416
322# run all tests in a previously built tarball417# run all tests in a previously built tarball
@@ -334,15 +429,10 @@
334dist-upload-escudero:429dist-upload-escudero:
335 version=`./bzr version --short` && \430 version=`./bzr version --short` && \
336 tarball=../bzr-$$version.tar.gz && \431 tarball=../bzr-$$version.tar.gz && \
337 zipball=../bzr-$$version.zip && \432 scp $$tarball $$tarball.sig \
338 scp $$zipball $$zipball.sig $$tarball $$tarball.sig \
339 escudero.ubuntu.com:/srv/bazaar.canonical.com/www/releases/src \433 escudero.ubuntu.com:/srv/bazaar.canonical.com/www/releases/src \
340 && \434 && \
341 echo verifying over http... && \435 echo verifying over http... && \
342 curl http://bazaar-vcs.org/releases/src/bzr-$$version.zip \
343 | diff -s - $$zipball && \
344 curl http://bazaar-vcs.org/releases/src/bzr-$$version.zip.sig \
345 | diff -s - $$zipball.sig
346 curl http://bazaar-vcs.org/releases/src/bzr-$$version.tar.gz \436 curl http://bazaar-vcs.org/releases/src/bzr-$$version.tar.gz \
347 | diff -s - $$tarball && \437 | diff -s - $$tarball && \
348 curl http://bazaar-vcs.org/releases/src/bzr-$$version.tar.gz.sig \438 curl http://bazaar-vcs.org/releases/src/bzr-$$version.tar.gz.sig \
349439
=== modified file 'NEWS'
--- NEWS 2009-09-02 18:07:58 +0000
+++ NEWS 2009-11-03 09:40:55 +0000
@@ -2,44 +2,409 @@
2Bazaar Release Notes2Bazaar Release Notes
3####################3####################
44
5
6.. contents:: List of Releases5.. contents:: List of Releases
7 :depth: 16 :depth: 1
87
9In Development8
10##############9bzr 2.1.0b3 (not released yet)
1110##############################
12Compatibility Breaks11
13********************12:Codename:
1413:2.1.0b3: ???
15New Features14
16************15Compatibility Breaks
1716********************
18Bug Fixes17
19*********18New Features
2019************
21* ``bzr check`` in pack-0.92, 1.6 and 1.9 format repositories will no20
22 longer report incorrect errors about ``Missing inventory ('TREE_ROOT', ...)``21Bug Fixes
23 (Robert Collins, #416732)22*********
23
24* Hooks daughter classes should always call the base constructor.
25 (Alexander Belchenko, Vincent Ladeuil, #389648)
26
27Improvements
28************
29
30Documentation
31*************
32
33API Changes
34***********
35
36Internals
37*********
38
39Testing
40*******
41
42* KnownFailure is now signalled to ``ExtendedTestResult`` using the same
43 method that Python 2.7 uses - ``addExpectedFailure``. (Robert Collins)
44
45* TestNotApplicable is now handled within the TestCase.run method rather
46 than being looked for within ``ExtendedTestResult.addError``. This
47 provides better handling with other ``TestResult`` objects, degrading to
48 sucess rather than error. (Robert Collins)
49
50* The private method ``_testConcluded`` on ``ExtendedTestResult`` has been
51 removed - it was empty and unused. (Robert Collins)
52
53* UnavailableFeature is now handled within the TestCase.run method rather
54 than being looked for within addError. If the Result object does not
55 have an addNotSupported method, addSkip is attempted instead, and
56 failing that addSuccess. (Robert Collins)
57
58* When a TestResult does not have an addSkip method, skipped tests are now
59 reported as successful tests, rather than as errors. This change is
60 to make it possible to get a clean test run with a less capable
61 TestResult. (Robert Collins)
62
63
64
65bzr 2.0.3 (not released yet)
66############################
67
68:Codename: template
69:2.0.3: ???
70
71Compatibility Breaks
72********************
73
74New Features
75************
76
77Bug Fixes
78*********
79
80Improvements
81************
82
83Documentation
84*************
85
86API Changes
87***********
88
89Internals
90*********
91
92Testing
93*******
94
95
96bzr 2.1.0b2
97###########
98
99:Codename: a load off my mind
100:2.1.0b2: 2009-11-02
101
102This is our second feature-filled release since 2.0, pushing us down the
103path to a 2.1.0. Once again, all bugfixes in 2.0.2 are present in 2.1.0b2.
104
105Key highlights in this release are: improved handling of
106failures-during-cleanup for commit, fixing a long-standing bug with
107``bzr+http`` and shared repositories, and a new StaticTuple datatype,
108allowing us to reduce memory consumption (50%) and garbage collector
109overhead (40% faster) for many operations.
110
111Bug Fixes
112*********
113
114* ``bzr+http`` servers no longer give spurious jail break errors when
115 serving branches inside a shared repository. (Andrew Bennetts, #348308)
116
117* Errors during commit are handled more robustly so that knock-on errors
118 are less likely to occur, and will not obscure the original error if
119 they do occur. This fixes some causes of ``TooManyConcurrentRequests``
120 and similar errors. (Andrew Bennetts, #429747, #243391)
121
122* TreeTransform.adjust_path updates the limbo paths of descendants of adjusted
123 files. (Aaron Bentley)
124
125* Unicode paths are now handled correctly and consistently by the smart
126 server. (Andrew Bennetts, Michael Hudson, #458762)
127
128Improvements
129************
130
131* When reading index files, we now use a ``StaticTuple`` rather than a
132 plain ``tuple`` object. This generally gives a 20% decrease in peak
133 memory, and can give a performance boost up to 40% on large projects.
134 (John Arbash Meinel)
135
136* Peak memory under certain operations has been reduced significantly.
137 (eg, 'bzr branch launchpad standalone' is cut in half)
138 (John Arbash Meinel)
139
140Documentation
141*************
142
143* Filtered views user documentation upgraded to refer to format 2a
144 instead of pre-2.0 formats. (Ian Clatworthy)
145
146API Changes
147***********
148
149* Remove deprecated ``CLIUIFactory``. (Martin Pool)
150
151* ``UIFactory`` now has new ``show_error``, ``show_message`` and
152 ``show_warning`` methods, which can be hooked by non-text UIs.
153 (Martin Pool)
154
155Internals
156*********
157
158* Added ``bzrlib._simple_set_pyx``. This is a hybrid between a Set and a
159 Dict (it only holds keys, but you can lookup the object located at a
160 given key). It has significantly reduced memory consumption versus the
161 builtin objects (1/2 the size of Set, 1/3rd the size of Dict). This is
162 used as the interning structure for StaticTuple objects.
163 (John Arbash Meinel)
164
165* ``bzrlib._static_tuple_c.StaticTuple`` is now available and used by
166 the btree index parser and the chk map parser. This class functions
167 similarly to ``tuple`` objects. However, it can only point to a limited
168 collection of types. (Currently StaticTuple, str, unicode, None, bool,
169 int, long, float, but not subclasses). This allows us to remove it from
170 the garbage collector (it cannot be in a cycle), it also allows us to
171 intern the objects. In testing, this can reduce peak memory by 20-40%,
172 and significantly improve performance by removing objects from being
173 inspected by the garbage collector. (John Arbash Meinel)
174
175* ``GroupCompressBlock._ensure_content()`` will now release the
176 ``zlib.decompressobj()`` when the first request is for all of the
177 content. (Previously it would only be released if you made a request for
178 part of the content, and then all of it later.) This turns out to be a
179 significant memory savings, as a ``zstream`` carries around approx 260kB
180 of internal state and buffers. (For branching bzr.dev this drops peak
181 memory from 382MB => 345MB.) (John Arbash Meinel)
182
183* When streaming content between ``2a`` format repositories, we now clear
184 caches from earlier versioned files. (So 'revisions' is cleared when we
185 start reading 'inventories', etc.) This can have a significant impact on
186 peak memory for initial copies (~200MB). (John Arbash Meinel)
187
188
189bzr 2.0.2
190#########
191
192:Codename: after the scare
193:2.0.2: 2009-11-02
194
195The second in our "let's keep the stable bugfixes flowing" series. As
196expected this has a few (~9) bugfixes relative to 2.0.1, and no major api
197changes or features.
198
199Bug Fixes
200*********
201
202* Avoid "NoneType has no attribute st_mode" error when files disappear
203 from a directory while it's being read. (Martin Pool, #446033)
204
205* Content filters are now applied correctly after revert.
206 (Ian Clatworthy)
207
208* Diff parsing handles "Binary files differ" hunks. (Aaron Bentley, #436325)
209
210* Fetching from stacked pre-2a repository via a smart server no longer
211 fails intermittently with "second push failed to complete".
212 (Andrew Bennetts, #437626)
213
214* Fix typos left after test_selftest refactoring.
215 (Vincent Ladeuil, Matt Nordhoff, #461149)
216
217* Fixed ``ObjectNotLocked`` errors during ``bzr log -r NNN somefile``.
218 (Andrew Bennetts, #445171)
219
220* PreviewTree file names are not limited by the encoding of the temp
221 directory's filesystem. (Aaron Bentley, #436794)
222
223Improvements
224************
225
226* ``bzr log`` now read-locks branches exactly once, so makes better use of
227 data caches. (Andrew Bennetts)
228
229Documentation
230*************
231
232* Filtered views user documentation upgraded to refer to format 2a
233 instead of pre-2.0 formats. (Ian Clatworthy)
234
235
236bzr 2.1.0b1
237###########
238
239:Codename: While the cat is away
240:2.1.0b1: 2009-10-14
241
242This is the first development release in the new split "stable" and
243"development" series. As such, the release is a snapshot of bzr.dev
244without creating a release candidate first. This release includes a
245fair amount of internal changes, with deprecated code being removed,
246and several new feature developments. People looking for a stable code
247base with only bugfixes should focus on the 2.0.1 release. All bugfixes
248present in 2.0.1 are present in 2.1.0b1.
249
250Highlights include support for ``bzr+ssh://host/~/homedir`` style urls,
251finer control over the plugin search path via extended BZR_PLUGIN_PATH
252syntax, visible warnings when extension modules fail to load, and improved
253error handling during unlocking.
254
255
256New Features
257************
258
259* Bazaar can now send mail through Apple OS X Mail.app.
260 (Brian de Alwis)
261
262* ``bzr+ssh`` and ``bzr`` paths can now be relative to home directories
263 specified in the URL. Paths starting with a path segment of ``~`` are
264 relative to the home directory of the user running the server, and paths
265 starting with ``~user`` are relative to the home directory of the named
266 user. For example, for a user "bob" with a home directory of
267 ``/home/bob``, these URLs are all equivalent:
268
269 * ``bzr+ssh://bob@host/~/repo``
270 * ``bzr+ssh://bob@host/~bob/repo``
271 * ``bzr+ssh://bob@host/home/bob/repo``
272
273 If ``bzr serve`` was invoked with a ``--directory`` argument, then no
274 home directories outside that directory will be accessible via this
275 method.
276
277 This is a feature of ``bzr serve``, so pre-2.1 clients will
278 automatically benefit from this feature when ``bzr`` on the server is
279 upgraded. (Andrew Bennetts, #109143)
280
281* Extensions can now be compiled if either Cython or Pyrex is available.
282 Currently Pyrex is preferred, but that may change in the future.
283 (Arkanes)
284
285* Give more control on BZR_PLUGIN_PATH by providing a way to refer to or
286 disable the user, site and core plugin directories.
287 (Vincent Ladeuil, #412930, #316192, #145612)
288
289Bug Fixes
290*********
291
292* Bazaar's native protocol code now correctly handles EINTR, which most
293 noticeably occurs if you break in to the debugger while connected to a
294 bzr+ssh server. You can now can continue from the debugger (by typing
295 'c') and the process continues. However, note that pressing C-\ in the
296 shell may still kill the SSH process, which is bug 162509, so you must
297 sent a signal to the bzr process specifically, for example by typing
298 ``kill -QUIT PID`` in another shell. (Martin Pool, #341535)
299
300* ``bzr add`` in a tree that has files with ``\r`` or ``\n`` in the
301 filename will issue a warning and skip over those files.
302 (Robert Collins, #3918)
303
304* ``bzr dpush`` now aborts if uncommitted changes (including pending merges)
305 are present in the working tree. The configuration option ``dpush_strict``
306 can be used to set the default for this behavior.
307 (Vincent Ladeuil, #438158)
308
309* ``bzr merge`` and ``bzr remove-tree`` now requires --force if pending
310 merges are present in the working tree.
311 (Vincent Ladeuil, #426344)
312
313* Clearer message when Bazaar runs out of memory, instead of a ``MemoryError``
314 traceback. (Martin Pool, #109115)
315
316* Don't give a warning on Windows when failing to import ``_readdir_pyx``
317 as it is never built. (John Arbash Meinel, #430645)
24318
25* Don't restrict the command name used to run the test suite.319* Don't restrict the command name used to run the test suite.
26 (Vincent Ladeuil, #419950)320 (Vincent Ladeuil, #419950)
27321
322* ftp transports were built differently when the kerberos python module was
323 present leading to obscure failures related to ASCII/BINARY modes.
324 (Vincent Ladeuil, #443041)
325
326* Network streams now decode adjacent records of the same type into a
327 single stream, reducing layering churn. (Robert Collins)
328
329* PreviewTree behaves correctly when get_file_mtime is invoked on an unmodified
330 file. (Aaron Bentley, #251532)
331
332* Registry objects should not use iteritems() when asked to use items().
333 (Vincent Ladeuil, #430510)
334
335* Weave based repositories couldn't be cloned when committers were using
336 domains or user ids embedding '.sig'. Now they can.
337 (Matthew Fuller, Vincent Ladeuil, #430868)
338
28Improvements339Improvements
29************340************
30341
342* Revision specifiers can now be given in a more DWIM form, without
343 needing explicit prefixes for specifiers like tags or revision id's.
344 See ``bzr help revisionspec`` for full details. (Matthew Fuller)
345
346* Bazaar gives a warning before exiting, and writes into ``.bzr.log``, if
347 compiled extensions can't be loaded. This typically indicates a
348 packaging or installation problem. In this case Bazaar will keep
349 running using pure-Python versions, but this may be substantially
350 slower. The warning can be disabled by setting
351 ``ignore_missing_extensions = True`` in ``bazaar.conf``.
352 See also <https://answers.launchpad.net/bzr/+faq/703>.
353 (Martin Pool, #406113, #430529)
354
355* Secondary errors that occur during Branch.unlock and Repository.unlock
356 no longer obscure the original error. These methods now use a new
357 decorator, ``only_raises``. This fixes many causes of
358 ``TooManyConcurrentRequests`` and similar errors.
359 (Andrew Bennetts, #429747)
360
31Documentation361Documentation
32*************362*************
33363
364* Describe the new shell-like test feature. (Vincent Ladeuil)
365
366* Help on hooks no longer says 'Not deprecated' for hooks that are
367 currently supported. (Ian Clatworthy, #422415)
368
34API Changes369API Changes
35***********370***********
36371
372* ``bzrlib.user_encoding`` has been removed; use
373 ``bzrlib.osutils.get_user_encoding`` instead. (Martin Pool)
374
37* ``bzrlib.tests`` now uses ``stopTestRun`` for its ``TestResult``375* ``bzrlib.tests`` now uses ``stopTestRun`` for its ``TestResult``
38 subclasses - the same as python's unittest module. (Robert Collins)376 subclasses - the same as python's unittest module. (Robert Collins)
377
378* ``diff._get_trees_to_diff`` has been renamed to
379 ``diff.get_trees_and_branches_to_diff``. It is now a public API, and it
380 returns the old and new branches. (Gary van der Merwe)
381
382* ``bzrlib.trace.log_error``, ``error`` and ``info`` have been deprecated.
383 (Martin Pool)
384
385* ``MutableTree.has_changes()`` does not require a tree parameter anymore. It
386 now defaults to comparing to the basis tree. It now checks for pending
387 merges too. ``Merger.check_basis`` has been deprecated and replaced by the
388 corresponding has_changes() calls. ``Merge.compare_basis``,
389 ``Merger.file_revisions`` and ``Merger.ensure_revision_trees`` have also
390 been deprecated.
391 (Vincent Ladeuil, #440631)
392
393* ``ProgressTask.note`` is deprecated.
394 (Martin Pool)
39395
40Internals396Internals
41*********397*********
42398
399* Added ``-Drelock`` debug flag. It will ``note`` a message every time a
400 repository or branch object is unlocked then relocked the same way.
401 (Andrew Bennetts)
402
403* ``BTreeLeafParser.extract_key`` has been tweaked slightly to reduce
404 mallocs while parsing the index (approx 3=>1 mallocs per key read).
405 This results in a 10% speedup while reading an index.
406 (John Arbash Meinel)
407
43* The ``bzrlib.lsprof`` module has a new class ``BzrProfiler`` which makes408* The ``bzrlib.lsprof`` module has a new class ``BzrProfiler`` which makes
44 profiling in some situations like callbacks and generators easier.409 profiling in some situations like callbacks and generators easier.
45 (Robert Collins)410 (Robert Collins)
@@ -50,27 +415,195 @@
50* Passing ``--lsprof-tests -v`` to bzr selftest will cause lsprof output to415* Passing ``--lsprof-tests -v`` to bzr selftest will cause lsprof output to
51 be output for every test. Note that this is very verbose! (Robert Collins)416 be output for every test. Note that this is very verbose! (Robert Collins)
52417
418* Setting ``BZR_TEST_PDB=1`` when running selftest will cause a pdb
419 post_mortem to be triggered when a test failure occurs. (Robert Collins)
420
421* Shell-like tests can now be written. Code in ``bzrlib/tests/script.py`` ,
422 documentation in ``developers/testing.txt`` for details.
423 (Vincent Ladeuil)
424
425* Some tests could end up with the same id, that was dormant for
426 a long time.
427 (Vincent Ladeuil, #442980)
428
429* Stop showing the number of tests due to missing features in the test
430 progress bar. (Martin Pool)
431
53* Test parameterisation now does a shallow copy, not a deep copy of the test432* Test parameterisation now does a shallow copy, not a deep copy of the test
54 to be parameterised. This is not expected to break external use of test433 to be parameterised. This is not expected to break external use of test
55 parameterisation, and is substantially faster. (Robert Collins)434 parameterisation, and is substantially faster. (Robert Collins)
56435
57436* Tests that try to open a bzr dir on an arbitrary transport will now
58bzr 2.0rc2437 fail unless they have explicitly permitted the transport via
59##########438 ``self.permit_url``. The standard test factories such as ``self.get_url``
60439 will permit the urls they provide automatically, so only exceptional
61Bug Fixes440 tests should need to do this. (Robert Collins)
62*********441
442* The break-in test no longer cares about clean shutdown of the child,
443 instead it is happy if the debugger starts up. (Robert Collins)
444
445* The full test suite is expected to pass when the C extensions are not
446 present. (Vincent Ladeuil, #430749)
447
448
449bzr 2.0.1
450#########
451
452:Codename: Stability First
453:2.0.1: 2009-10-14
454
455The first of our new ongoing bugfix-only stable releases has arrived. It
456includes a collection of 12 bugfixes applied to bzr 2.0.0, but does not
457include any of the feature development in the 2.1.0 series.
458
459
460Bug Fixes
461*********
462
463* ``bzr add`` in a tree that has files with ``\r`` or ``\n`` in the
464 filename will issue a warning and skip over those files.
465 (Robert Collins, #3918)
466
467* bzr will attempt to authenticate with SSH servers that support
468 ``keyboard-interactive`` auth but not ``password`` auth when using
469 Paramiko. (Andrew Bennetts, #433846)
470
471* Fixed fetches from a stacked branch on a smart server that were failing
472 with some combinations of remote and local formats. This was causing
473 "unknown object type identifier 60" errors. (Andrew Bennetts, #427736)
474
475* Fixed ``ObjectNotLocked`` errors when doing some log and diff operations
476 on branches via a smart server. (Andrew Bennetts, #389413)
477
478* Handle things like ``bzr add foo`` and ``bzr rm foo`` when the tree is
479 at the root of a drive. ``osutils._cicp_canonical_relpath`` always
480 assumed that ``abspath()`` returned a path that did not have a trailing
481 ``/``, but that is not true when working at the root of the filesystem.
482 (John Arbash Meinel, Jason Spashett, #322807)
483
484* Hide deprecation warnings for 'final' releases for python2.6.
485 (John Arbash Meinel, #440062)
486
487* Improve the time for ``bzr log DIR`` for 2a format repositories.
488 We had been using the same code path as for <2a formats, which required
489 iterating over all objects in all revisions.
490 (John Arbash Meinel, #374730)
491
492* Make sure that we unlock the tree if we fail to create a TreeTransform
493 object when doing a merge, and there is limbo, or pending-deletions
494 directory. (Gary van der Merwe, #427773)
495
496* Occasional IndexError on renamed files have been fixed. Operations that
497 set a full inventory in the working tree will now go via the
498 apply_inventory_delta code path which is simpler and easier to
499 understand than dirstates set_state_from_inventory method. This may
500 have a small performance impact on operations built on _write_inventory,
501 but such operations are already doing full tree scans, so no radical
502 performance change should be observed. (Robert Collins, #403322)
503
504* Retrieving file text or mtime from a _PreviewTree has good performance when
505 there are many changes. (Aaron Bentley)
506
507* The CHK index pages now use an unlimited cache size. With a limited
508 cache and a large project, the random access of chk pages could cause us
509 to download the entire cix file many times.
510 (John Arbash Meinel, #402623)
511
512* When a file kind becomes unversionable after being added, a sensible
513 error will be shown instead of a traceback. (Robert Collins, #438569)
514
515Documentation
516*************
517
518* Improved README. (Ian Clatworthy)
519
520* Improved upgrade documentation for Launchpad branches.
521 (Barry Warsaw)
522
523
524bzr 2.0.0
525#########
526
527:2.0.0: 2009-09-22
528:Codename: Instant Karma
529
530This release of Bazaar makes the 2a (previously 'brisbane-core') format
531the default when new branches or repositories are created. This format is
532substantially smaller and faster for many operations. Most of the work in
533this release focuses on bug fixes and stabilization, covering both 2a and
534previous formats. (See the Upgrade Guide for information on migrating
535existing projects.)
536
537This release also improves the documentation content and presentation,
538including adding Windows HtmlHelp manuals.
539
540The Bazaar team decided that 2.0 will be a long-term supported release,
541with bugfix-only 2.0.x releases based on it, continuing for at least six
542months or until the following stable release.
543
544Changes from 2.0.0rc2 to final
545******************************
546
547* Officially branded as 2.0.0 rather than 2.0 to clarify between things
548 that "want to happen on the 2.0.x stable series" versus things that want
549 to "land in 2.0.0". (Changes how bzrlib._format_version_tuple() handles
550 micro = 0.) (John Arbash Meinel)
551
552
553bzr 2.0.0rc2
554############
555
556:2.0.0rc2: 2009-09-10
557
558New Features
559************
560
561* Added post_commit hook for mutable trees. This allows the keywords
562 plugin to expand keywords on files changed by the commit.
563 (Ian Clatworthy, #408841)
564
565Bug Fixes
566*********
567
568* Bazaar's native protocol code now correctly handles EINTR, which most
569 noticeably occurs if you break in to the debugger while connected to a
570 bzr+ssh server. You can now can continue from the debugger (by typing
571 'c') and the process continues. However, note that pressing C-\ in the
572 shell may still kill the SSH process, which is bug 162509, so you must
573 sent a signal to the bzr process specifically, for example by typing
574 ``kill -QUIT PID`` in another shell. (Martin Pool, #341535)
63575
64* ``bzr check`` in pack-0.92, 1.6 and 1.9 format repositories will no576* ``bzr check`` in pack-0.92, 1.6 and 1.9 format repositories will no
65 longer report incorrect errors about ``Missing inventory ('TREE_ROOT', ...)``577 longer report incorrect errors about ``Missing inventory ('TREE_ROOT', ...)``
66 (Robert Collins, #416732)578 (Robert Collins, #416732)
67579
580* ``bzr info -v`` on a 2a format still claimed that it was a "Development
581 format" (John Arbash Meinel, #424392)
582
68* ``bzr log stacked-branch`` shows the full log including583* ``bzr log stacked-branch`` shows the full log including
69 revisions that are in the fallback repository. (Regressed in 2.0rc1).584 revisions that are in the fallback repository. (Regressed in 2.0rc1).
70 (John Arbash Meinel, #419241)585 (John Arbash Meinel, #419241)
71586
72* Fix a segmentation fault when computing the ``merge_sort`` of a graph587* Clearer message when Bazaar runs out of memory, instead of a ``MemoryError``
73 that has a ghost in the mainline ancestry.588 traceback. (Martin Pool, #109115)
589
590* Conversion to 2a will create a single pack for all the new revisions (as
591 long as it ran without interruption). This improves both ``bzr upgrade``
592 and ``bzr pull`` or ``bzr merge`` from local branches in older formats.
593 The autopack logic that occurs every 100 revisions during local
594 conversions was not returning that pack's identifier, which resulted in
595 the partial packs created during the conversion not being consolidated
596 at the end of the conversion process. (Robert Collins, #423818)
597
598* Fetches from 2a to 2a are now again requested in 'groupcompress' order.
599 Groups that are seen as 'underutilized' will be repacked on-the-fly.
600 This means that when the source is fully packed, there is minimal
601 overhead during the fetch, but if the source is poorly packed the result
602 is a fairly well packed repository (not as good as 'bzr pack' but
603 good-enough.) (Robert Collins, John Arbash Meinel, #402652)
604
605* Fix a potential segmentation fault when doing 'log' of a branch that had
606 ghosts in its mainline. (Evaluating None as a tuple is bad.)
74 (John Arbash Meinel, #419241)607 (John Arbash Meinel, #419241)
75608
76* ``groupcompress`` sort order is now more stable, rather than relying on609* ``groupcompress`` sort order is now more stable, rather than relying on
@@ -81,28 +614,41 @@
81 bugfix vs 2.0rc1, and all 2.0rc1 users should upgrade to 2.0rc2 before614 bugfix vs 2.0rc1, and all 2.0rc1 users should upgrade to 2.0rc2 before
82 converting repositories. (Robert Collins, #422849)615 converting repositories. (Robert Collins, #422849)
83616
617* Network streams now decode adjacent records of the same type into a
618 single stream, reducing layering churn. (Robert Collins)
619
620* Prevent some kinds of incomplete data from being committed to a 2a
621 repository, such as revisions without inventories, a missing chk_bytes
622 record for an inventory, or a missing text referenced by an inventory.
623 (Andrew Bennetts, #423506, #406687)
624
84Documentation625Documentation
85*************626*************
86627
628* Fix assertion error about "_remember_remote_is_before" when pushing to
629 older smart servers.
630 (Andrew Bennetts, #418931)
631
632* Help on hooks no longer says 'Not deprecated' for hooks that are
633 currently supported. (Ian Clatworthy, #422415)
634
635* PDF and CHM (Windows HtmlHelp) formats are now supported for the
636 user documentation. The HTML documentation is better broken up into
637 topics. (Ian Clatworthy)
638
639* The developer and foreign language documents are now separated
640 out so that searching in the HTML and CHM files produces more
641 useful results. (Ian Clatworthy)
642
87* The main table of contents now provides links to the new Migration Docs643* The main table of contents now provides links to the new Migration Docs
88 and Plugins Guide. (Ian Clatworthy)644 and Plugins Guide. (Ian Clatworthy)
89645
90646
91bzr 2.0rc1647bzr 2.0.0rc1
92##########648############
93
94649
95:Codename: no worries650:Codename: no worries
96:2.0rc1: 2009-08-26651:2.0.0rc1: 2009-08-26
97
98This release of Bazaar makes 2a 'brisbane-core' format the
99default. Most of the work in this release now focuses on bug
100fixes and stabilization, covering both 2a and previous formats.
101
102The Bazaar team decided that 2.0 will be a long-term supported
103release, with bugfix-only releases based on it continuing for at
104least six months or until the following stable release (we said
105that previously, but that's worth repeating).
106652
107Compatibility Breaks653Compatibility Breaks
108********************654********************
@@ -110,7 +656,7 @@
110* The default format for bzr is now ``2a``. This format brings many656* The default format for bzr is now ``2a``. This format brings many
111 significant performance and size improvements. bzr can pull from657 significant performance and size improvements. bzr can pull from
112 any existing repository into a ``2a`` one, but can only transfer658 any existing repository into a ``2a`` one, but can only transfer
113 into ``rich-root`` repositories from ``2a``. The Upgrade guide659 from ``2a`` into ``rich-root`` repositories. The Upgrade guide
114 has more information about this change. (Robert Collins)660 has more information about this change. (Robert Collins)
115661
116* On Windows auto-detection of Putty's plink.exe is disabled.662* On Windows auto-detection of Putty's plink.exe is disabled.
@@ -175,7 +721,7 @@
175* ``bzr shelve`` and ``bzr unshelve`` now work on windows.721* ``bzr shelve`` and ``bzr unshelve`` now work on windows.
176 (Robert Collins, #305006)722 (Robert Collins, #305006)
177723
178* Commit of specific files no longer prevents using the the iter_changes724* Commit of specific files no longer prevents using the iter_changes
179 codepath. On 2a repositories, commit of specific files should now be as725 codepath. On 2a repositories, commit of specific files should now be as
180 fast, or slightly faster, than a full commit. (Robert Collins)726 fast, or slightly faster, than a full commit. (Robert Collins)
181727
@@ -202,8 +748,17 @@
202Testing748Testing
203*******749*******
204750
205bzr 1.18.1 NOT RELEASED YET751bzr 1.18.1
206###########################752##########
753
754:Codename: nein nein nein!
755:1.18.1: 2009-09-09
756
757This release fixes two small but worthwhile bugs relevant to users on
758Microsoft Windows: some commands that failed on with locking errors will
759now work, and a bug that caused poor performance after committing a file
760with line-ending conversion has now been fixed. It also fixes a bug in
761pushing to older servers.
207762
208Bug Fixes763Bug Fixes
209*********764*********
@@ -212,13 +767,17 @@
212 conversion will commit too many copies a file.767 conversion will commit too many copies a file.
213 (Martin Pool, #415508)768 (Martin Pool, #415508)
214769
770* Fix assertion error about ``_remember_remote_is_before`` in
771 ``set_tags_bytes`` when pushing to older smart servers.
772 (Andrew Bennetts, Alexander Belchenko, #418931)
773
215Improvements774Improvements
216************775************
217776
218* ``bzr push`` locally on windows will no longer give a locking error with777* ``bzr push`` locally on Windows will no longer give a locking error with
219 dirstate based formats. (Robert Collins)778 dirstate based formats. (Robert Collins)
220779
221* ``bzr shelve`` and ``bzr unshelve`` now work on windows.780* ``bzr shelve`` and ``bzr unshelve`` now work on Windows.
222 (Robert Collins, #305006)781 (Robert Collins, #305006)
223782
224API Changes783API Changes
@@ -583,8 +1142,8 @@
583 knit format repositories. (Andrew Bennetts, #405653)1142 knit format repositories. (Andrew Bennetts, #405653)
584 1143
5851144
586bzr 1.17 "So late it's brunch" 2009-07-201145bzr 1.17
587#########################################1146########
588:Codename: so-late-its-brunch1147:Codename: so-late-its-brunch
589:1.17rc1: 2009-07-131148:1.17rc1: 2009-07-13
590:1.17: 2009-07-201149:1.17: 2009-07-20
@@ -833,8 +1392,10 @@
833 this class and the UI. (Martin Pool)1392 this class and the UI. (Martin Pool)
8341393
8351394
836bzr 1.16.1 2009-06-261395bzr 1.16.1
837#####################1396##########
1397
1398:Released: 2009-06-26
8381399
839End user testing of the 2a format revealed two serious bugs. The first,1400End user testing of the 2a format revealed two serious bugs. The first,
840#365615, caused bzr to raise AbsentContentFactory errors when autopacking.1401#365615, caused bzr to raise AbsentContentFactory errors when autopacking.
@@ -889,8 +1450,8 @@
889 (Robert Collins, #376748)1450 (Robert Collins, #376748)
8901451
8911452
892bzr 1.16 "It's yesterday in California" 2009-06-181453bzr 1.16
893##################################################1454########
894:Codename: yesterday-in-california1455:Codename: yesterday-in-california
895:1.16rc1: 2009-06-111456:1.16rc1: 2009-06-11
896:1.16: 2009-06-181457:1.16: 2009-06-18
@@ -929,7 +1490,7 @@
929************1490************
9301491
931* A new repository format ``2a`` has been added. This is a beta release1492* A new repository format ``2a`` has been added. This is a beta release
932 of the the brisbane-core (aka group-compress) project. This format now1493 of the brisbane-core (aka group-compress) project. This format now
933 suitable for wider testing by advanced users willing to deal with some1494 suitable for wider testing by advanced users willing to deal with some
934 bugs. We would appreciate test reports, either positive or negative.1495 bugs. We would appreciate test reports, either positive or negative.
935 Format 2a is substantially smaller and faster for many operations on1496 Format 2a is substantially smaller and faster for many operations on
@@ -1658,7 +2219,7 @@
16582219
1659* Added ``bzrlib.inventory_delta`` module. This will be used for2220* Added ``bzrlib.inventory_delta`` module. This will be used for
1660 serializing and deserializing inventory deltas for more efficient2221 serializing and deserializing inventory deltas for more efficient
1661 streaming on the the network. (Robert Collins, Andrew Bennetts)2222 streaming on the network. (Robert Collins, Andrew Bennetts)
16622223
1663* ``Branch._get_config`` has been added, which splits out access to the2224* ``Branch._get_config`` has been added, which splits out access to the
1664 specific config file from the branch. This is used to let RemoteBranch2225 specific config file from the branch. This is used to let RemoteBranch
@@ -2367,8 +2928,11 @@
2367 (Vincent Ladeuil)2928 (Vincent Ladeuil)
23682929
23692930
2370bzr 1.11 "Eyes up!" 2009-01-192931bzr 1.11
2371##############################2932########
2933
2934:Codename: "Eyes up!"
2935:Released: 2009-01-19
23722936
2373This first monthly release of Bazaar for 2009 improves Bazaar's operation2937This first monthly release of Bazaar for 2009 improves Bazaar's operation
2374in Windows, Mac OS X, and other situations where file names are matched2938in Windows, Mac OS X, and other situations where file names are matched
@@ -2394,8 +2958,11 @@
23942958
23952959
23962960
2397bzr 1.11rc1 "Eyes up!" 2009-01-092961bzr 1.11rc1
2398#################################2962###########
2963
2964:Codename: "Eyes up!"
2965:Released: 2009-01-09
23992966
2400Changes2967Changes
2401*******2968*******
@@ -2631,8 +3198,10 @@
26313198
26323199
26333200
2634bzr 1.10 2008-12-053201bzr 1.10
2635###################3202########
3203
3204:Released: 2008-12-05
26363205
2637Bazaar 1.10 has several performance improvements for copying revisions3206Bazaar 1.10 has several performance improvements for copying revisions
2638(especially for small updates to large projects). There has also been a3207(especially for small updates to large projects). There has also been a
@@ -2657,8 +3226,10 @@
2657 topologically. (John Arbash Meinel, #304841)3226 topologically. (John Arbash Meinel, #304841)
26583227
26593228
2660bzr 1.10rc1 2008-11-283229bzr 1.10rc1
2661######################3230###########
3231
3232:Released: 2008-11-28
26623233
2663This release of Bazaar focuses on performance improvements when pushing3234This release of Bazaar focuses on performance improvements when pushing
2664and pulling revisions, both locally and to remote networks. The popular3235and pulling revisions, both locally and to remote networks. The popular
@@ -2778,8 +3349,10 @@
2778* Doctests now only report the first failure. (Martin Pool)3349* Doctests now only report the first failure. (Martin Pool)
27793350
27803351
2781bzr 1.9 2008-11-073352bzr 1.9
2782##################3353#######
3354
3355:Released: 2008-11-07
27833356
2784This release of Bazaar adds a new repository format, ``1.9``, with smaller3357This release of Bazaar adds a new repository format, ``1.9``, with smaller
2785and more efficient index files. This format can be specified when3358and more efficient index files. This format can be specified when
@@ -2801,8 +3374,10 @@
2801 (John Arbash Meinel, #293746)3374 (John Arbash Meinel, #293746)
28023375
28033376
2804bzr 1.9rc1 2008-10-313377bzr 1.9rc1
2805#####################3378##########
3379
3380:Released: 2008-10-31
28063381
2807New Features3382New Features
2808************3383************
@@ -2919,8 +3494,10 @@
2919 configuration of authetication credentials.3494 configuration of authetication credentials.
29203495
29213496
2922bzr 1.8 2008-10-163497bzr 1.8
2923##################3498#######
3499
3500:Released: 2008-10-16
29243501
2925Bazaar 1.8 includes several fixes that improve working tree performance,3502Bazaar 1.8 includes several fixes that improve working tree performance,
2926display of revision logs, and merges. The bzr testsuite now passes on OS3503display of revision logs, and merges. The bzr testsuite now passes on OS
@@ -2941,8 +3518,10 @@
2941 that platform. (Alexander Belchenko, Martin Pool, #277481)3518 that platform. (Alexander Belchenko, Martin Pool, #277481)
29423519
29433520
2944bzr 1.8rc1 2008-10-073521bzr 1.8rc1
2945#####################3522##########
3523
3524:Released: 2008-10-07
29463525
2947Changes3526Changes
2948*******3527*******
@@ -3140,14 +3719,18 @@
3140 (Vincent Ladeuil)3719 (Vincent Ladeuil)
31413720
31423721
3143bzr 1.7.1 2008-10-013722bzr 1.7.1
3144####################3723#########
3724
3725:Released: 2008-10-01
31453726
3146No changes from 1.7.1rc1.3727No changes from 1.7.1rc1.
31473728
31483729
3149bzr 1.7.1rc1 2008-09-243730bzr 1.7.1rc1
3150#######################3731############
3732
3733:Released: 2008-09-24
31513734
3152This release just includes an update to how the merge algorithm handles3735This release just includes an update to how the merge algorithm handles
3153file paths when we encounter complex history.3736file paths when we encounter complex history.
@@ -3162,8 +3745,10 @@
3162 (John Arbash Meinel)3745 (John Arbash Meinel)
31633746
31643747
3165bzr 1.7 2008-09-233748bzr 1.7
3166##################3749#######
3750
3751:Released: 2008-09-23
31673752
3168This release includes many bug fixes and a few performance and feature3753This release includes many bug fixes and a few performance and feature
3169improvements. ``bzr rm`` will now scan for missing files and remove them,3754improvements. ``bzr rm`` will now scan for missing files and remove them,
@@ -3180,8 +3765,10 @@
3180 packaging qbzr. (Mark Hammond)3765 packaging qbzr. (Mark Hammond)
31813766
31823767
3183bzr 1.7rc2 2008-09-173768bzr 1.7rc2
3184#####################3769##########
3770
3771:Released: 2008-09-17
31853772
3186A few bug fixes from 1.7rc1. The biggest change is a new3773A few bug fixes from 1.7rc1. The biggest change is a new
3187``RemoteBranch.get_stacked_on_url`` rpc. This allows clients that are3774``RemoteBranch.get_stacked_on_url`` rpc. This allows clients that are
@@ -3205,8 +3792,10 @@
3205 (Andrew Bennetts)3792 (Andrew Bennetts)
32063793
32073794
3208bzr 1.7rc1 2008-09-093795bzr 1.7rc1
3209#####################3796##########
3797
3798:Released: 2008-09-09
32103799
3211This release candidate for bzr 1.7 has several bug fixes and a few3800This release candidate for bzr 1.7 has several bug fixes and a few
3212performance and feature improvements. ``bzr rm`` will now scan for3801performance and feature improvements. ``bzr rm`` will now scan for
@@ -3403,16 +3992,20 @@
3403 clients now use this mechanism. (Neil Martinsen-Burrell)3992 clients now use this mechanism. (Neil Martinsen-Burrell)
34043993
34053994
3406bzr 1.6.1 2008-09-053995bzr 1.6.1
3407####################3996#########
3997
3998:Released: 2008-09-05
34083999
3409A couple regressions were found in the 1.6 release. There was a4000A couple regressions were found in the 1.6 release. There was a
3410performance issue when using ``bzr+ssh`` to branch large repositories,4001performance issue when using ``bzr+ssh`` to branch large repositories,
3411and some problems with stacking and ``rich-root`` capable repositories.4002and some problems with stacking and ``rich-root`` capable repositories.
34124003
34134004
3414bzr 1.6.1rc2 2008-09-034005bzr 1.6.1rc2
3415#######################4006############
4007
4008:Released: 2008-09-03
34164009
3417Bug Fixes4010Bug Fixes
3418*********4011*********
@@ -3423,8 +4016,10 @@
3423 (John Arbash Meinel, #264321)4016 (John Arbash Meinel, #264321)
34244017
34254018
3426bzr 1.6.1rc1 2008-08-294019bzr 1.6.1rc1
3427#######################4020############
4021
4022:Released: 2008-08-29
34284023
3429This release fixes a few regressions found in the 1.6 client. Fetching4024This release fixes a few regressions found in the 1.6 client. Fetching
3430changes was using an O(N^2) buffering algorithm, so for large projects it4025changes was using an O(N^2) buffering algorithm, so for large projects it
@@ -3464,8 +4059,10 @@
3464 (John Arbash Meinel, #262333)4059 (John Arbash Meinel, #262333)
34654060
34664061
3467bzr 1.6 2008-08-254062bzr 1.6
3468##################4063#######
4064
4065:Released: 2008-08-25
34694066
3470Finally, the long awaited bzr 1.6 has been released. This release includes4067Finally, the long awaited bzr 1.6 has been released. This release includes
3471new features like Stacked Branches, improved weave merge, and an updated4068new features like Stacked Branches, improved weave merge, and an updated
@@ -3478,8 +4075,10 @@
3478TortoiseBzr in the standalone Windows installer.4075TortoiseBzr in the standalone Windows installer.
34794076
34804077
3481bzr 1.6rc5 2008-08-194078bzr 1.6rc5
3482#####################4079##########
4080
4081:Released: 2008-08-19
34834082
3484Bug Fixes4083Bug Fixes
3485*********4084*********
@@ -3491,8 +4090,10 @@
3491 (This change was reverted when merged to bzr.dev)4090 (This change was reverted when merged to bzr.dev)
34924091
34934092
3494bzr 1.6rc4 2008-08-184093bzr 1.6rc4
3495#####################4094##########
4095
4096:Released: 2008-08-18
34964097
3497Bug Fixes4098Bug Fixes
3498*********4099*********
@@ -3502,8 +4103,10 @@
3502 rather than preserving deltas. (John Arbash Meinel, #256757)4103 rather than preserving deltas. (John Arbash Meinel, #256757)
35034104
35044105
3505bzr 1.6rc3 2008-08-144106bzr 1.6rc3
3506#####################4107##########
4108
4109:Released: 2008-08-14
35074110
3508Changes4111Changes
3509*******4112*******
@@ -3536,8 +4139,10 @@
3536 development which is substantially faster. (Robert Collins)4139 development which is substantially faster. (Robert Collins)
35374140
35384141
3539bzr 1.6rc2 2008-08-134142bzr 1.6rc2
3540#####################4143##########
4144
4145:Released: 2008-08-13
35414146
3542This release candidate has a few minor bug fixes, and some regression4147This release candidate has a few minor bug fixes, and some regression
3543fixes for Windows.4148fixes for Windows.
@@ -3575,8 +4180,10 @@
3575 will get the same results. (John Arbash Meinel, #232188)4180 will get the same results. (John Arbash Meinel, #232188)
35764181
35774182
3578bzr 1.6rc1 2008-08-064183bzr 1.6rc1
3579#####################4184##########
4185
4186:Released: 2008-08-06
35804187
3581This release candidate for bzr 1.6 solidifies the new branch stacking4188This release candidate for bzr 1.6 solidifies the new branch stacking
3582feature. Bazaar now recommends that users upgrade all knit repositories,4189feature. Bazaar now recommends that users upgrade all knit repositories,
@@ -3712,8 +4319,10 @@
3712 (Ian Clatworthy)4319 (Ian Clatworthy)
37134320
37144321
3715bzr 1.6beta3 2008-07-174322bzr 1.6beta3
3716#######################4323############
4324
4325:Released: 2008-07-17
37174326
3718This release adds a new 'stacked branches' feature allowing branches to4327This release adds a new 'stacked branches' feature allowing branches to
3719share storage without being in the same repository or on the same machine.4328share storage without being in the same repository or on the same machine.
@@ -3885,8 +4494,10 @@
3885 (Robert Collins)4494 (Robert Collins)
38864495
38874496
3888bzr 1.6beta2 2008-06-104497bzr 1.6beta2
3889#######################4498############
4499
4500:Released: 2008-06-10
38904501
3891This release contains further progress towards our 1.6 goals of shallow4502This release contains further progress towards our 1.6 goals of shallow
3892repositories, and contains a fix for some user-affecting bugs in the4503repositories, and contains a fix for some user-affecting bugs in the
@@ -3969,9 +4580,10 @@
3969* Knit record serialisation is now stricter on what it will accept, to4580* Knit record serialisation is now stricter on what it will accept, to
3970 guard against potential internal bugs, or broken input. (Robert Collins)4581 guard against potential internal bugs, or broken input. (Robert Collins)
39714582
3972bzr 1.6beta1 2008-06-024583bzr 1.6beta1
3973#######################4584############
39744585
4586:Released: 2008-06-02
39754587
3976Commands that work on the revision history such as push, pull, missing,4588Commands that work on the revision history such as push, pull, missing,
3977uncommit and log are now substantially faster. This release adds a4589uncommit and log are now substantially faster. This release adds a
@@ -4189,8 +4801,10 @@
4189 (Martin Pool)4801 (Martin Pool)
41904802
41914803
4192bzr 1.5 2008-05-164804bzr 1.5
4193##################4805#######
4806
4807:Released: 2008-05-16
41944808
4195This release of Bazaar includes several updates to the documentation, and fixes4809This release of Bazaar includes several updates to the documentation, and fixes
4196to prepare for making rich root support the default format. Many bugs have been4810to prepare for making rich root support the default format. Many bugs have been
@@ -4211,8 +4825,10 @@
4211 (Ian Clatworthy)4825 (Ian Clatworthy)
42124826
42134827
4214bzr 1.5rc1 2008-05-094828bzr 1.5rc1
4215#####################4829##########
4830
4831:Released: 2008-05-09
42164832
4217Changes4833Changes
4218*******4834*******
@@ -4327,7 +4943,7 @@
4327 exception. (Andrew Bennetts)4943 exception. (Andrew Bennetts)
43284944
4329* New ``--debugflag``/``-E`` option to ``bzr selftest`` for setting4945* New ``--debugflag``/``-E`` option to ``bzr selftest`` for setting
4330 options for debugging tests, these are complementary to the the -D4946 options for debugging tests, these are complementary to the -D
4331 options. The ``-Dselftest_debug`` global option has been replaced by the4947 options. The ``-Dselftest_debug`` global option has been replaced by the
4332 ``-E=allow_debug`` option for selftest. (Andrew Bennetts)4948 ``-E=allow_debug`` option for selftest. (Andrew Bennetts)
43334949
@@ -4382,8 +4998,10 @@
4382 (Martin Pool)4998 (Martin Pool)
43834999
43845000
4385bzr 1.4 2008-04-285001bzr 1.4
4386##################5002#######
5003
5004:Released: 2008-04-28
43875005
4388This release of Bazaar includes handy improvements to the speed of log and5006This release of Bazaar includes handy improvements to the speed of log and
4389status, new options for several commands, improved documentation, and better5007status, new options for several commands, improved documentation, and better
@@ -4402,8 +5020,10 @@
4402 (John Arbash Meinel, Andrew Bennetts, #214894)5020 (John Arbash Meinel, Andrew Bennetts, #214894)
44035021
44045022
4405bzr 1.4rc2 2008-04-215023bzr 1.4rc2
4406#####################5024##########
5025
5026:Released: 2008-04-21
44075027
4408Bug Fixes5028Bug Fixes
4409*********5029*********
@@ -4426,8 +5046,10 @@
4426 (Robert Collins, John Arbash Meinel)5046 (Robert Collins, John Arbash Meinel)
44275047
44285048
4429bzr 1.4rc1 2008-04-115049bzr 1.4rc1
4430#####################5050##########
5051
5052:Released: 2008-04-11
44315053
4432Changes5054Changes
4433*******5055*******
@@ -4714,14 +5336,18 @@
4714 ``Graph.get_parent_map`` returns a dict of key:parents. (Robert Collins)5336 ``Graph.get_parent_map`` returns a dict of key:parents. (Robert Collins)
47155337
47165338
4717bzr 1.3.1 2008-04-095339bzr 1.3.1
4718####################5340#########
5341
5342:Released: 2008-04-09
47195343
4720No changes from 1.3.1rc1.5344No changes from 1.3.1rc1.
47215345
47225346
4723bzr 1.3.1rc1 2008-04-045347bzr 1.3.1rc1
4724#######################5348############
5349
5350:Released: 2008-04-04
47255351
4726Bug Fixes5352Bug Fixes
4727*********5353*********
@@ -4732,8 +5358,10 @@
4732 (#208418, Andrew Bennetts, Martin Pool, Robert Collins)5358 (#208418, Andrew Bennetts, Martin Pool, Robert Collins)
47335359
47345360
4735bzr 1.3 2008-03-205361bzr 1.3
4736##################5362#######
5363
5364:Released: 2008-03-20
47375365
4738Bazaar has become part of the GNU project <http://www.gnu.org>5366Bazaar has become part of the GNU project <http://www.gnu.org>
47395367
@@ -4749,8 +5377,10 @@
4749 (#202778, Martin Pool)5377 (#202778, Martin Pool)
47505378
47515379
4752bzr 1.3rc1 2008-03-165380bzr 1.3rc1
4753#####################5381##########
5382
5383:Released: 2008-03-16
47545384
4755Notes When Upgrading5385Notes When Upgrading
4756********************5386********************
@@ -4936,8 +5566,10 @@
4936 format. (Robert Collins)5566 format. (Robert Collins)
49375567
49385568
4939bzr 1.2 2008-02-155569bzr 1.2
4940##################5570#######
5571
5572:Released: 2008-02-15
49415573
4942Bug Fixes5574Bug Fixes
4943*********5575*********
@@ -4945,8 +5577,10 @@
4945* Fix failing test in Launchpad plugin. (Martin Pool)5577* Fix failing test in Launchpad plugin. (Martin Pool)
49465578
49475579
4948bzr 1.2rc1 2008-02-135580bzr 1.2rc1
4949#####################5581##########
5582
5583:Released: 2008-02-13
49505584
4951Notes When Upgrading5585Notes When Upgrading
4952********************5586********************
@@ -5147,13 +5781,17 @@
5147 revision names etc. (Robert Collins)5781 revision names etc. (Robert Collins)
51485782
51495783
5150bzr 1.1 2008-01-155784bzr 1.1
5151##################5785#######
5786
5787:Released: 2008-01-15
51525788
5153(no changes from 1.1rc1)5789(no changes from 1.1rc1)
51545790
5155bzr 1.1rc1 2008-01-055791bzr 1.1rc1
5156#####################5792##########
5793
5794:Released: 2008-01-05
51575795
5158Changes5796Changes
5159*******5797*******
@@ -5363,8 +6001,10 @@
5363 replaced by the new helper methods added in this release. (Robert Collins)6001 replaced by the new helper methods added in this release. (Robert Collins)
53646002
53656003
5366bzr 1.0 2007-12-146004bzr 1.0
5367##################6005#######
6006
6007:Released: 2007-12-14
53686008
5369Documentation6009Documentation
5370*************6010*************
@@ -5381,8 +6021,10 @@
5381 (Ian Clatworthy)6021 (Ian Clatworthy)
53826022
53836023
5384bzr 1.0rc3 2007-12-116024bzr 1.0rc3
5385#####################6025##########
6026
6027:Released: 2007-12-11
53866028
5387Changes6029Changes
5388*******6030*******
@@ -5423,8 +6065,10 @@
5423 (Vincent Ladeuil)6065 (Vincent Ladeuil)
54246066
54256067
5426bzr 1.0rc2 2007-12-076068bzr 1.0rc2
5427#####################6069##########
6070
6071:Released: 2007-12-07
54286072
5429Improvements6073Improvements
5430************6074************
@@ -5498,8 +6142,10 @@
5498 ``started`` methods. (Matt Nordhoff)6142 ``started`` methods. (Matt Nordhoff)
54996143
55006144
5501bzr 1.0rc1 2007-11-306145bzr 1.0rc1
5502#####################6146##########
6147
6148:Released: 2007-11-30
55036149
5504Notes When Upgrading6150Notes When Upgrading
5505********************6151********************
@@ -5775,8 +6421,10 @@
5775* InventoryEntry.diff is now deprecated. Please use diff.DiffTree instead.6421* InventoryEntry.diff is now deprecated. Please use diff.DiffTree instead.
57766422
57776423
5778bzr 0.92 2007-11-056424bzr 0.92
5779###################6425########
6426
6427:Released: 2007-11-05
57806428
5781Changes6429Changes
5782*******6430*******
@@ -5784,8 +6432,10 @@
5784 * New uninstaller on Win32. (Alexander Belchenko)6432 * New uninstaller on Win32. (Alexander Belchenko)
57856433
57866434
5787bzr 0.92rc1 2007-10-296435bzr 0.92rc1
5788######################6436###########
6437
6438:Released: 2007-10-29
57896439
5790Changes6440Changes
5791*******6441*******
@@ -6104,8 +6754,10 @@
6104 raises a Python warning. (Martin Pool)6754 raises a Python warning. (Martin Pool)
61056755
61066756
6107bzr 0.91 2007-09-266757bzr 0.91
6108###################6758########
6759
6760:Released: 2007-09-26
61096761
6110Bug Fixes6762Bug Fixes
6111*********6763*********
@@ -6126,15 +6778,19 @@
6126 (Andrew Bennetts)6778 (Andrew Bennetts)
61276779
61286780
6129bzr 0.91rc2 2007-09-116781bzr 0.91rc2
6130######################6782###########
6783
6784:Released: 2007-09-11
61316785
6132* Replaced incorrect tarball for previous release; a debug statement was left6786* Replaced incorrect tarball for previous release; a debug statement was left
6133 in bzrlib/remote.py.6787 in bzrlib/remote.py.
61346788
61356789
6136bzr 0.91rc1 2007-09-116790bzr 0.91rc1
6137######################6791###########
6792
6793:Released: 2007-09-11
61386794
6139Changes6795Changes
6140*******6796*******
@@ -6461,8 +7117,10 @@
6461 [] to revert all files is deprecated. (Aaron Bentley)7117 [] to revert all files is deprecated. (Aaron Bentley)
64627118
64637119
6464bzr 0.90 2007-08-287120bzr 0.90
6465###################7121########
7122
7123:Released: 2007-08-28
64667124
6467Improvements7125Improvements
6468************7126************
@@ -6485,8 +7143,10 @@
6485 and call ``create_repository`` on that. (Martin Pool)7143 and call ``create_repository`` on that. (Martin Pool)
64867144
64877145
6488bzr 0.90rc1 2007-08-147146bzr 0.90rc1
6489######################7147###########
7148
7149:Released: 2007-08-14
64907150
6491Bugfixes7151Bugfixes
6492********7152********
@@ -6758,8 +7418,10 @@
6758 parameter. Varargs-style parameters are deprecated. (Aaron Bentley)7418 parameter. Varargs-style parameters are deprecated. (Aaron Bentley)
67597419
67607420
6761bzr 0.18 2007-07-177421bzr 0.18
6762####################7422########
7423
7424:Released: 2007-07-17
67637425
6764Bugfixes7426Bugfixes
6765********7427********
@@ -6767,8 +7429,10 @@
6767* Fix 'bzr add' crash under Win32 (Kuno Meyer)7429* Fix 'bzr add' crash under Win32 (Kuno Meyer)
67687430
67697431
6770bzr 0.18rc1 2007-07-107432bzr 0.18rc1
6771#######################7433###########
7434
7435:Released: 2007-07-10
67727436
6773Bugfixes7437Bugfixes
6774********7438********
@@ -7019,8 +7683,10 @@
7019 (Vincent Ladeuil, #110448)7683 (Vincent Ladeuil, #110448)
70207684
70217685
7022bzr 0.17 2007-06-187686bzr 0.17
7023####################7687########
7688
7689:Released: 2007-06-18
70247690
7025Bugfixes7691Bugfixes
7026********7692********
@@ -7032,8 +7698,10 @@
7032 (Aaron Bentley, Ian Clatworthy, #120930)7698 (Aaron Bentley, Ian Clatworthy, #120930)
70337699
70347700
7035bzr 0.17rc1 2007-06-127701bzr 0.17rc1
7036#######################7702###########
7703
7704:Released: 2007-06-12
70377705
7038Notes When Upgrading7706Notes When Upgrading
7039********************7707********************
@@ -7134,8 +7802,10 @@
7134 your repository. (Previously Branch6 only supported revisions in your7802 your repository. (Previously Branch6 only supported revisions in your
7135 mainline). (John Arbash Meinel, #115343)7803 mainline). (John Arbash Meinel, #115343)
71367804
7137bzr 0.16 2007-05-077805bzr 0.16
7138####################7806########
7807
7808:Released: 2007-05-07
71397809
7140Bugfixes7810Bugfixes
7141********7811********
@@ -7165,8 +7835,10 @@
7165 diff`` and ``bzr status`` significantly improving the speed of7835 diff`` and ``bzr status`` significantly improving the speed of
7166 both. (John Arbash Meinel)7836 both. (John Arbash Meinel)
71677837
7168bzr 0.16rc2 2007-04-307838bzr 0.16rc2
7169#######################7839###########
7840
7841:Released: 2007-04-30
71707842
7171Bugfixes7843Bugfixes
7172********7844********
@@ -7189,8 +7861,10 @@
7189* ``WorkingTree4._iter_changes`` should not descend into unversioned7861* ``WorkingTree4._iter_changes`` should not descend into unversioned
7190 directories. (John Arbash Meinel, #110399)7862 directories. (John Arbash Meinel, #110399)
71917863
7192bzr 0.16rc1 2007-04-267864bzr 0.16rc1
7193#######################7865###########
7866
7867:Released: 2007-04-26
71947868
7195Notes When Upgrading7869Notes When Upgrading
7196********************7870********************
@@ -7497,8 +8171,10 @@
7497 implementation of new auth schemes for both http and proxy.8171 implementation of new auth schemes for both http and proxy.
7498 (Vincent Ladeuil)8172 (Vincent Ladeuil)
74998173
7500bzr 0.15 2007-04-018174bzr 0.15
7501###################8175########
8176
8177:Released: 2007-04-01
75028178
7503Bugfixes8179Bugfixes
7504********8180********
@@ -7510,8 +8186,10 @@
7510 checking out a branch that contains an old-format working tree.8186 checking out a branch that contains an old-format working tree.
7511 (Martin Pool)8187 (Martin Pool)
75128188
7513bzr 0.15rc3 2007-03-268189bzr 0.15rc3
7514#######################8190###########
8191
8192:Released: 2007-03-26
75158193
7516Changes8194Changes
7517*******8195*******
@@ -7586,8 +8264,10 @@
7586* Correctly handles mutiple permanent http redirections.8264* Correctly handles mutiple permanent http redirections.
7587 (vila, #88780)8265 (vila, #88780)
75888266
7589bzr 0.15rc2 2007-03-148267bzr 0.15rc2
7590#######################8268###########
8269
8270:Released: 2007-03-14
75918271
7592Notes When Upgrading8272Notes When Upgrading
7593********************8273********************
@@ -7640,8 +8320,10 @@
7640 (Wouter van Heyst, #53483)8320 (Wouter van Heyst, #53483)
76418321
76428322
7643bzr 0.15rc1 2007-03-078323bzr 0.15rc1
7644#######################8324###########
8325
8326:Released: 2007-03-07
76458327
7646Surprises8328Surprises
7647*********8329*********
@@ -7871,8 +8553,10 @@
7871 before the rest of the suite. (Martin Pool)8553 before the rest of the suite. (Martin Pool)
78728554
78738555
7874bzr 0.14 2007-01-238556bzr 0.14
7875####################8557########
8558
8559:Released: 2007-01-23
78768560
7877Improvements8561Improvements
7878************8562************
@@ -7891,8 +8575,10 @@
7891 it is in is below a repository. (James Westby, #77306)8575 it is in is below a repository. (James Westby, #77306)
78928576
78938577
7894bzr 0.14rc1 2007-01-168578bzr 0.14rc1
7895#######################8579###########
8580
8581:Released: 2007-01-16
78968582
7897Improvements8583Improvements
7898************8584************
@@ -8026,14 +8712,18 @@
8026 (Alexander Belchenko, #68124)8712 (Alexander Belchenko, #68124)
80278713
80288714
8029bzr 0.13 2006-12-058715bzr 0.13
8030####################8716########
8717
8718:Released: 2006-12-05
80318719
8032No changes from 0.13rc8720No changes from 0.13rc
80338721
80348722
8035bzr 0.13rc1 2006-11-278723bzr 0.13rc1
8036#######################8724###########
8725
8726:Released: 2006-11-27
80378727
8038Improvements8728Improvements
8039************8729************
@@ -8158,8 +8848,10 @@
8158* TestingHTTPRequestHandler really handles the Range header8848* TestingHTTPRequestHandler really handles the Range header
8159 (previously it was ignoring it and returning the whole file,).8849 (previously it was ignoring it and returning the whole file,).
81608850
8161bzr 0.12 2006-10-308851bzr 0.12
8162####################8852########
8853
8854:Released: 2006-10-30
81638855
8164Internals8856Internals
8165*********8857*********
@@ -8168,8 +8860,10 @@
8168 and remove benchmarks that take longer than 10min to run.8860 and remove benchmarks that take longer than 10min to run.
8169 (John Arbash Meinel)8861 (John Arbash Meinel)
81708862
8171bzr 0.12rc1 2006-10-238863bzr 0.12rc1
8172#######################8864###########
8865
8866:Released: 2006-10-23
81738867
8174Improvements8868Improvements
8175************8869************
@@ -8290,13 +8984,17 @@
8290 option to set the BzrDir, Repository and Branch formats of the8984 option to set the BzrDir, Repository and Branch formats of the
8291 created objects. (Robert Collins, John Arbash Meinel)8985 created objects. (Robert Collins, John Arbash Meinel)
82928986
8293bzr 0.11 2006-10-028987bzr 0.11
8294####################8988########
8989
8990:Released: 2006-10-02
82958991
8296* Smart server transport test failures on windows fixed. (Lukáš Lalinský).8992* Smart server transport test failures on windows fixed. (Lukáš Lalinský).
82978993
8298bzr 0.11rc2 2006-09-278994bzr 0.11rc2
8299#######################8995###########
8996
8997:Released: 2006-09-27
83008998
8301Bug Fixes8999Bug Fixes
8302*********9000*********
@@ -8306,8 +9004,10 @@
8306* Commit performance regression fixed. (Aaron Bentley, Robert Collins, John9004* Commit performance regression fixed. (Aaron Bentley, Robert Collins, John
8307 Arbash Meinel).9005 Arbash Meinel).
83089006
8309bzr 0.11rc1 2006-09-259007bzr 0.11rc1
8310#######################9008###########
9009
9010:Released: 2006-09-25
83119011
8312Improvements9012Improvements
8313************9013************
@@ -8500,8 +9200,10 @@
8500 allow upgrades to a richer interface than the VFS one provided by9200 allow upgrades to a richer interface than the VFS one provided by
8501 Transport. (Andrew Bennetts, Martin Pool)9201 Transport. (Andrew Bennetts, Martin Pool)
85029202
8503bzr 0.10 2006-08-299203bzr 0.10
8504####################9204########
9205
9206:Released: 2006-08-29
85059207
8506Improvements9208Improvements
8507************9209************
@@ -8578,8 +9280,10 @@
8578 need to be installed. This should help make the life of packagers9280 need to be installed. This should help make the life of packagers
8579 easier. (John Arbash Meinel)9281 easier. (John Arbash Meinel)
85809282
8581bzr 0.9.0 2006-08-119283bzr 0.9.0
8582#####################9284#########
9285
9286:Released: 2006-08-11
85839287
8584Surprises9288Surprises
8585*********9289*********
@@ -8846,16 +9550,20 @@
88469550
8847* "RevisionTree" is now in bzrlib/revisiontree.py. (Robert Collins)9551* "RevisionTree" is now in bzrlib/revisiontree.py. (Robert Collins)
88489552
8849bzr 0.8.2 2006-05-179553bzr 0.8.2
8850#####################9554#########
9555
9556:Released: 2006-05-17
88519557
8852Bug Fixes9558Bug Fixes
8853*********9559*********
88549560
8855* setup.py failed to install launchpad plugin. (Martin Pool)9561* setup.py failed to install launchpad plugin. (Martin Pool)
88569562
8857bzr 0.8.1 2006-05-169563bzr 0.8.1
8858#####################9564#########
9565
9566:Released: 2006-05-16
88599567
8860Bug Fixes9568Bug Fixes
8861*********9569*********
@@ -8908,8 +9616,10 @@
8908* Fix test case for bzr info in upgrading a standalone branch to metadir,9616* Fix test case for bzr info in upgrading a standalone branch to metadir,
8909 uses bzrlib api now. (Olaf Conradi)9617 uses bzrlib api now. (Olaf Conradi)
89109618
8911bzr 0.8 2006-05-089619bzr 0.8
8912###################9620#######
9621
9622:Released: 2006-05-08
89139623
8914Notes When Upgrading9624Notes When Upgrading
8915********************9625********************
@@ -9170,8 +9880,10 @@
9170* ``run_bzr`` and ``run_bzr_captured`` now accept a 'stdin="foo"'9880* ``run_bzr`` and ``run_bzr_captured`` now accept a 'stdin="foo"'
9171 parameter which will provide String("foo") to the command as its stdin.9881 parameter which will provide String("foo") to the command as its stdin.
91729882
9173bzr 0.7 2006-01-099883bzr 0.7
9174##################9884#######
9885
9886:Released: 2006-01-09
91759887
9176Changes9888Changes
9177*******9889*******
@@ -9466,8 +10178,10 @@
9466* ``bzrlib.osutils.safe_unicode`` now exists to provide parameter coercion10178* ``bzrlib.osutils.safe_unicode`` now exists to provide parameter coercion
9467 for functions that need unicode strings. (Robert Collins)10179 for functions that need unicode strings. (Robert Collins)
946810180
9469bzr 0.6 2005-10-2810181bzr 0.6
9470##################10182#######
10183
10184:Released: 2005-10-28
947110185
9472Improvements10186Improvements
9473************10187************
@@ -9682,8 +10396,10 @@
9682 [-1] in the revision-history. (Andres Salomon)10396 [-1] in the revision-history. (Andres Salomon)
968310397
968410398
9685bzr 0.1.1 2005-10-1210399bzr 0.1.1
9686####################10400#########
10401
10402:Released: 2005-10-12
968710403
9688Bug Fixes10404Bug Fixes
9689*********10405*********
@@ -9700,8 +10416,10 @@
9700* Avoid some unnecessary http operations in branch and pull.10416* Avoid some unnecessary http operations in branch and pull.
970110417
970210418
9703bzr 0.1 2005-10-1110419bzr 0.1
9704##################10420#######
10421
10422:Released: 2005-10-11
970510423
9706Notes10424Notes
9707*****10425*****
@@ -9830,8 +10548,10 @@
9830 of tests to run, e.g. ``bzr selftest test_weave``10548 of tests to run, e.g. ``bzr selftest test_weave``
983110549
983210550
9833bzr 0.0.9 2005-09-2310551bzr 0.0.9
9834####################10552#########
10553
10554:Released: 2005-09-23
983510555
9836Bug Fixes10556Bug Fixes
9837*********10557*********
@@ -9872,8 +10592,11 @@
9872 another (used by pull, merged, etc.)10592 another (used by pull, merged, etc.)
987310593
987410594
9875bzr 0.0.8 2005-09-2010595bzr 0.0.8
9876####################10596#########
10597
10598:Released: 2005-09-20
10599
987710600
9878Improvements10601Improvements
9879************10602************
@@ -9923,8 +10646,10 @@
9923* Quieten warnings about locking; patch from Matt Lavin.10646* Quieten warnings about locking; patch from Matt Lavin.
992410647
992510648
9926bzr-0.0.7 2005-09-0210649bzr-0.0.7
9927####################10650#########
10651
10652:Released: 2005-09-02
992810653
9929New Features10654New Features
9930************10655************
@@ -9978,8 +10703,10 @@
997810703
997910704
998010705
9981bzr-0.0.6 2005-08-1810706bzr-0.0.6
9982####################10707#########
10708
10709:Released: 2005-08-18
998310710
9984New Features10711New Features
9985************10712************
@@ -10064,8 +10791,10 @@
10064* Fix bugs in committing only selected files or within a subdirectory.10791* Fix bugs in committing only selected files or within a subdirectory.
1006510792
1006610793
10067bzr-0.0.5 2005-06-1510794bzr-0.0.5
10068#####################10795#########
10796
10797:Released: 2005-06-15
1006910798
10070Changes10799Changes
10071*******10800*******
@@ -10206,8 +10935,10 @@
10206 2.4 is now only recommended.10935 2.4 is now only recommended.
1020710936
1020810937
10209bzr-0.0.4 2005-04-2210938bzr-0.0.4
10210#####################10939#########
10940
10941:Released: 2005-04-22
1021110942
10212Enhancements10943Enhancements
10213************10944************
@@ -10275,8 +11006,10 @@
10275 from QuantumG.11006 from QuantumG.
1027611007
1027711008
10278bzr-0.0.3 2005-04-0611009bzr-0.0.3
10279#####################11010#########
11011
11012:Released: 2005-04-06
1028011013
10281Enhancements11014Enhancements
10282************11015************
@@ -10330,8 +11063,11 @@
10330* Win32 fixes from Steve Brown.11063* Win32 fixes from Steve Brown.
1033111064
1033211065
10333bzr-0.0.2 "black cube" 2005-03-3111066bzr-0.0.2
10334###################################11067#########
11068
11069:Codename: "black cube"
11070:Released: 2005-03-31
1033511071
10336Enhancements11072Enhancements
10337************11073************
@@ -10359,8 +11095,10 @@
10359 the root directory only.11095 the root directory only.
1036011096
1036111097
10362bzr-0.0.1 2005-03-2611098bzr-0.0.1
10363#####################11099#########
11100
11101:Released: 2005-03-26
1036411102
10365Enhancements11103Enhancements
10366************11104************
@@ -10389,8 +11127,10 @@
10389 supported).11127 supported).
1039011128
1039111129
10392bzr-0.0.0.69 2005-03-2211130bzr-0.0.0.69
10393########################11131############
11132
11133:Released: 2005-03-22
1039411134
10395Enhancements11135Enhancements
10396************11136************
@@ -10400,5 +11140,38 @@
10400* Storage of local versions: init, add, remove, rm, info, log,11140* Storage of local versions: init, add, remove, rm, info, log,
10401 diff, status, etc.11141 diff, status, etc.
1040211142
11143
11144bzr ?.?.? (not released yet)
11145############################
11146
11147:Codename: template
11148:2.0.2: ???
11149
11150Compatibility Breaks
11151********************
11152
11153New Features
11154************
11155
11156Bug Fixes
11157*********
11158
11159Improvements
11160************
11161
11162Documentation
11163*************
11164
11165API Changes
11166***********
11167
11168Internals
11169*********
11170
11171Testing
11172*******
11173
11174
11175
10403..11176..
10404 vim: tw=74 ft=rst ff=unix11177 vim: tw=74 ft=rst ff=unix
1040511178
=== modified file 'README'
--- README 2008-03-16 14:01:20 +0000
+++ README 2009-11-03 09:40:55 +0000
@@ -3,72 +3,44 @@
3=================3=================
44
5Bazaar (``bzr``) is a decentralized revision control system, designed to be5Bazaar (``bzr``) is a decentralized revision control system, designed to be
6easy for developers and end users alike. Bazaar is part of the GNU project to6easy for developers and end users alike. Bazaar is part of the GNU project
7develop a complete free operating system.7to develop a complete free operating system.
88
9To install Bazaar from source, follow the instructions in the INSTALL9To install Bazaar, follow the instructions given at
10file. Otherwise, you may want to check your distribution package manager10http://bazaar-vcs.org/Download. Ready-to-install packages are available
11for ready-to-install packages, or http://bazaar-vcs.org/DistroDownloads.11for most popular operating systems or you can install from source.
1212
13To learn how to use Bazaar, check the documentation in the doc/ directory.13To learn how to use Bazaar, see the official documentation at:
14Once installed, you can also run 'bzr help'. An always up-to-date and more14
15complete set of documents can be found in the Bazaar website, at:15 http://doc.bazaar-vcs.org/en/
1616
17 http://bazaar-vcs.org/Documentation17For additional training materials including screencasts and slides,
18visit our community wiki documentation page at:
19
20 http://bazaar-vcs.org/Documentation/
1821
19Bazaar is written in Python, and is sponsored by Canonical Limited, the22Bazaar is written in Python, and is sponsored by Canonical Limited, the
20founders of Ubuntu and Launchpad. Bazaar is Free Software, and is released23founders of Ubuntu and Launchpad. Bazaar is Free Software, and is released
21under the GNU General Public License.24under the GNU General Public License.
2225
23Bazaar was formerly known as Bazaar-NG. It's the successor to ``baz``, a fork
24of GNU arch, but shares no code. (To upgrade from Baz, use the ``baz-import``
25command in the bzrtools plugin.)
26
27Bazaar highlights26Bazaar highlights
28=================27=================
2928
30* Easy to use and intuitive.29Bazaar directly supports both central version control (like cvs/svn) and
3130distributed version control (like git/hg). Developers can organize their
32 Only five commands are needed to do all basic operations, and all31workspace in whichever way they want on a per project basis including:
33 commands have documentation accessible via 'bzr help command'.32
34 Bazaar's interface is also easy to learn for CVS and Subversion users.33* checkouts (like svn)
3534* feature branches (like hg)
36* Robust and reliable.35* shared working tree (like git).
3736
38 Bazaar is developed under an extensive test suite. Branches can be37It also directly supports and encourages a large number of development best
39 checked and verified for integrity at any time, and revisions can be38practices like refactoring and pre-commit regression testing. Users can
40 signed with PGP/GnuPG.39choose between our command line tool and our cross-platform GUI application.
4140For further details, see our website at http://bazaar-vcs.org/en.
42* Publish branches with HTTP.41
4342Feedback
44 Branches can be hosted on an HTTP server with no need for special43========
45 software on the server side. Branches can be uploaded by bzr itself
46 over SSH (SFTP), or with rsync.
47
48* Adapts to multiple environments.
49
50 Bazaar runs on Linux and Windows, fully supports Unicode filenames,
51 and suits different development models, including centralized.
52
53* Easily extended and customized.
54
55 A rich Python interface is provided for extending and embedding,
56 including a plugin interface. There are already many available plugins,
57 most of them registered at http://bazaar-vcs.org/PluginRegistry.
58
59* Smart merging.
60
61 Changes will never be merged more than once, conflicts will be
62 minimized, and identical changes are dealt with well.
63
64* Vibrant and active community.
65
66 Help with Bazaar is obtained easily, via the mailing list, or the IRC
67 channel.
68
69
70Registration and Feedback
71=========================
7244
73If you encounter any problems with Bazaar, need help understanding it, or would45If you encounter any problems with Bazaar, need help understanding it, or would
74like to offer suggestions or feedback, please get in touch with us:46like to offer suggestions or feedback, please get in touch with us:
@@ -76,7 +48,7 @@
76* Ask a question through our web support interface, at 48* Ask a question through our web support interface, at
77 https://answers.launchpad.net/bzr/49 https://answers.launchpad.net/bzr/
7850
79* Report bugs at https://bugs.edge.launchpad.net/bzr/+filebug51* Report bugs at https://bugs.launchpad.net/bzr/+filebug
8052
81* Write to us at bazaar@lists.canonical.com 53* Write to us at bazaar@lists.canonical.com
82 You can join the list at <https://lists.ubuntu.com/mailman/listinfo/bazaar>.54 You can join the list at <https://lists.ubuntu.com/mailman/listinfo/bazaar>.
@@ -85,12 +57,8 @@
8557
86* Talk to us in irc://irc.ubuntu.com/bzr58* Talk to us in irc://irc.ubuntu.com/bzr
8759
88* And see http://bazaar-vcs.org/BzrSupport for more.60Our mission is to make a version control tool that developers LOVE to use
8961and that casual contributors feel confident with. Please let us know how
90If you would like to help us improve Bazaar by telling us about yourself and62we're going.
91what we could do better, please register and complete the online survey here:63
92http://www.surveymonkey.com/s.aspx?sm=L94RvLswhKdktrxiHWiX3g_3d_3d.
93Registration is completely optional.
94
95Enjoy,
96The Bazaar Team64The Bazaar Team
9765
=== modified file 'bzrlib/__init__.py'
--- bzrlib/__init__.py 2009-08-30 21:34:42 +0000
+++ bzrlib/__init__.py 2009-11-03 09:40:55 +0000
@@ -31,16 +31,10 @@
31 import bzrlib.lazy_regex31 import bzrlib.lazy_regex
32 bzrlib.lazy_regex.install_lazy_compile()32 bzrlib.lazy_regex.install_lazy_compile()
3333
34from bzrlib.osutils import get_user_encoding
35
3634
37IGNORE_FILENAME = ".bzrignore"35IGNORE_FILENAME = ".bzrignore"
3836
3937
40# XXX: Deprecated as of bzr-1.17 use osutils.get_user_encoding() directly
41user_encoding = get_user_encoding()
42
43
44__copyright__ = "Copyright 2005, 2006, 2007, 2008, 2009 Canonical Ltd."38__copyright__ = "Copyright 2005, 2006, 2007, 2008, 2009 Canonical Ltd."
4539
46# same format as sys.version_info: "A tuple containing the five components of40# same format as sys.version_info: "A tuple containing the five components of
@@ -50,10 +44,11 @@
50# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a44# Python version 2.0 is (2, 0, 0, 'final', 0)." Additionally we use a
51# releaselevel of 'dev' for unreleased under-development code.45# releaselevel of 'dev' for unreleased under-development code.
5246
53version_info = (2, 1, 0, 'dev', 0)47version_info = (2, 1, 0, 'dev', 3)
5448
55# API compatibility version: bzrlib is currently API compatible with 1.15.49# API compatibility version: bzrlib is currently API compatible with 1.15.
56api_minimum_version = (1, 17, 0)50api_minimum_version = (2, 1, 0)
51
5752
58def _format_version_tuple(version_info):53def _format_version_tuple(version_info):
59 """Turn a version number 2, 3 or 5-tuple into a short string.54 """Turn a version number 2, 3 or 5-tuple into a short string.
@@ -65,23 +60,29 @@
65 zero for final releases.60 zero for final releases.
6661
67 >>> print _format_version_tuple((1, 0, 0, 'final', 0))62 >>> print _format_version_tuple((1, 0, 0, 'final', 0))
68 1.063 1.0.0
69 >>> print _format_version_tuple((1, 2, 0, 'dev', 0))64 >>> print _format_version_tuple((1, 2, 0, 'dev', 0))
70 1.2dev65 1.2.0dev
66 >>> print bzrlib._format_version_tuple((1, 2, 0, 'dev', 1))
67 1.2.0dev1
71 >>> print _format_version_tuple((1, 1, 1, 'candidate', 2))68 >>> print _format_version_tuple((1, 1, 1, 'candidate', 2))
72 1.1.1rc269 1.1.1rc2
73 >>> print bzrlib._format_version_tuple((2, 1, 0, 'beta', 1))70 >>> print bzrlib._format_version_tuple((2, 1, 0, 'beta', 1))
74 2.1b171 2.1.0b1
75 >>> print _format_version_tuple((1, 4, 0))72 >>> print _format_version_tuple((1, 4, 0))
76 1.473 1.4.0
77 >>> print _format_version_tuple((1, 4))74 >>> print _format_version_tuple((1, 4))
78 1.475 1.4
76 >>> print bzrlib._format_version_tuple((2, 1, 0, 'final', 1))
77 Traceback (most recent call last):
78 ...
79 ValueError: version_info (2, 1, 0, 'final', 1) not valid
79 >>> print _format_version_tuple((1, 4, 0, 'wibble', 0))80 >>> print _format_version_tuple((1, 4, 0, 'wibble', 0))
80 Traceback (most recent call last):81 Traceback (most recent call last):
81 ...82 ...
82 ValueError: version_info (1, 4, 0, 'wibble', 0) not valid83 ValueError: version_info (1, 4, 0, 'wibble', 0) not valid
83 """84 """
84 if len(version_info) == 2 or version_info[2] == 0:85 if len(version_info) == 2:
85 main_version = '%d.%d' % version_info[:2]86 main_version = '%d.%d' % version_info[:2]
86 else:87 else:
87 main_version = '%d.%d.%d' % version_info[:3]88 main_version = '%d.%d.%d' % version_info[:3]
@@ -96,6 +97,8 @@
96 sub_string = ''97 sub_string = ''
97 elif release_type == 'dev' and sub == 0:98 elif release_type == 'dev' and sub == 0:
98 sub_string = 'dev'99 sub_string = 'dev'
100 elif release_type == 'dev':
101 sub_string = 'dev' + str(sub)
99 elif release_type in ('alpha', 'beta'):102 elif release_type in ('alpha', 'beta'):
100 sub_string = release_type[0] + str(sub)103 sub_string = release_type[0] + str(sub)
101 elif release_type == 'candidate':104 elif release_type == 'candidate':
@@ -103,7 +106,6 @@
103 else:106 else:
104 raise ValueError("version_info %r not valid" % (version_info,))107 raise ValueError("version_info %r not valid" % (version_info,))
105108
106 version_string = '%d.%d.%d.%s.%d' % tuple(version_info)
107 return main_version + sub_string109 return main_version + sub_string
108110
109111
110112
=== modified file 'bzrlib/_bencode_pyx.pyx'
--- bzrlib/_bencode_pyx.pyx 2009-06-05 01:48:32 +0000
+++ bzrlib/_bencode_pyx.pyx 2009-11-03 09:40:55 +0000
@@ -58,6 +58,13 @@
58 void D_UPDATE_TAIL(Decoder, int n)58 void D_UPDATE_TAIL(Decoder, int n)
59 void E_UPDATE_TAIL(Encoder, int n)59 void E_UPDATE_TAIL(Encoder, int n)
6060
61# To maintain compatibility with older versions of pyrex, we have to use the
62# relative import here, rather than 'bzrlib._static_tuple_c'
63from _static_tuple_c cimport StaticTuple, StaticTuple_CheckExact, \
64 import_static_tuple_c
65
66import_static_tuple_c()
67
6168
62cdef class Decoder:69cdef class Decoder:
63 """Bencode decoder"""70 """Bencode decoder"""
@@ -371,7 +378,8 @@
371 self._encode_int(x)378 self._encode_int(x)
372 elif PyLong_CheckExact(x):379 elif PyLong_CheckExact(x):
373 self._encode_long(x)380 self._encode_long(x)
374 elif PyList_CheckExact(x) or PyTuple_CheckExact(x):381 elif (PyList_CheckExact(x) or PyTuple_CheckExact(x)
382 or StaticTuple_CheckExact(x)):
375 self._encode_list(x)383 self._encode_list(x)
376 elif PyDict_CheckExact(x):384 elif PyDict_CheckExact(x):
377 self._encode_dict(x)385 self._encode_dict(x)
378386
=== modified file 'bzrlib/_btree_serializer_pyx.pyx'
--- bzrlib/_btree_serializer_pyx.pyx 2009-06-22 12:52:39 +0000
+++ bzrlib/_btree_serializer_pyx.pyx 2009-11-03 09:40:55 +0000
@@ -1,4 +1,4 @@
1# Copyright (C) 2008 Canonical Ltd1# Copyright (C) 2008, 2009 Canonical Ltd
2#2#
3# This program is free software; you can redistribute it and/or modify3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by4# it under the terms of the GNU General Public License as published by
@@ -38,11 +38,16 @@
38 Py_ssize_t PyString_Size(object p)38 Py_ssize_t PyString_Size(object p)
39 Py_ssize_t PyString_GET_SIZE_ptr "PyString_GET_SIZE" (PyObject *)39 Py_ssize_t PyString_GET_SIZE_ptr "PyString_GET_SIZE" (PyObject *)
40 char * PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *)40 char * PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *)
41 char * PyString_AS_STRING(object)
42 Py_ssize_t PyString_GET_SIZE(object)
41 int PyString_AsStringAndSize_ptr(PyObject *, char **buf, Py_ssize_t *len)43 int PyString_AsStringAndSize_ptr(PyObject *, char **buf, Py_ssize_t *len)
42 void PyString_InternInPlace(PyObject **)44 void PyString_InternInPlace(PyObject **)
43 int PyTuple_CheckExact(object t)45 int PyTuple_CheckExact(object t)
46 object PyTuple_New(Py_ssize_t n_entries)
47 void PyTuple_SET_ITEM(object, Py_ssize_t offset, object) # steals the ref
44 Py_ssize_t PyTuple_GET_SIZE(object t)48 Py_ssize_t PyTuple_GET_SIZE(object t)
45 PyObject *PyTuple_GET_ITEM_ptr_object "PyTuple_GET_ITEM" (object tpl, int index)49 PyObject *PyTuple_GET_ITEM_ptr_object "PyTuple_GET_ITEM" (object tpl, int index)
50 void Py_INCREF(object)
46 void Py_DECREF_ptr "Py_DECREF" (PyObject *)51 void Py_DECREF_ptr "Py_DECREF" (PyObject *)
4752
48cdef extern from "string.h":53cdef extern from "string.h":
@@ -52,6 +57,12 @@
52 # void *memrchr(void *s, int c, size_t n)57 # void *memrchr(void *s, int c, size_t n)
53 int strncmp(char *s1, char *s2, size_t n)58 int strncmp(char *s1, char *s2, size_t n)
5459
60# It seems we need to import the definitions so that the pyrex compiler has
61# local names to access them.
62from _static_tuple_c cimport StaticTuple, \
63 import_static_tuple_c, StaticTuple_New, \
64 StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact
65
5566
56# TODO: Find some way to import this from _dirstate_helpers67# TODO: Find some way to import this from _dirstate_helpers
57cdef void* _my_memrchr(void *s, int c, size_t n):68cdef void* _my_memrchr(void *s, int c, size_t n):
@@ -68,6 +79,7 @@
68 pos = pos - 179 pos = pos - 1
69 return NULL80 return NULL
7081
82
71# TODO: Import this from _dirstate_helpers when it is merged83# TODO: Import this from _dirstate_helpers when it is merged
72cdef object safe_string_from_size(char *s, Py_ssize_t size):84cdef object safe_string_from_size(char *s, Py_ssize_t size):
73 if size < 0:85 if size < 0:
@@ -91,6 +103,10 @@
91 Py_DECREF_ptr(py_str)103 Py_DECREF_ptr(py_str)
92 return result104 return result
93105
106from bzrlib import _static_tuple_c
107# This sets up the StaticTuple C_API functionality
108import_static_tuple_c()
109
94110
95cdef class BTreeLeafParser:111cdef class BTreeLeafParser:
96 """Parse the leaf nodes of a BTree index.112 """Parse the leaf nodes of a BTree index.
@@ -130,6 +146,7 @@
130 self._cur_str = NULL146 self._cur_str = NULL
131 self._end_str = NULL147 self._end_str = NULL
132 self._header_found = 0148 self._header_found = 0
149 # keys are tuples
133150
134 cdef extract_key(self, char * last):151 cdef extract_key(self, char * last):
135 """Extract a key.152 """Extract a key.
@@ -139,15 +156,14 @@
139 """156 """
140 cdef char *temp_ptr157 cdef char *temp_ptr
141 cdef int loop_counter158 cdef int loop_counter
142 # keys are tuples159 cdef StaticTuple key
143 loop_counter = 0160
144 key_segments = []161 key = StaticTuple_New(self.key_length)
145 while loop_counter < self.key_length:162 for loop_counter from 0 <= loop_counter < self.key_length:
146 loop_counter = loop_counter + 1
147 # grab a key segment163 # grab a key segment
148 temp_ptr = <char*>memchr(self._start, c'\0', last - self._start)164 temp_ptr = <char*>memchr(self._start, c'\0', last - self._start)
149 if temp_ptr == NULL:165 if temp_ptr == NULL:
150 if loop_counter == self.key_length:166 if loop_counter + 1 == self.key_length:
151 # capture to last167 # capture to last
152 temp_ptr = last168 temp_ptr = last
153 else:169 else:
@@ -157,15 +173,20 @@
157 last - self._start)))173 last - self._start)))
158 raise AssertionError(failure_string)174 raise AssertionError(failure_string)
159 # capture the key string175 # capture the key string
160 # TODO: Consider using PyIntern_FromString, the only caveat is that176 if (self.key_length == 1
161 # it assumes a NULL-terminated string, so we have to check if177 and (temp_ptr - self._start) == 45
162 # temp_ptr[0] == c'\0' or some other char.178 and strncmp(self._start, 'sha1:', 5) == 0):
163 key_element = safe_interned_string_from_size(self._start,179 key_element = safe_string_from_size(self._start,
180 temp_ptr - self._start)
181 else:
182 key_element = safe_interned_string_from_size(self._start,
164 temp_ptr - self._start)183 temp_ptr - self._start)
165 # advance our pointer184 # advance our pointer
166 self._start = temp_ptr + 1185 self._start = temp_ptr + 1
167 PyList_Append(key_segments, key_element)186 Py_INCREF(key_element)
168 return tuple(key_segments)187 StaticTuple_SET_ITEM(key, loop_counter, key_element)
188 key = StaticTuple_Intern(key)
189 return key
169190
170 cdef int process_line(self) except -1:191 cdef int process_line(self) except -1:
171 """Process a line in the bytes."""192 """Process a line in the bytes."""
@@ -174,6 +195,7 @@
174 cdef char *ref_ptr195 cdef char *ref_ptr
175 cdef char *next_start196 cdef char *next_start
176 cdef int loop_counter197 cdef int loop_counter
198 cdef Py_ssize_t str_len
177199
178 self._start = self._cur_str200 self._start = self._cur_str
179 # Find the next newline201 # Find the next newline
@@ -186,14 +208,13 @@
186 # And the next string is right after it208 # And the next string is right after it
187 self._cur_str = last + 1209 self._cur_str = last + 1
188 # The last character is right before the '\n'210 # The last character is right before the '\n'
189 last = last
190211
191 if last == self._start:212 if last == self._start:
192 # parsed it all.213 # parsed it all.
193 return 0214 return 0
194 if last < self._start:215 if last < self._start:
195 # Unexpected error condition - fail216 # Unexpected error condition - fail
196 return -1217 raise AssertionError("last < self._start")
197 if 0 == self._header_found:218 if 0 == self._header_found:
198 # The first line in a leaf node is the header "type=leaf\n"219 # The first line in a leaf node is the header "type=leaf\n"
199 if strncmp("type=leaf", self._start, last - self._start) == 0:220 if strncmp("type=leaf", self._start, last - self._start) == 0:
@@ -202,36 +223,48 @@
202 else:223 else:
203 raise AssertionError('Node did not start with "type=leaf": %r'224 raise AssertionError('Node did not start with "type=leaf": %r'
204 % (safe_string_from_size(self._start, last - self._start)))225 % (safe_string_from_size(self._start, last - self._start)))
205 return -1
206226
207 key = self.extract_key(last)227 key = self.extract_key(last)
208 # find the value area228 # find the value area
209 temp_ptr = <char*>_my_memrchr(self._start, c'\0', last - self._start)229 temp_ptr = <char*>_my_memrchr(self._start, c'\0', last - self._start)
210 if temp_ptr == NULL:230 if temp_ptr == NULL:
211 # Invalid line231 # Invalid line
212 return -1232 raise AssertionError("Failed to find the value area")
213 else:233 else:
214 # capture the value string234 # Because of how conversions were done, we ended up with *lots* of
215 value = safe_string_from_size(temp_ptr + 1, last - temp_ptr - 1)235 # values that are identical. These are all of the 0-length nodes
236 # that are referred to by the TREE_ROOT (and likely some other
237 # directory nodes.) For example, bzr has 25k references to
238 # something like '12607215 328306 0 0', which ends up consuming 1MB
239 # of memory, just for those strings.
240 str_len = last - temp_ptr - 1
241 if (str_len > 4
242 and strncmp(" 0 0", last - 4, 4) == 0):
243 # This drops peak mem for bzr.dev from 87.4MB => 86.2MB
244 # For Launchpad 236MB => 232MB
245 value = safe_interned_string_from_size(temp_ptr + 1, str_len)
246 else:
247 value = safe_string_from_size(temp_ptr + 1, str_len)
216 # shrink the references end point248 # shrink the references end point
217 last = temp_ptr249 last = temp_ptr
250
218 if self.ref_list_length:251 if self.ref_list_length:
219 ref_lists = []252 ref_lists = StaticTuple_New(self.ref_list_length)
220 loop_counter = 0253 loop_counter = 0
221 while loop_counter < self.ref_list_length:254 while loop_counter < self.ref_list_length:
222 ref_list = []255 ref_list = []
223 # extract a reference list256 # extract a reference list
224 loop_counter = loop_counter + 1257 loop_counter = loop_counter + 1
225 if last < self._start:258 if last < self._start:
226 return -1259 raise AssertionError("last < self._start")
227 # find the next reference list end point:260 # find the next reference list end point:
228 temp_ptr = <char*>memchr(self._start, c'\t', last - self._start)261 temp_ptr = <char*>memchr(self._start, c'\t', last - self._start)
229 if temp_ptr == NULL:262 if temp_ptr == NULL:
230 # Only valid for the last list263 # Only valid for the last list
231 if loop_counter != self.ref_list_length:264 if loop_counter != self.ref_list_length:
232 # Invalid line265 # Invalid line
233 return -1266 raise AssertionError(
234 raise AssertionError("invalid key")267 "invalid key, loop_counter != self.ref_list_length")
235 else:268 else:
236 # scan to the end of the ref list area269 # scan to the end of the ref list area
237 ref_ptr = last270 ref_ptr = last
@@ -248,18 +281,20 @@
248 if temp_ptr == NULL:281 if temp_ptr == NULL:
249 # key runs to the end282 # key runs to the end
250 temp_ptr = ref_ptr283 temp_ptr = ref_ptr
284
251 PyList_Append(ref_list, self.extract_key(temp_ptr))285 PyList_Append(ref_list, self.extract_key(temp_ptr))
252 PyList_Append(ref_lists, tuple(ref_list))286 ref_list = StaticTuple_Intern(StaticTuple(*ref_list))
287 Py_INCREF(ref_list)
288 StaticTuple_SET_ITEM(ref_lists, loop_counter - 1, ref_list)
253 # prepare for the next reference list289 # prepare for the next reference list
254 self._start = next_start290 self._start = next_start
255 ref_lists = tuple(ref_lists)291 node_value = StaticTuple(value, ref_lists)
256 node_value = (value, ref_lists)
257 else:292 else:
258 if last != self._start:293 if last != self._start:
259 # unexpected reference data present294 # unexpected reference data present
260 return -1295 raise AssertionError("unexpected reference data present")
261 node_value = (value, ())296 node_value = StaticTuple(value, StaticTuple())
262 PyList_Append(self.keys, (key, node_value))297 PyList_Append(self.keys, StaticTuple(key, node_value))
263 return 0298 return 0
264299
265 def parse(self):300 def parse(self):
@@ -294,7 +329,6 @@
294 cdef Py_ssize_t flat_len329 cdef Py_ssize_t flat_len
295 cdef Py_ssize_t key_len330 cdef Py_ssize_t key_len
296 cdef Py_ssize_t node_len331 cdef Py_ssize_t node_len
297 cdef PyObject * val
298 cdef char * value332 cdef char * value
299 cdef Py_ssize_t value_len333 cdef Py_ssize_t value_len
300 cdef char * out334 cdef char * out
@@ -303,13 +337,12 @@
303 cdef int first_ref_list337 cdef int first_ref_list
304 cdef int first_reference338 cdef int first_reference
305 cdef int i339 cdef int i
306 cdef PyObject *ref_bit
307 cdef Py_ssize_t ref_bit_len340 cdef Py_ssize_t ref_bit_len
308341
309 if not PyTuple_CheckExact(node):342 if not PyTuple_CheckExact(node) and not StaticTuple_CheckExact(node):
310 raise TypeError('We expected a tuple() for node not: %s'343 raise TypeError('We expected a tuple() or StaticTuple() for node not: %s'
311 % type(node))344 % type(node))
312 node_len = PyTuple_GET_SIZE(node)345 node_len = len(node)
313 have_reference_lists = reference_lists346 have_reference_lists = reference_lists
314 if have_reference_lists:347 if have_reference_lists:
315 if node_len != 4:348 if node_len != 4:
@@ -318,8 +351,17 @@
318 elif node_len < 3:351 elif node_len < 3:
319 raise ValueError('Without ref_lists, we need at least 3 entries not: %s'352 raise ValueError('Without ref_lists, we need at least 3 entries not: %s'
320 % len(node))353 % len(node))
321 # I don't expect that we can do faster than string.join()354 # TODO: We can probably do better than string.join(), namely
322 string_key = '\0'.join(<object>PyTuple_GET_ITEM_ptr_object(node, 1))355 # when key has only 1 item, we can just grab that string
356 # And when there are 2 items, we could do a single malloc + len() + 1
357 # also, doing .join() requires a PyObject_GetAttrString call, which
358 # we could also avoid.
359 # TODO: Note that pyrex 0.9.6 generates fairly crummy code here, using the
360 # python object interface, versus 0.9.8+ which uses a helper that
361 # checks if this supports the sequence interface.
362 # We *could* do more work on our own, and grab the actual items
363 # lists. For now, just ask people to use a better compiler. :)
364 string_key = '\0'.join(node[1])
323365
324 # TODO: instead of using string joins, precompute the final string length,366 # TODO: instead of using string joins, precompute the final string length,
325 # and then malloc a single string and copy everything in.367 # and then malloc a single string and copy everything in.
@@ -336,7 +378,7 @@
336 refs_len = 0378 refs_len = 0
337 if have_reference_lists:379 if have_reference_lists:
338 # Figure out how many bytes it will take to store the references380 # Figure out how many bytes it will take to store the references
339 ref_lists = <object>PyTuple_GET_ITEM_ptr_object(node, 3)381 ref_lists = node[3]
340 next_len = len(ref_lists) # TODO: use a Py function382 next_len = len(ref_lists) # TODO: use a Py function
341 if next_len > 0:383 if next_len > 0:
342 # If there are no nodes, we don't need to do any work384 # If there are no nodes, we don't need to do any work
@@ -350,31 +392,31 @@
350 # references392 # references
351 refs_len = refs_len + (next_len - 1)393 refs_len = refs_len + (next_len - 1)
352 for reference in ref_list:394 for reference in ref_list:
353 if not PyTuple_CheckExact(reference):395 if (not PyTuple_CheckExact(reference)
396 and not StaticTuple_CheckExact(reference)):
354 raise TypeError(397 raise TypeError(
355 'We expect references to be tuples not: %s'398 'We expect references to be tuples not: %s'
356 % type(reference))399 % type(reference))
357 next_len = PyTuple_GET_SIZE(reference)400 next_len = len(reference)
358 if next_len > 0:401 if next_len > 0:
359 # We will need (len - 1) '\x00' characters to402 # We will need (len - 1) '\x00' characters to
360 # separate the reference key403 # separate the reference key
361 refs_len = refs_len + (next_len - 1)404 refs_len = refs_len + (next_len - 1)
362 for i from 0 <= i < next_len:405 for ref_bit in reference:
363 ref_bit = PyTuple_GET_ITEM_ptr_object(reference, i)406 if not PyString_CheckExact(ref_bit):
364 if not PyString_CheckExact_ptr(ref_bit):
365 raise TypeError('We expect reference bits'407 raise TypeError('We expect reference bits'
366 ' to be strings not: %s'408 ' to be strings not: %s'
367 % type(<object>ref_bit))409 % type(<object>ref_bit))
368 refs_len = refs_len + PyString_GET_SIZE_ptr(ref_bit)410 refs_len = refs_len + PyString_GET_SIZE(ref_bit)
369411
370 # So we have the (key NULL refs NULL value LF)412 # So we have the (key NULL refs NULL value LF)
371 key_len = PyString_Size(string_key)413 key_len = PyString_Size(string_key)
372 val = PyTuple_GET_ITEM_ptr_object(node, 2)414 val = node[2]
373 if not PyString_CheckExact_ptr(val):415 if not PyString_CheckExact(val):
374 raise TypeError('Expected a plain str for value not: %s'416 raise TypeError('Expected a plain str for value not: %s'
375 % type(<object>val))417 % type(val))
376 value = PyString_AS_STRING_ptr(val)418 value = PyString_AS_STRING(val)
377 value_len = PyString_GET_SIZE_ptr(val)419 value_len = PyString_GET_SIZE(val)
378 flat_len = (key_len + 1 + refs_len + 1 + value_len + 1)420 flat_len = (key_len + 1 + refs_len + 1 + value_len + 1)
379 line = PyString_FromStringAndSize(NULL, flat_len)421 line = PyString_FromStringAndSize(NULL, flat_len)
380 # Get a pointer to the new buffer422 # Get a pointer to the new buffer
@@ -396,14 +438,14 @@
396 out[0] = c'\r'438 out[0] = c'\r'
397 out = out + 1439 out = out + 1
398 first_reference = 0440 first_reference = 0
399 next_len = PyTuple_GET_SIZE(reference)441 next_len = len(reference)
400 for i from 0 <= i < next_len:442 for i from 0 <= i < next_len:
401 if i != 0:443 if i != 0:
402 out[0] = c'\x00'444 out[0] = c'\x00'
403 out = out + 1445 out = out + 1
404 ref_bit = PyTuple_GET_ITEM_ptr_object(reference, i)446 ref_bit = reference[i]
405 ref_bit_len = PyString_GET_SIZE_ptr(ref_bit)447 ref_bit_len = PyString_GET_SIZE(ref_bit)
406 memcpy(out, PyString_AS_STRING_ptr(ref_bit), ref_bit_len)448 memcpy(out, PyString_AS_STRING(ref_bit), ref_bit_len)
407 out = out + ref_bit_len449 out = out + ref_bit_len
408 out[0] = c'\0'450 out[0] = c'\0'
409 out = out + 1451 out = out + 1
410452
=== modified file 'bzrlib/_chk_map_py.py'
--- bzrlib/_chk_map_py.py 2009-04-09 20:23:07 +0000
+++ bzrlib/_chk_map_py.py 2009-11-03 09:40:55 +0000
@@ -19,6 +19,8 @@
19import zlib19import zlib
20import struct20import struct
2121
22from bzrlib.static_tuple import StaticTuple
23
22_LeafNode = None24_LeafNode = None
23_InternalNode = None25_InternalNode = None
24_unknown = None26_unknown = None
@@ -93,7 +95,7 @@
93 value_lines = lines[pos:pos+num_value_lines]95 value_lines = lines[pos:pos+num_value_lines]
94 pos += num_value_lines96 pos += num_value_lines
95 value = '\n'.join(value_lines)97 value = '\n'.join(value_lines)
96 items[tuple(elements[:-1])] = value98 items[StaticTuple.from_sequence(elements[:-1])] = value
97 if len(items) != length:99 if len(items) != length:
98 raise AssertionError("item count (%d) mismatch for key %s,"100 raise AssertionError("item count (%d) mismatch for key %s,"
99 " bytes %r" % (length, key, bytes))101 " bytes %r" % (length, key, bytes))
@@ -141,7 +143,7 @@
141 for line in lines[5:]:143 for line in lines[5:]:
142 line = common_prefix + line144 line = common_prefix + line
143 prefix, flat_key = line.rsplit('\x00', 1)145 prefix, flat_key = line.rsplit('\x00', 1)
144 items[prefix] = (flat_key,)146 items[prefix] = StaticTuple(flat_key,)
145 if len(items) == 0:147 if len(items) == 0:
146 raise AssertionError("We didn't find any item for %s" % key)148 raise AssertionError("We didn't find any item for %s" % key)
147 result._items = items149 result._items = items
@@ -155,4 +157,3 @@
155 result._node_width = len(prefix)157 result._node_width = len(prefix)
156 result._search_prefix = common_prefix158 result._search_prefix = common_prefix
157 return result159 return result
158
159160
=== modified file 'bzrlib/_chk_map_pyx.pyx'
--- bzrlib/_chk_map_pyx.pyx 2009-06-22 12:52:39 +0000
+++ bzrlib/_chk_map_pyx.pyx 2009-11-03 09:40:54 +0000
@@ -29,9 +29,8 @@
2929
30cdef extern from "Python.h":30cdef extern from "Python.h":
31 ctypedef int Py_ssize_t # Required for older pyrex versions31 ctypedef int Py_ssize_t # Required for older pyrex versions
32 struct _PyObject:32 ctypedef struct PyObject:
33 pass33 pass
34 ctypedef _PyObject PyObject
35 int PyTuple_CheckExact(object p)34 int PyTuple_CheckExact(object p)
36 Py_ssize_t PyTuple_GET_SIZE(object t)35 Py_ssize_t PyTuple_GET_SIZE(object t)
37 int PyString_CheckExact(object)36 int PyString_CheckExact(object)
@@ -52,6 +51,18 @@
52 char *PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *s)51 char *PyString_AS_STRING_ptr "PyString_AS_STRING" (PyObject *s)
53 object PyString_FromStringAndSize(char*, Py_ssize_t)52 object PyString_FromStringAndSize(char*, Py_ssize_t)
5453
54# cimport all of the definitions we will need to access
55from _static_tuple_c cimport StaticTuple,\
56 import_static_tuple_c, StaticTuple_New, \
57 StaticTuple_Intern, StaticTuple_SET_ITEM, StaticTuple_CheckExact
58
59cdef extern from "_static_tuple_c.h":
60 # Defined explicitly rather than cimport-ing. Trying to use cimport, the
61 # type for PyObject is a different class that happens to have the same
62 # name...
63 PyObject * StaticTuple_GET_ITEM_ptr "StaticTuple_GET_ITEM" (StaticTuple,
64 Py_ssize_t)
65
55cdef extern from "zlib.h":66cdef extern from "zlib.h":
56 ctypedef unsigned long uLong67 ctypedef unsigned long uLong
57 ctypedef unsigned int uInt68 ctypedef unsigned int uInt
@@ -60,8 +71,14 @@
60 uLong crc32(uLong crc, Bytef *buf, uInt len)71 uLong crc32(uLong crc, Bytef *buf, uInt len)
6172
6273
74# Set up the StaticTuple C_API functionality
75import_static_tuple_c()
76
77cdef object _LeafNode
63_LeafNode = None78_LeafNode = None
79cdef object _InternalNode
64_InternalNode = None80_InternalNode = None
81cdef object _unknown
65_unknown = None82_unknown = None
6683
67# We shouldn't just copy this from _dirstate_helpers_pyx84# We shouldn't just copy this from _dirstate_helpers_pyx
@@ -91,9 +108,9 @@
91 cdef char *c_out108 cdef char *c_out
92 cdef PyObject *bit109 cdef PyObject *bit
93110
94 if not PyTuple_CheckExact(key):111 if not StaticTuple_CheckExact(key):
95 raise TypeError('key %r is not a tuple' % (key,))112 raise TypeError('key %r is not a StaticTuple' % (key,))
96 num_bits = PyTuple_GET_SIZE(key)113 num_bits = len(key)
97 # 4 bytes per crc32, and another 1 byte between bits114 # 4 bytes per crc32, and another 1 byte between bits
98 num_out_bytes = (9 * num_bits) - 1115 num_out_bytes = (9 * num_bits) - 1
99 out = PyString_FromStringAndSize(NULL, num_out_bytes)116 out = PyString_FromStringAndSize(NULL, num_out_bytes)
@@ -105,7 +122,7 @@
105 # We use the _ptr variant, because GET_ITEM returns a borrowed122 # We use the _ptr variant, because GET_ITEM returns a borrowed
106 # reference, and Pyrex assumes that returned 'object' are a new123 # reference, and Pyrex assumes that returned 'object' are a new
107 # reference124 # reference
108 bit = PyTuple_GET_ITEM_ptr(key, i)125 bit = StaticTuple_GET_ITEM_ptr(key, i)
109 if not PyString_CheckExact_ptr(bit):126 if not PyString_CheckExact_ptr(bit):
110 raise TypeError('Bit %d of %r is not a string' % (i, key))127 raise TypeError('Bit %d of %r is not a string' % (i, key))
111 c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)128 c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
@@ -129,9 +146,9 @@
129 cdef char *c_out146 cdef char *c_out
130 cdef PyObject *bit147 cdef PyObject *bit
131148
132 if not PyTuple_CheckExact(key):149 if not StaticTuple_CheckExact(key):
133 raise TypeError('key %r is not a tuple' % (key,))150 raise TypeError('key %r is not a StaticTuple' % (key,))
134 num_bits = PyTuple_GET_SIZE(key)151 num_bits = len(key)
135 # 4 bytes per crc32, and another 1 byte between bits152 # 4 bytes per crc32, and another 1 byte between bits
136 num_out_bytes = (5 * num_bits) - 1153 num_out_bytes = (5 * num_bits) - 1
137 out = PyString_FromStringAndSize(NULL, num_out_bytes)154 out = PyString_FromStringAndSize(NULL, num_out_bytes)
@@ -140,10 +157,10 @@
140 if i > 0:157 if i > 0:
141 c_out[0] = c'\x00'158 c_out[0] = c'\x00'
142 c_out = c_out + 1159 c_out = c_out + 1
143 bit = PyTuple_GET_ITEM_ptr(key, i)160 bit = StaticTuple_GET_ITEM_ptr(key, i)
144 if not PyString_CheckExact_ptr(bit):161 if not PyString_CheckExact_ptr(bit):
145 raise TypeError('Bit %d of %r is not a string: %r' % (i, key,162 raise TypeError('Bit %d of %r is not a string: %r'
146 <object>bit))163 % (i, key, <object>bit))
147 c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)164 c_bit = <Bytef *>PyString_AS_STRING_ptr(bit)
148 c_len = PyString_GET_SIZE_ptr(bit)165 c_len = PyString_GET_SIZE_ptr(bit)
149 crc_val = crc32(0, c_bit, c_len)166 crc_val = crc32(0, c_bit, c_len)
@@ -195,6 +212,7 @@
195 cdef char *prefix, *value_start, *prefix_tail212 cdef char *prefix, *value_start, *prefix_tail
196 cdef char *next_null, *last_null, *line_start213 cdef char *next_null, *last_null, *line_start
197 cdef char *c_entry, *entry_start214 cdef char *c_entry, *entry_start
215 cdef StaticTuple entry_bits
198216
199 if _LeafNode is None:217 if _LeafNode is None:
200 from bzrlib import chk_map218 from bzrlib import chk_map
@@ -265,12 +283,14 @@
265 if next_line == NULL:283 if next_line == NULL:
266 raise ValueError('missing trailing newline')284 raise ValueError('missing trailing newline')
267 cur = next_line + 1285 cur = next_line + 1
268 entry_bits = PyTuple_New(width)286 entry_bits = StaticTuple_New(width)
269 for i from 0 <= i < num_prefix_bits:287 for i from 0 <= i < num_prefix_bits:
288 # TODO: Use PyList_GetItem, or turn prefix_bits into a
289 # tuple/StaticTuple
270 entry = prefix_bits[i]290 entry = prefix_bits[i]
271 # SET_ITEM 'steals' a reference291 # SET_ITEM 'steals' a reference
272 Py_INCREF(entry)292 Py_INCREF(entry)
273 PyTuple_SET_ITEM(entry_bits, i, entry)293 StaticTuple_SET_ITEM(entry_bits, i, entry)
274 value = PyString_FromStringAndSize(value_start, next_line - value_start)294 value = PyString_FromStringAndSize(value_start, next_line - value_start)
275 # The next entry bit needs the 'tail' from the prefix, and first part295 # The next entry bit needs the 'tail' from the prefix, and first part
276 # of the line296 # of the line
@@ -288,7 +308,7 @@
288 memcpy(c_entry + prefix_tail_len, line_start, next_null - line_start)308 memcpy(c_entry + prefix_tail_len, line_start, next_null - line_start)
289 Py_INCREF(entry)309 Py_INCREF(entry)
290 i = num_prefix_bits310 i = num_prefix_bits
291 PyTuple_SET_ITEM(entry_bits, i, entry)311 StaticTuple_SET_ITEM(entry_bits, i, entry)
292 while next_null != last_null: # We have remaining bits312 while next_null != last_null: # We have remaining bits
293 i = i + 1313 i = i + 1
294 if i > width:314 if i > width:
@@ -301,11 +321,12 @@
301 entry = PyString_FromStringAndSize(entry_start,321 entry = PyString_FromStringAndSize(entry_start,
302 next_null - entry_start)322 next_null - entry_start)
303 Py_INCREF(entry)323 Py_INCREF(entry)
304 PyTuple_SET_ITEM(entry_bits, i, entry)324 StaticTuple_SET_ITEM(entry_bits, i, entry)
305 if len(entry_bits) != width:325 if len(entry_bits) != width:
306 raise AssertionError(326 raise AssertionError(
307 'Incorrect number of elements (%d vs %d)'327 'Incorrect number of elements (%d vs %d)'
308 % (len(entry_bits)+1, width + 1))328 % (len(entry_bits)+1, width + 1))
329 entry_bits = StaticTuple_Intern(entry_bits)
309 PyDict_SetItem(items, entry_bits, value)330 PyDict_SetItem(items, entry_bits, value)
310 if len(items) != length:331 if len(items) != length:
311 raise ValueError("item count (%d) mismatch for key %s,"332 raise ValueError("item count (%d) mismatch for key %s,"
@@ -343,6 +364,8 @@
343 _unknown = chk_map._unknown364 _unknown = chk_map._unknown
344 result = _InternalNode(search_key_func=search_key_func)365 result = _InternalNode(search_key_func=search_key_func)
345366
367 if not StaticTuple_CheckExact(key):
368 raise TypeError('key %r is not a StaticTuple' % (key,))
346 if not PyString_CheckExact(bytes):369 if not PyString_CheckExact(bytes):
347 raise TypeError('bytes must be a plain string not %s' % (type(bytes),))370 raise TypeError('bytes must be a plain string not %s' % (type(bytes),))
348371
@@ -384,7 +407,8 @@
384 memcpy(c_item_prefix + prefix_length, cur, next_null - cur)407 memcpy(c_item_prefix + prefix_length, cur, next_null - cur)
385 flat_key = PyString_FromStringAndSize(next_null + 1,408 flat_key = PyString_FromStringAndSize(next_null + 1,
386 next_line - next_null - 1)409 next_line - next_null - 1)
387 PyDict_SetItem(items, item_prefix, (flat_key,))410 flat_key = StaticTuple(flat_key).intern()
411 PyDict_SetItem(items, item_prefix, flat_key)
388 cur = next_line + 1412 cur = next_line + 1
389 assert len(items) > 0413 assert len(items) > 0
390 result._items = items414 result._items = items
@@ -398,4 +422,3 @@
398 result._node_width = len(item_prefix)422 result._node_width = len(item_prefix)
399 result._search_prefix = PyString_FromStringAndSize(prefix, prefix_length)423 result._search_prefix = PyString_FromStringAndSize(prefix, prefix_length)
400 return result424 return result
401
402425
=== modified file 'bzrlib/_dirstate_helpers_pyx.pyx'
--- bzrlib/_dirstate_helpers_pyx.pyx 2009-08-28 05:00:33 +0000
+++ bzrlib/_dirstate_helpers_pyx.pyx 2009-11-03 09:40:54 +0000
@@ -1202,7 +1202,9 @@
1202 content_change = 01202 content_change = 0
1203 target_exec = False1203 target_exec = False
1204 else:1204 else:
1205 raise Exception, "unknown kind %s" % path_info[2]1205 if path is None:
1206 path = self.pathjoin(old_dirname, old_basename)
1207 raise errors.BadFileKindError(path, path_info[2])
1206 if source_minikind == c'd':1208 if source_minikind == c'd':
1207 if path is None:1209 if path is None:
1208 old_path = path = self.pathjoin(old_dirname, old_basename)1210 old_path = path = self.pathjoin(old_dirname, old_basename)
12091211
=== added file 'bzrlib/_export_c_api.h'
--- bzrlib/_export_c_api.h 1970-01-01 00:00:00 +0000
+++ bzrlib/_export_c_api.h 2009-11-03 09:40:54 +0000
@@ -0,0 +1,104 @@
1/* Copyright (C) 2009 Canonical Ltd
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18
19/* This file contains helper functions for exporting a C API for a CPython
20 * extension module.
21 */
22
23#ifndef _EXPORT_C_API_H_
24#define _EXPORT_C_API_H_
25
26static const char *_C_API_NAME = "_C_API";
27
28/**
29 * Add a C function to the modules _C_API
30 * This wraps the function in a PyCObject, and inserts that into a dict.
31 * The key of the dict is the function name, and the description is the
32 * signature of the function.
33 * This is generally called during a modules init_MODULE function.
34 *
35 * @param module A Python module (the one being initialized)
36 * @param funcname The name of the function being exported
37 * @param func A pointer to the function
38 * @param signature The C signature of the function
39 * @return 0 if everything is successful, -1 if there is a problem. An
40 * exception should also be set
41 */
42static int
43_export_function(PyObject *module, char *funcname, void *func, char *signature)
44{
45 PyObject *d = NULL;
46 PyObject *c_obj = NULL;
47
48 /* (char *) is because python2.4 declares this api as 'char *' rather than
49 * const char* which it really is.
50 */
51 d = PyObject_GetAttrString(module, (char *)_C_API_NAME);
52 if (!d) {
53 PyErr_Clear();
54 d = PyDict_New();
55 if (!d)
56 goto bad;
57 Py_INCREF(d);
58 if (PyModule_AddObject(module, (char *)_C_API_NAME, d) < 0)
59 goto bad;
60 }
61 c_obj = PyCObject_FromVoidPtrAndDesc(func, signature, 0);
62 if (!c_obj)
63 goto bad;
64 if (PyDict_SetItemString(d, funcname, c_obj) < 0)
65 goto bad;
66 Py_DECREF(d);
67 return 0;
68bad:
69 Py_XDECREF(c_obj);
70 Py_XDECREF(d);
71 return -1;
72}
73
74/* Note:
75 * It feels like more could be done here. Specifically, if you look at
76 * _static_tuple_c.h you can see some boilerplate where we have:
77 * #ifdef STATIC_TUPLE_MODULE // are we exporting or importing
78 * static RETVAL FUNCNAME PROTO;
79 * #else
80 * static RETVAL (*FUNCNAME) PROTO;
81 * #endif
82 *
83 * And then in _static_tuple_c.c we have
84 * int setup_c_api()
85 * {
86 * _export_function(module, #FUNCNAME, FUNCNAME, #PROTO);
87 * }
88 *
89 * And then in _static_tuple_c.h import_##MODULE
90 * struct function_definition functions[] = {
91 * {#FUNCNAME, (void **)&FUNCNAME, #RETVAL #PROTO},
92 * ...
93 * {NULL}};
94 *
95 * And some similar stuff for types. However, this would mean that we would
96 * need a way for the C preprocessor to build up a list of definitions to be
97 * generated, and then expand that list at the appropriate time.
98 * I would guess there would be a way to do this, but probably not without a
99 * lot of magic, and the end result probably wouldn't be very pretty to
100 * maintain. Perhaps python's dynamic nature has left me jaded about writing
101 * boilerplate....
102 */
103
104#endif // _EXPORT_C_API_H_
0105
=== added file 'bzrlib/_import_c_api.h'
--- bzrlib/_import_c_api.h 1970-01-01 00:00:00 +0000
+++ bzrlib/_import_c_api.h 2009-11-03 09:40:54 +0000
@@ -0,0 +1,189 @@
1/* Copyright (C) 2009 Canonical Ltd
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18#ifndef _IMPORT_C_API_H_
19#define _IMPORT_C_API_H_
20
21/**
22 * Helper functions to eliminate some of the boilerplate when importing a C API
23 * from a CPython extension module.
24 *
25 * For more information see _export_c_api.h
26 */
27
28static const char *_C_API_NAME = "_C_API";
29
30/**
31 * Import a function from the _C_API_NAME dict that is part of module.
32 *
33 * @param module The Python module we are importing from
34 * the attribute _C_API_NAME will be used as a dictionary
35 * containing the function pointer we are looking for.
36 * @param funcname Name of the function we want to import
37 * @param func A pointer to the function handle where we will store the
38 * function.
39 * @param signature The C signature of the function. This is validated
40 * against the signature stored in the C api, to make sure
41 * there is no versioning skew.
42 */
43static int _import_function(PyObject *module, const char *funcname,
44 void **func, const char *signature)
45{
46 PyObject *d = NULL;
47 PyObject *c_obj = NULL;
48 const char *desc = NULL;
49
50 /* (char *) because Python2.4 defines this as (char *) rather than
51 * (const char *)
52 */
53 d = PyObject_GetAttrString(module, (char *)_C_API_NAME);
54 if (!d) {
55 // PyObject_GetAttrString sets an appropriate exception
56 goto bad;
57 }
58 c_obj = PyDict_GetItemString(d, funcname);
59 if (!c_obj) {
60 // PyDict_GetItemString does not set an exception
61 PyErr_Format(PyExc_AttributeError,
62 "Module %s did not export a function named %s\n",
63 PyModule_GetName(module), funcname);
64 goto bad;
65 }
66 desc = (char *)PyCObject_GetDesc(c_obj);
67 if (!desc || strcmp(desc, signature) != 0) {
68 if (desc == NULL) {
69 desc = "<null>";
70 }
71 PyErr_Format(PyExc_TypeError,
72 "C function %s.%s has wrong signature (expected %s, got %s)",
73 PyModule_GetName(module), funcname, signature, desc);
74 goto bad;
75 }
76 *func = PyCObject_AsVoidPtr(c_obj);
77 Py_DECREF(d);
78 return 0;
79bad:
80 Py_XDECREF(d);
81 return -1;
82}
83
84
85/**
86 * Get a pointer to an exported PyTypeObject.
87 *
88 * @param module The Python module we are importing from
89 * @param class_name Attribute of the module that should reference the
90 * Type object. Note that a PyTypeObject is the python
91 * description of the type, not the raw C structure.
92 * @return A Pointer to the requested type object. On error NULL will be
93 * returned and an exception will be set.
94 */
95static PyTypeObject *
96_import_type(PyObject *module, const char *class_name)
97{
98 PyObject *type = NULL;
99
100 type = PyObject_GetAttrString(module, (char *)class_name);
101 if (!type) {
102 goto bad;
103 }
104 if (!PyType_Check(type)) {
105 PyErr_Format(PyExc_TypeError,
106 "%s.%s is not a type object",
107 PyModule_GetName(module), class_name);
108 goto bad;
109 }
110 return (PyTypeObject *)type;
111bad:
112 Py_XDECREF(type);
113 return NULL;
114}
115
116
117struct function_description
118{
119 const char *name;
120 void **pointer;
121 const char *signature;
122};
123
124struct type_description
125{
126 const char *name;
127 PyTypeObject **pointer;
128};
129
130/**
131 * Helper for importing several functions and types in a data-driven manner.
132 *
133 * @param module The name of the module we will be importing
134 * @param functions A list of function_description objects, describing the
135 * functions being imported.
136 * The list should be terminated with {NULL} to indicate
137 * there are no more functions to import.
138 * @param types A list of type_description objects describing type
139 * objects that we want to import. The list should be
140 * terminated with {NULL} to indicate there are no more
141 * types to import.
142 * @return 0 on success, -1 on error and an exception should be set.
143 */
144
145static int
146_import_extension_module(const char *module_name,
147 struct function_description *functions,
148 struct type_description *types)
149{
150 PyObject *module = NULL;
151 struct function_description *cur_func;
152 struct type_description *cur_type;
153 int ret_code;
154
155 module = PyImport_ImportModule((char *)module_name);
156 if (!module)
157 goto bad;
158 if (functions != NULL) {
159 cur_func = functions;
160 while (cur_func->name != NULL) {
161 ret_code = _import_function(module, cur_func->name,
162 cur_func->pointer,
163 cur_func->signature);
164 if (ret_code < 0)
165 goto bad;
166 cur_func++;
167 }
168 }
169 if (types != NULL) {
170 PyTypeObject *type_p = NULL;
171 cur_type = types;
172 while (cur_type->name != NULL) {
173 type_p = _import_type(module, cur_type->name);
174 if (type_p == NULL)
175 goto bad;
176 *(cur_type->pointer) = type_p;
177 cur_type++;
178 }
179 }
180
181 Py_XDECREF(module);
182 return 0;
183bad:
184 Py_XDECREF(module);
185 return -1;
186}
187
188
189#endif // _IMPORT_C_API_H_
0190
=== modified file 'bzrlib/_known_graph_py.py'
--- bzrlib/_known_graph_py.py 2009-08-25 18:45:40 +0000
+++ bzrlib/_known_graph_py.py 2009-11-03 09:40:55 +0000
@@ -281,3 +281,26 @@
281 in tsort.merge_sort(as_parent_map, tip_key,281 in tsort.merge_sort(as_parent_map, tip_key,
282 mainline_revisions=None,282 mainline_revisions=None,
283 generate_revno=True)]283 generate_revno=True)]
284
285 def get_parent_keys(self, key):
286 """Get the parents for a key
287
288 Returns a list containg the parents keys. If the key is a ghost,
289 None is returned. A KeyError will be raised if the key is not in
290 the graph.
291
292 :param keys: Key to check (eg revision_id)
293 :return: A list of parents
294 """
295 return self._nodes[key].parent_keys
296
297 def get_child_keys(self, key):
298 """Get the children for a key
299
300 Returns a list containg the children keys. A KeyError will be raised
301 if the key is not in the graph.
302
303 :param keys: Key to check (eg revision_id)
304 :return: A list of children
305 """
306 return self._nodes[key].child_keys
284307
=== modified file 'bzrlib/_known_graph_pyx.pyx'
--- bzrlib/_known_graph_pyx.pyx 2009-09-02 13:32:52 +0000
+++ bzrlib/_known_graph_pyx.pyx 2009-11-03 09:40:54 +0000
@@ -88,6 +88,18 @@
88 PyList_Append(keys, child.key)88 PyList_Append(keys, child.key)
89 return keys89 return keys
9090
91 property parent_keys:
92 def __get__(self):
93 if self.parents is None:
94 return None
95
96 cdef _KnownGraphNode parent
97
98 keys = []
99 for parent in self.parents:
100 PyList_Append(keys, parent.key)
101 return keys
102
91 cdef clear_references(self):103 cdef clear_references(self):
92 self.parents = None104 self.parents = None
93 self.children = None105 self.children = None
@@ -549,6 +561,29 @@
549 # shown a specific impact, yet.561 # shown a specific impact, yet.
550 sorter = _MergeSorter(self, tip_key)562 sorter = _MergeSorter(self, tip_key)
551 return sorter.topo_order()563 return sorter.topo_order()
564
565 def get_parent_keys(self, key):
566 """Get the parents for a key
567
568 Returns a list containg the parents keys. If the key is a ghost,
569 None is returned. A KeyError will be raised if the key is not in
570 the graph.
571
572 :param keys: Key to check (eg revision_id)
573 :return: A list of parents
574 """
575 return self._nodes[key].parent_keys
576
577 def get_child_keys(self, key):
578 """Get the children for a key
579
580 Returns a list containg the children keys. A KeyError will be raised
581 if the key is not in the graph.
582
583 :param keys: Key to check (eg revision_id)
584 :return: A list of children
585 """
586 return self._nodes[key].child_keys
552587
553588
554cdef class _MergeSortNode:589cdef class _MergeSortNode:
555590
=== modified file 'bzrlib/_patiencediff_c.c'
--- bzrlib/_patiencediff_c.c 2009-03-23 14:59:43 +0000
+++ bzrlib/_patiencediff_c.c 2009-11-03 09:40:55 +0000
@@ -298,7 +298,7 @@
298 apos = SENTINEL;298 apos = SENTINEL;
299 /* loop through all lines in the linked list */299 /* loop through all lines in the linked list */
300 for (i = h[equiv].a_pos; i != SENTINEL; i = lines_a[i].next) {300 for (i = h[equiv].a_pos; i != SENTINEL; i = lines_a[i].next) {
301 /* the index is lower than alo, the the next line */301 /* the index is lower than alo, continue to the next line */
302 if (i < alo) {302 if (i < alo) {
303 h[equiv].a_pos = i;303 h[equiv].a_pos = i;
304 continue;304 continue;
@@ -319,7 +319,7 @@
319 /* check for duplicates of this line in lines_b[blo:bhi] */319 /* check for duplicates of this line in lines_b[blo:bhi] */
320 /* loop through all lines in the linked list */320 /* loop through all lines in the linked list */
321 for (i = h[equiv].b_pos; i != SENTINEL; i = lines_b[i].next) {321 for (i = h[equiv].b_pos; i != SENTINEL; i = lines_b[i].next) {
322 /* the index is lower than blo, the the next line */322 /* the index is lower than blo, continue to the next line */
323 if (i < blo) {323 if (i < blo) {
324 h[equiv].b_pos = i;324 h[equiv].b_pos = i;
325 continue;325 continue;
326326
=== modified file 'bzrlib/_readdir_pyx.pyx'
--- bzrlib/_readdir_pyx.pyx 2009-07-27 04:24:36 +0000
+++ bzrlib/_readdir_pyx.pyx 2009-11-03 09:40:54 +0000
@@ -343,8 +343,10 @@
343 raise OSError(errno, "lstat: " + strerror(errno),343 raise OSError(errno, "lstat: " + strerror(errno),
344 path + "/" + entry.d_name)344 path + "/" + entry.d_name)
345 else:345 else:
346 kind = _missing346 # the file seems to have disappeared after being
347 statvalue = None347 # seen by readdir - perhaps a transient temporary
348 # file. there's no point returning it.
349 continue
348 # We append a 5-tuple that can be modified in-place by the C350 # We append a 5-tuple that can be modified in-place by the C
349 # api:351 # api:
350 # inode to sort on (to replace with top_path)352 # inode to sort on (to replace with top_path)
351353
=== added file 'bzrlib/_simple_set_pyx.pxd'
--- bzrlib/_simple_set_pyx.pxd 1970-01-01 00:00:00 +0000
+++ bzrlib/_simple_set_pyx.pxd 2009-11-03 09:40:54 +0000
@@ -0,0 +1,91 @@
1# Copyright (C) 2009 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Interface definition of a class like PySet but without caching the hash.
18
19This is generally useful when you want to 'intern' objects, etc. Note that this
20differs from Set in that we:
21 1) Don't have all of the .intersection, .difference, etc functions
22 2) Do return the object from the set via queries
23 eg. SimpleSet.add(key) => saved_key and SimpleSet[key] => saved_key
24"""
25
26cdef extern from "Python.h":
27 ctypedef struct PyObject:
28 pass
29
30
31cdef public api class SimpleSet [object SimpleSetObject, type SimpleSet_Type]:
32 """A class similar to PySet, but with simpler implementation.
33
34 The main advantage is that this class uses only 2N memory to store N
35 objects rather than 4N memory. The main trade-off is that we do not cache
36 the hash value of saved objects. As such, it is assumed that computing the
37 hash will be cheap (such as strings or tuples of strings, etc.)
38
39 This also differs in that you can get back the objects that are stored
40 (like a dict), but we also don't implement the complete list of 'set'
41 operations (difference, intersection, etc).
42 """
43 # Data structure definition:
44 # This is a basic hash table using open addressing.
45 # http://en.wikipedia.org/wiki/Open_addressing
46 # Basically that means we keep an array of pointers to Python objects
47 # (called a table). Each location in the array is called a 'slot'.
48 #
49 # An empty slot holds a NULL pointer, a slot where there was an item
50 # which was then deleted will hold a pointer to _dummy, and a filled slot
51 # points at the actual object which fills that slot.
52 #
53 # The table is always a power of two, and the default location where an
54 # object is inserted is at hash(object) & (table_size - 1)
55 #
56 # If there is a collision, then we search for another location. The
57 # specific algorithm is in _lookup. We search until we:
58 # find the object
59 # find an equivalent object (by tp_richcompare(obj1, obj2, Py_EQ))
60 # find a NULL slot
61 #
62 # When an object is deleted, we set its slot to _dummy. this way we don't
63 # have to track whether there was a collision, and find the corresponding
64 # keys. (The collision resolution algorithm makes that nearly impossible
65 # anyway, because it depends on the upper bits of the hash.)
66 # The main effect of this, is that if we find _dummy, then we can insert
67 # an object there, but we have to keep searching until we find NULL to
68 # know that the object is not present elsewhere.
69
70 cdef Py_ssize_t _used # active
71 cdef Py_ssize_t _fill # active + dummy
72 cdef Py_ssize_t _mask # Table contains (mask+1) slots, a power of 2
73 cdef PyObject **_table # Pyrex/Cython doesn't support arrays to 'object'
74 # so we manage it manually
75
76 cdef PyObject *_get(self, object key) except? NULL
77 cdef object _add(self, key)
78 cdef int _discard(self, key) except -1
79 cdef int _insert_clean(self, PyObject *key) except -1
80 cdef Py_ssize_t _resize(self, Py_ssize_t min_unused) except -1
81
82
83# TODO: might want to export the C api here, though it is all available from
84# the class object...
85cdef api SimpleSet SimpleSet_New()
86cdef api object SimpleSet_Add(object self, object key)
87cdef api int SimpleSet_Contains(object self, object key) except -1
88cdef api int SimpleSet_Discard(object self, object key) except -1
89cdef api PyObject *SimpleSet_Get(SimpleSet self, object key) except? NULL
90cdef api Py_ssize_t SimpleSet_Size(object self) except -1
91cdef api int SimpleSet_Next(object self, Py_ssize_t *pos, PyObject **key)
092
=== added file 'bzrlib/_simple_set_pyx.pyx'
--- bzrlib/_simple_set_pyx.pyx 1970-01-01 00:00:00 +0000
+++ bzrlib/_simple_set_pyx.pyx 2009-11-03 09:40:54 +0000
@@ -0,0 +1,590 @@
1# Copyright (C) 2009 Canonical Ltd
2#
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 2 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16
17"""Definition of a class that is similar to Set with some small changes."""
18
19cdef extern from "python-compat.h":
20 pass
21
22cdef extern from "Python.h":
23 ctypedef unsigned long size_t
24 ctypedef long (*hashfunc)(PyObject*) except -1
25 ctypedef object (*richcmpfunc)(PyObject *, PyObject *, int)
26 ctypedef int (*visitproc)(PyObject *, void *)
27 ctypedef int (*traverseproc)(PyObject *, visitproc, void *)
28 int Py_EQ
29 void Py_INCREF(PyObject *)
30 void Py_DECREF(PyObject *)
31 ctypedef struct PyTypeObject:
32 hashfunc tp_hash
33 richcmpfunc tp_richcompare
34 traverseproc tp_traverse
35
36 PyTypeObject *Py_TYPE(PyObject *)
37 # Note: *Don't* use hash(), Pyrex 0.9.8.5 thinks it returns an 'int', and
38 # thus silently truncates to 32-bits on 64-bit machines.
39 long PyObject_Hash(PyObject *) except -1
40
41 void *PyMem_Malloc(size_t nbytes)
42 void PyMem_Free(void *)
43 void memset(void *, int, size_t)
44
45
46# Dummy is an object used to mark nodes that have been deleted. Since
47# collisions require us to move a node to an alternative location, if we just
48# set an entry to NULL on delete, we won't find any relocated nodes.
49# We have to use _dummy_obj because we need to keep a refcount to it, but we
50# also use _dummy as a pointer, because it avoids having to put <PyObject*> all
51# over the code base.
52cdef object _dummy_obj
53cdef PyObject *_dummy
54_dummy_obj = object()
55_dummy = <PyObject *>_dummy_obj
56
57
58cdef object _NotImplemented
59_NotImplemented = NotImplemented
60
61
62cdef int _is_equal(PyObject *this, long this_hash, PyObject *other) except -1:
63 cdef long other_hash
64
65 if this == other:
66 return 1
67 other_hash = PyObject_Hash(other)
68 if other_hash != this_hash:
69 return 0
70
71 # This implements a subset of the PyObject_RichCompareBool functionality.
72 # Namely it:
73 # 1) Doesn't try to do anything with old-style classes
74 # 2) Assumes that both objects have a tp_richcompare implementation, and
75 # that if that is not enough to compare equal, then they are not
76 # equal. (It doesn't try to cast them both to some intermediate form
77 # that would compare equal.)
78 res = Py_TYPE(this).tp_richcompare(this, other, Py_EQ)
79 if res is _NotImplemented:
80 res = Py_TYPE(other).tp_richcompare(other, this, Py_EQ)
81 if res is _NotImplemented:
82 return 0
83 if res:
84 return 1
85 return 0
86
87
88cdef public api class SimpleSet [object SimpleSetObject, type SimpleSet_Type]:
89 """This class can be used to track canonical forms for objects.
90
91 It is similar in function to the interned dictionary that is used by
92 strings. However:
93
94 1) It assumes that hash(obj) is cheap, so does not need to inline a copy
95 of it
96 2) It only stores one reference to the object, rather than 2 (key vs
97 key:value)
98
99 As such, it uses 1/3rd the amount of memory to store a pointer to the
100 interned object.
101 """
102 # Attributes are defined in the .pxd file
103 DEF DEFAULT_SIZE=1024
104
105 def __init__(self):
106 cdef Py_ssize_t size, n_bytes
107
108 size = DEFAULT_SIZE
109 self._mask = size - 1
110 self._used = 0
111 self._fill = 0
112 n_bytes = sizeof(PyObject*) * size;
113 self._table = <PyObject **>PyMem_Malloc(n_bytes)
114 if self._table == NULL:
115 raise MemoryError()
116 memset(self._table, 0, n_bytes)
117
118 def __dealloc__(self):
119 if self._table != NULL:
120 PyMem_Free(self._table)
121 self._table = NULL
122
123 property used:
124 def __get__(self):
125 return self._used
126
127 property fill:
128 def __get__(self):
129 return self._fill
130
131 property mask:
132 def __get__(self):
133 return self._mask
134
135 def _memory_size(self):
136 """Return the number of bytes of memory consumed by this class."""
137 return sizeof(self) + (sizeof(PyObject*)*(self._mask + 1))
138
139 def __len__(self):
140 return self._used
141
142 def _test_lookup(self, key):
143 cdef PyObject **slot
144
145 slot = _lookup(self, key)
146 if slot[0] == NULL:
147 res = '<null>'
148 elif slot[0] == _dummy:
149 res = '<dummy>'
150 else:
151 res = <object>slot[0]
152 return <int>(slot - self._table), res
153
154 def __contains__(self, key):
155 """Is key present in this SimpleSet."""
156 cdef PyObject **slot
157
158 slot = _lookup(self, key)
159 if slot[0] == NULL or slot[0] == _dummy:
160 return False
161 return True
162
163 cdef PyObject *_get(self, object key) except? NULL:
164 """Return the object (or nothing) define at the given location."""
165 cdef PyObject **slot
166
167 slot = _lookup(self, key)
168 if slot[0] == NULL or slot[0] == _dummy:
169 return NULL
170 return slot[0]
171
172 def __getitem__(self, key):
173 """Return a stored item that is equivalent to key."""
174 cdef PyObject *py_val
175
176 py_val = self._get(key)
177 if py_val == NULL:
178 raise KeyError("Key %s is not present" % key)
179 val = <object>(py_val)
180 return val
181
182 cdef int _insert_clean(self, PyObject *key) except -1:
183 """Insert a key into self.table.
184
185 This is only meant to be used during times like '_resize',
186 as it makes a lot of assuptions about keys not already being present,
187 and there being no dummy entries.
188 """
189 cdef size_t i, n_lookup
190 cdef long the_hash
191 cdef PyObject **table, **slot
192 cdef Py_ssize_t mask
193
194 mask = self._mask
195 table = self._table
196
197 the_hash = PyObject_Hash(key)
198 i = the_hash
199 for n_lookup from 0 <= n_lookup <= <size_t>mask: # Don't loop forever
200 slot = &table[i & mask]
201 if slot[0] == NULL:
202 slot[0] = key
203 self._fill = self._fill + 1
204 self._used = self._used + 1
205 return 1
206 i = i + 1 + n_lookup
207 raise RuntimeError('ran out of slots.')
208
209 def _py_resize(self, min_used):
210 """Do not use this directly, it is only exposed for testing."""
211 return self._resize(min_used)
212
213 cdef Py_ssize_t _resize(self, Py_ssize_t min_used) except -1:
214 """Resize the internal table.
215
216 The final table will be big enough to hold at least min_used entries.
217 We will copy the data from the existing table over, leaving out dummy
218 entries.
219
220 :return: The new size of the internal table
221 """
222 cdef Py_ssize_t new_size, n_bytes, remaining
223 cdef PyObject **new_table, **old_table, **slot
224
225 new_size = DEFAULT_SIZE
226 while new_size <= min_used and new_size > 0:
227 new_size = new_size << 1
228 # We rolled over our signed size field
229 if new_size <= 0:
230 raise MemoryError()
231 # Even if min_used == self._mask + 1, and we aren't changing the actual
232 # size, we will still run the algorithm so that dummy entries are
233 # removed
234 # TODO: Test this
235 # if new_size < self._used:
236 # raise RuntimeError('cannot shrink SimpleSet to something'
237 # ' smaller than the number of used slots.')
238 n_bytes = sizeof(PyObject*) * new_size;
239 new_table = <PyObject **>PyMem_Malloc(n_bytes)
240 if new_table == NULL:
241 raise MemoryError()
242
243 old_table = self._table
244 self._table = new_table
245 memset(self._table, 0, n_bytes)
246 self._mask = new_size - 1
247 self._used = 0
248 remaining = self._fill
249 self._fill = 0
250
251 # Moving everything to the other table is refcount neutral, so we don't
252 # worry about it.
253 slot = old_table
254 while remaining > 0:
255 if slot[0] == NULL: # unused slot
256 pass
257 elif slot[0] == _dummy: # dummy slot
258 remaining = remaining - 1
259 else: # active slot
260 remaining = remaining - 1
261 self._insert_clean(slot[0])
262 slot = slot + 1
263 PyMem_Free(old_table)
264 return new_size
265
266 def add(self, key):
267 """Similar to set.add(), start tracking this key.
268
269 There is one small difference, which is that we return the object that
270 is stored at the given location. (which is closer to the
271 dict.setdefault() functionality.)
272 """
273 return self._add(key)
274
275 cdef object _add(self, key):
276 cdef PyObject **slot, *py_key
277 cdef int added
278
279 py_key = <PyObject *>key
280 if (Py_TYPE(py_key).tp_richcompare == NULL
281 or Py_TYPE(py_key).tp_hash == NULL):
282 raise TypeError('Types added to SimpleSet must implement'
283 ' both tp_richcompare and tp_hash')
284 added = 0
285 # We need at least one empty slot
286 assert self._used < self._mask
287 slot = _lookup(self, key)
288 if (slot[0] == NULL):
289 Py_INCREF(py_key)
290 self._fill = self._fill + 1
291 self._used = self._used + 1
292 slot[0] = py_key
293 added = 1
294 elif (slot[0] == _dummy):
295 Py_INCREF(py_key)
296 self._used = self._used + 1
297 slot[0] = py_key
298 added = 1
299 # No else: clause. If _lookup returns a pointer to
300 # a live object, then we already have a value at this location.
301 retval = <object>(slot[0])
302 # PySet and PyDict use a 2-3rds full algorithm, we'll follow suit
303 if added and (self._fill * 3) >= ((self._mask + 1) * 2):
304 # However, we always work for a load factor of 2:1
305 self._resize(self._used * 2)
306 # Even if we resized and ended up moving retval into a different slot,
307 # it is still the value that is held at the slot equivalent to 'key',
308 # so we can still return it
309 return retval
310
311 def discard(self, key):
312 """Remove key from the set, whether it exists or not.
313
314 :return: False if the item did not exist, True if it did
315 """
316 if self._discard(key):
317 return True
318 return False
319
320 cdef int _discard(self, key) except -1:
321 cdef PyObject **slot, *py_key
322
323 slot = _lookup(self, key)
324 if slot[0] == NULL or slot[0] == _dummy:
325 return 0
326 self._used = self._used - 1
327 Py_DECREF(slot[0])
328 slot[0] = _dummy
329 # PySet uses the heuristic: If more than 1/5 are dummies, then resize
330 # them away
331 # if ((so->_fill - so->_used) * 5 < so->mask)
332 # However, we are planning on using this as an interning structure, in
333 # which we will be putting a lot of objects. And we expect that large
334 # groups of them are going to have the same lifetime.
335 # Dummy entries hurt a little bit because they cause the lookup to keep
336 # searching, but resizing is also rather expensive
337 # For now, we'll just use their algorithm, but we may want to revisit
338 # it
339 if ((self._fill - self._used) * 5 > self._mask):
340 self._resize(self._used * 2)
341 return 1
342
343 def __iter__(self):
344 return _SimpleSet_iterator(self)
345
346
347cdef class _SimpleSet_iterator:
348 """Iterator over the SimpleSet structure."""
349
350 cdef Py_ssize_t pos
351 cdef SimpleSet set
352 cdef Py_ssize_t _used # track if things have been mutated while iterating
353 cdef Py_ssize_t len # number of entries left
354
355 def __init__(self, obj):
356 self.set = obj
357 self.pos = 0
358 self._used = self.set._used
359 self.len = self.set._used
360
361 def __iter__(self):
362 return self
363
364 def __next__(self):
365 cdef Py_ssize_t mask, i
366 cdef PyObject *key
367
368 if self.set is None:
369 raise StopIteration
370 if self.set._used != self._used:
371 # Force this exception to continue to be raised
372 self._used = -1
373 raise RuntimeError("Set size changed during iteration")
374 if not SimpleSet_Next(self.set, &self.pos, &key):
375 self.set = None
376 raise StopIteration
377 # we found something
378 the_key = <object>key # INCREF
379 self.len = self.len - 1
380 return the_key
381
382 def __length_hint__(self):
383 if self.set is not None and self._used == self.set._used:
384 return self.len
385 return 0
386
387
388
389cdef api SimpleSet SimpleSet_New():
390 """Create a new SimpleSet object."""
391 return SimpleSet()
392
393
394cdef SimpleSet _check_self(object self):
395 """Check that the parameter is not None.
396
397 Pyrex/Cython will do type checking, but only to ensure that an object is
398 either the right type or None. You can say "object foo not None" for pure
399 python functions, but not for C functions.
400 So this is just a helper for all the apis that need to do the check.
401 """
402 cdef SimpleSet true_self
403 if self is None:
404 raise TypeError('self must not be None')
405 true_self = self
406 return true_self
407
408
409cdef PyObject **_lookup(SimpleSet self, object key) except NULL:
410 """Find the slot where 'key' would fit.
411
412 This is the same as a dicts 'lookup' function.
413
414 :param key: An object we are looking up
415 :param hash: The hash for key
416 :return: The location in self.table where key should be put.
417 location == NULL is an exception, but (*location) == NULL just
418 indicates the slot is empty and can be used.
419 """
420 # This uses Quadratic Probing:
421 # http://en.wikipedia.org/wiki/Quadratic_probing
422 # with c1 = c2 = 1/2
423 # This leads to probe locations at:
424 # h0 = hash(k1)
425 # h1 = h0 + 1
426 # h2 = h0 + 3 = h1 + 1 + 1
427 # h3 = h0 + 6 = h2 + 1 + 2
428 # h4 = h0 + 10 = h2 + 1 + 3
429 # Note that all of these are '& mask', but that is computed *after* the
430 # offset.
431 # This differs from the algorithm used by Set and Dict. Which, effectively,
432 # use double-hashing, and a step size that starts large, but dwindles to
433 # stepping one-by-one.
434 # This gives more 'locality' in that if you have a collision at offset X,
435 # the first fallback is X+1, which is fast to check. However, that means
436 # that an object w/ hash X+1 will also check there, and then X+2 next.
437 # However, for objects with differing hashes, their chains are different.
438 # The former checks X, X+1, X+3, ... the latter checks X+1, X+2, X+4, ...
439 # So different hashes diverge quickly.
440 # A bigger problem is that we *only* ever use the lowest bits of the hash
441 # So all integers (x + SIZE*N) will resolve into the same bucket, and all
442 # use the same collision resolution. We may want to try to find a way to
443 # incorporate the upper bits of the hash with quadratic probing. (For
444 # example, X, X+1, X+3+some_upper_bits, X+6+more_upper_bits, etc.)
445 cdef size_t i, n_lookup
446 cdef Py_ssize_t mask
447 cdef long key_hash
448 cdef PyObject **table, **slot, *cur, **free_slot, *py_key
449
450 py_key = <PyObject *>key
451 # Note: avoid using hash(obj) because of a bug w/ pyrex 0.9.8.5 and 64-bit
452 # (it treats hash() as returning an 'int' rather than a 'long')
453 key_hash = PyObject_Hash(py_key)
454 i = <size_t>key_hash
455 mask = self._mask
456 table = self._table
457 free_slot = NULL
458 for n_lookup from 0 <= n_lookup <= <size_t>mask: # Don't loop forever
459 slot = &table[i & mask]
460 cur = slot[0]
461 if cur == NULL:
462 # Found a blank spot
463 if free_slot != NULL:
464 # Did we find an earlier _dummy entry?
465 return free_slot
466 else:
467 return slot
468 if cur == py_key:
469 # Found an exact pointer to the key
470 return slot
471 if cur == _dummy:
472 if free_slot == NULL:
473 free_slot = slot
474 elif _is_equal(py_key, key_hash, cur):
475 # Both py_key and cur belong in this slot, return it
476 return slot
477 i = i + 1 + n_lookup
478 raise AssertionError('should never get here')
479
480
481cdef api PyObject **_SimpleSet_Lookup(object self, object key) except NULL:
482 """Find the slot where 'key' would fit.
483
484 This is the same as a dicts 'lookup' function. This is a private
485 api because mutating what you get without maintaing the other invariants
486 is a 'bad thing'.
487
488 :param key: An object we are looking up
489 :param hash: The hash for key
490 :return: The location in self._table where key should be put
491 should never be NULL, but may reference a NULL (PyObject*)
492 """
493 return _lookup(_check_self(self), key)
494
495
496cdef api object SimpleSet_Add(object self, object key):
497 """Add a key to the SimpleSet (set).
498
499 :param self: The SimpleSet to add the key to.
500 :param key: The key to be added. If the key is already present,
501 self will not be modified
502 :return: The current key stored at the location defined by 'key'.
503 This may be the same object, or it may be an equivalent object.
504 (consider dict.setdefault(key, key))
505 """
506 return _check_self(self)._add(key)
507
508
509cdef api int SimpleSet_Contains(object self, object key) except -1:
510 """Is key present in self?"""
511 return (key in _check_self(self))
512
513
514cdef api int SimpleSet_Discard(object self, object key) except -1:
515 """Remove the object referenced at location 'key'.
516
517 :param self: The SimpleSet being modified
518 :param key: The key we are checking on
519 :return: 1 if there was an object present, 0 if there was not, and -1 on
520 error.
521 """
522 return _check_self(self)._discard(key)
523
524
525cdef api PyObject *SimpleSet_Get(SimpleSet self, object key) except? NULL:
526 """Get a pointer to the object present at location 'key'.
527
528 This returns an object which is equal to key which was previously added to
529 self. This returns a borrowed reference, as it may also return NULL if no
530 value is present at that location.
531
532 :param key: The value we are looking for
533 :return: The object present at that location
534 """
535 return _check_self(self)._get(key)
536
537
538cdef api Py_ssize_t SimpleSet_Size(object self) except -1:
539 """Get the number of active entries in 'self'"""
540 return _check_self(self)._used
541
542
543cdef api int SimpleSet_Next(object self, Py_ssize_t *pos, PyObject **key):
544 """Walk over items in a SimpleSet.
545
546 :param pos: should be initialized to 0 by the caller, and will be updated
547 by this function
548 :param key: Will return a borrowed reference to key
549 :return: 0 if nothing left, 1 if we are returning a new value
550 """
551 cdef Py_ssize_t i, mask
552 cdef SimpleSet true_self
553 cdef PyObject **table
554 true_self = _check_self(self)
555 i = pos[0]
556 if (i < 0):
557 return 0
558 mask = true_self._mask
559 table= true_self._table
560 while (i <= mask and (table[i] == NULL or table[i] == _dummy)):
561 i = i + 1
562 pos[0] = i + 1
563 if (i > mask):
564 return 0 # All done
565 if (key != NULL):
566 key[0] = table[i]
567 return 1
568
569
570cdef int SimpleSet_traverse(SimpleSet self, visitproc visit, void *arg):
571 """This is an implementation of 'tp_traverse' that hits the whole table.
572
573 Cython/Pyrex don't seem to let you define a tp_traverse, and they only
574 define one for you if you have an 'object' attribute. Since they don't
575 support C arrays of objects, we access the PyObject * directly.
576 """
577 cdef Py_ssize_t pos
578 cdef PyObject *next_key
579 cdef int ret
580
581 pos = 0
582 while SimpleSet_Next(self, &pos, &next_key):
583 ret = visit(next_key, arg)
584 if ret:
585 return ret
586 return 0
587
588# It is a little bit ugly to do this, but it works, and means that Meliae can
589# dump the total memory consumed by all child objects.
590(<PyTypeObject *>SimpleSet).tp_traverse = <traverseproc>SimpleSet_traverse
0591
=== added file 'bzrlib/_static_tuple_c.c'
--- bzrlib/_static_tuple_c.c 1970-01-01 00:00:00 +0000
+++ bzrlib/_static_tuple_c.c 2009-11-03 09:40:55 +0000
@@ -0,0 +1,941 @@
1/* Copyright (C) 2009 Canonical Ltd
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 *
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17
18/* Must be defined before importing _static_tuple_c.h so that we get the right
19 * linkage.
20 */
21#define STATIC_TUPLE_MODULE
22
23#include <Python.h>
24#include "python-compat.h"
25
26#include "_static_tuple_c.h"
27#include "_export_c_api.h"
28
29/* Pyrex 0.9.6.4 exports _simple_set_pyx_api as
30 * import__simple_set_pyx(), while Pyrex 0.9.8.5 and Cython 0.11.3 export them
31 * as import_bzrlib___simple_set_pyx(). As such, we just #define one to be
32 * equivalent to the other in our internal code.
33 */
34#define import__simple_set_pyx import_bzrlib___simple_set_pyx
35#include "_simple_set_pyx_api.h"
36
37#if defined(__GNUC__)
38# define inline __inline__
39#elif defined(_MSC_VER)
40# define inline __inline
41#else
42# define inline
43#endif
44
45
46/* The one and only StaticTuple with no values */
47static StaticTuple *_empty_tuple = NULL;
48static PyObject *_interned_tuples = NULL;
49
50
51static inline int
52_StaticTuple_is_interned(StaticTuple *self)
53{
54 return self->flags & STATIC_TUPLE_INTERNED_FLAG;
55}
56
57
58
59static PyObject *
60StaticTuple_as_tuple(StaticTuple *self)
61{
62 PyObject *tpl = NULL, *obj = NULL;
63 int i, len;
64
65 len = self->size;
66 tpl = PyTuple_New(len);
67 if (!tpl) {
68 /* Malloc failure */
69 return NULL;
70 }
71 for (i = 0; i < len; ++i) {
72 obj = (PyObject *)self->items[i];
73 Py_INCREF(obj);
74 PyTuple_SET_ITEM(tpl, i, obj);
75 }
76 return tpl;
77}
78
79
80static char StaticTuple_as_tuple_doc[] = "as_tuple() => tuple";
81
82static StaticTuple *
83StaticTuple_Intern(StaticTuple *self)
84{
85 PyObject *canonical_tuple = NULL;
86
87 if (_interned_tuples == NULL || _StaticTuple_is_interned(self)) {
88 Py_INCREF(self);
89 return self;
90 }
91 /* SimpleSet_Add returns whatever object is present at self
92 * or the new object if it needs to add it.
93 */
94 canonical_tuple = SimpleSet_Add(_interned_tuples, (PyObject *)self);
95 if (!canonical_tuple) {
96 // Some sort of exception, propogate it.
97 return NULL;
98 }
99 if (canonical_tuple != (PyObject *)self) {
100 // There was already a tuple with that value
101 return (StaticTuple *)canonical_tuple;
102 }
103 self->flags |= STATIC_TUPLE_INTERNED_FLAG;
104 // The two references in the dict do not count, so that the StaticTuple
105 // object does not become immortal just because it was interned.
106 Py_REFCNT(self) -= 1;
107 return self;
108}
109
110static char StaticTuple_Intern_doc[] = "intern() => unique StaticTuple\n"
111 "Return a 'canonical' StaticTuple object.\n"
112 "Similar to intern() for strings, this makes sure there\n"
113 "is only one StaticTuple object for a given value\n."
114 "Common usage is:\n"
115 " key = StaticTuple('foo', 'bar').intern()\n";
116
117
118static void
119StaticTuple_dealloc(StaticTuple *self)
120{
121 int i, len;
122
123 if (_StaticTuple_is_interned(self)) {
124 /* revive dead object temporarily for Discard */
125 Py_REFCNT(self) = 2;
126 if (SimpleSet_Discard(_interned_tuples, (PyObject*)self) != 1)
127 Py_FatalError("deletion of interned StaticTuple failed");
128 self->flags &= ~STATIC_TUPLE_INTERNED_FLAG;
129 }
130 len = self->size;
131 for (i = 0; i < len; ++i) {
132 Py_XDECREF(self->items[i]);
133 }
134 Py_TYPE(self)->tp_free((PyObject *)self);
135}
136
137
138/* Similar to PyTuple_New() */
139static StaticTuple *
140StaticTuple_New(Py_ssize_t size)
141{
142 StaticTuple *stuple;
143 if (size < 0) {
144 PyErr_BadInternalCall();
145 return NULL;
146 }
147
148 if (size < 0 || size > 255) {
149 /* Too big or too small */
150 PyErr_SetString(PyExc_ValueError, "StaticTuple(...)"
151 " takes from 0 to 255 items");
152 return NULL;
153 }
154 if (size == 0 && _empty_tuple != NULL) {
155 Py_INCREF(_empty_tuple);
156 return _empty_tuple;
157 }
158 /* Note that we use PyObject_NewVar because we want to allocate a variable
159 * width entry. However we *aren't* truly a PyVarObject because we don't
160 * use a long for ob_size. Instead we use a plain 'size' that is an int,
161 * and will be overloaded with flags in the future.
162 * As such we do the alloc, and then have to clean up anything it does
163 * incorrectly.
164 */
165 stuple = PyObject_NewVar(StaticTuple, &StaticTuple_Type, size);
166 if (stuple == NULL) {
167 return NULL;
168 }
169 stuple->size = size;
170 stuple->flags = 0;
171 stuple->_unused0 = 0;
172 stuple->_unused1 = 0;
173 if (size > 0) {
174 memset(stuple->items, 0, sizeof(PyObject *) * size);
175 }
176#if STATIC_TUPLE_HAS_HASH
177 stuple->hash = -1;
178#endif
179 return stuple;
180}
181
182
183static StaticTuple *
184StaticTuple_FromSequence(PyObject *sequence)
185{
186 StaticTuple *new = NULL;
187 PyObject *as_tuple = NULL;
188 PyObject *item;
189 Py_ssize_t i, size;
190
191 if (StaticTuple_CheckExact(sequence)) {
192 Py_INCREF(sequence);
193 return (StaticTuple *)sequence;
194 }
195 if (!PySequence_Check(sequence)) {
196 as_tuple = PySequence_Tuple(sequence);
197 if (as_tuple == NULL)
198 goto done;
199 sequence = as_tuple;
200 }
201 size = PySequence_Size(sequence);
202 if (size == -1) {
203 goto done;
204 }
205 new = StaticTuple_New(size);
206 if (new == NULL) {
207 goto done;
208 }
209 for (i = 0; i < size; ++i) {
210 // This returns a new reference, which we then 'steal' with
211 // StaticTuple_SET_ITEM
212 item = PySequence_GetItem(sequence, i);
213 if (item == NULL) {
214 Py_DECREF(new);
215 new = NULL;
216 goto done;
217 }
218 StaticTuple_SET_ITEM(new, i, item);
219 }
220done:
221 Py_XDECREF(as_tuple);
222 return (StaticTuple *)new;
223}
224
225static StaticTuple *
226StaticTuple_from_sequence(PyObject *self, PyObject *args, PyObject *kwargs)
227{
228 PyObject *sequence;
229 if (!PyArg_ParseTuple(args, "O", &sequence))
230 return NULL;
231 return StaticTuple_FromSequence(sequence);
232}
233
234
235/* Check that all items we point to are 'valid' */
236static int
237StaticTuple_check_items(StaticTuple *self)
238{
239 int i;
240 PyObject *obj;
241
242 for (i = 0; i < self->size; ++i) {
243 obj = self->items[i];
244 if (obj == NULL) {
245 PyErr_SetString(PyExc_RuntimeError, "StaticTuple(...)"
246 " should not have a NULL entry.");
247 return 0;
248 }
249 if (PyString_CheckExact(obj)
250 || StaticTuple_CheckExact(obj)
251 || obj == Py_None
252 || PyBool_Check(obj)
253 || PyInt_CheckExact(obj)
254 || PyLong_CheckExact(obj)
255 || PyFloat_CheckExact(obj)
256 || PyUnicode_CheckExact(obj)
257 ) continue;
258 PyErr_Format(PyExc_TypeError, "StaticTuple(...)"
259 " requires that all items are one of"
260 " str, StaticTuple, None, bool, int, long, float, or unicode"
261 " not %s.", Py_TYPE(obj)->tp_name);
262 return 0;
263 }
264 return 1;
265}
266
267static PyObject *
268StaticTuple_new_constructor(PyTypeObject *type, PyObject *args, PyObject *kwds)
269{
270 StaticTuple *self;
271 PyObject *obj = NULL;
272 Py_ssize_t i, len = 0;
273
274 if (type != &StaticTuple_Type) {
275 PyErr_SetString(PyExc_TypeError, "we only support creating StaticTuple");
276 return NULL;
277 }
278 if (!PyTuple_CheckExact(args)) {
279 PyErr_SetString(PyExc_TypeError, "args must be a tuple");
280 return NULL;
281 }
282 len = PyTuple_GET_SIZE(args);
283 self = (StaticTuple *)StaticTuple_New(len);
284 if (self == NULL) {
285 return NULL;
286 }
287 for (i = 0; i < len; ++i) {
288 obj = PyTuple_GET_ITEM(args, i);
289 Py_INCREF(obj);
290 self->items[i] = obj;
291 }
292 if (!StaticTuple_check_items(self)) {
293 type->tp_dealloc((PyObject *)self);
294 return NULL;
295 }
296 return (PyObject *)self;
297}
298
299static PyObject *
300StaticTuple_repr(StaticTuple *self)
301{
302 PyObject *as_tuple, *tuple_repr, *result;
303
304 as_tuple = StaticTuple_as_tuple(self);
305 if (as_tuple == NULL) {
306 return NULL;
307 }
308 tuple_repr = PyObject_Repr(as_tuple);
309 Py_DECREF(as_tuple);
310 if (tuple_repr == NULL) {
311 return NULL;
312 }
313 result = PyString_FromFormat("StaticTuple%s",
314 PyString_AsString(tuple_repr));
315 return result;
316}
317
318static long
319StaticTuple_hash(StaticTuple *self)
320{
321 /* adapted from tuplehash(), is the specific hash value considered
322 * 'stable'?
323 */
324 register long x, y;
325 Py_ssize_t len = self->size;
326 PyObject **p;
327 long mult = 1000003L;
328
329#if STATIC_TUPLE_HAS_HASH
330 if (self->hash != -1) {
331 return self->hash;
332 }
333#endif
334 x = 0x345678L;
335 p = self->items;
336 // TODO: We could set specific flags if we know that, for example, all the
337 // items are strings. I haven't seen a real-world benefit to that
338 // yet, though.
339 while (--len >= 0) {
340 y = PyObject_Hash(*p++);
341 if (y == -1) /* failure */
342 return -1;
343 x = (x ^ y) * mult;
344 /* the cast might truncate len; that doesn't change hash stability */
345 mult += (long)(82520L + len + len);
346 }
347 x += 97531L;
348 if (x == -1)
349 x = -2;
350#if STATIC_TUPLE_HAS_HASH
351 self->hash = x;
352#endif
353 return x;
354}
355
356static PyObject *
357StaticTuple_richcompare_to_tuple(StaticTuple *v, PyObject *wt, int op)
358{
359 PyObject *vt;
360 PyObject *result = NULL;
361
362 vt = StaticTuple_as_tuple((StaticTuple *)v);
363 if (vt == NULL) {
364 goto done;
365 }
366 if (!PyTuple_Check(wt)) {
367 PyErr_BadInternalCall();
368 goto done;
369 }
370 /* Now we have 2 tuples to compare, do it */
371 result = PyTuple_Type.tp_richcompare(vt, wt, op);
372done:
373 Py_XDECREF(vt);
374 return result;
375}
376
377/** Compare two objects to determine if they are equivalent.
378 * The basic flow is as follows
379 * 1) First make sure that both objects are StaticTuple instances. If they
380 * aren't then cast self to a tuple, and have the tuple do the comparison.
381 * 2) Special case comparison to Py_None, because it happens to occur fairly
382 * often in the test suite.
383 * 3) Special case when v and w are the same pointer. As we know the answer to
384 * all queries without walking individual items.
385 * 4) For all operations, we then walk the items to find the first paired
386 * items that are not equal.
387 * 5) If all items found are equal, we then check the length of self and
388 * other to determine equality.
389 * 6) If an item differs, then we apply "op" to those last two items. (eg.
390 * StaticTuple(A, B) > StaticTuple(A, C) iff B > C)
391 */
392
393static PyObject *
394StaticTuple_richcompare(PyObject *v, PyObject *w, int op)
395{
396 StaticTuple *v_st, *w_st;
397 Py_ssize_t vlen, wlen, min_len, i;
398 PyObject *v_obj, *w_obj;
399 richcmpfunc string_richcompare;
400
401 if (!StaticTuple_CheckExact(v)) {
402 /* This has never triggered, according to python-dev it seems this
403 * might trigger if '__op__' is defined but '__rop__' is not, sort of
404 * case. Such as "None == StaticTuple()"
405 */
406 fprintf(stderr, "self is not StaticTuple\n");
407 Py_INCREF(Py_NotImplemented);
408 return Py_NotImplemented;
409 }
410 v_st = (StaticTuple *)v;
411 if (StaticTuple_CheckExact(w)) {
412 /* The most common case */
413 w_st = (StaticTuple*)w;
414 } else if (PyTuple_Check(w)) {
415 /* One of v or w is a tuple, so we go the 'slow' route and cast up to
416 * tuples to compare.
417 */
418 /* TODO: This seems to be triggering more than I thought it would...
419 * We probably want to optimize comparing self to other when
420 * other is a tuple.
421 */
422 return StaticTuple_richcompare_to_tuple(v_st, w, op);
423 } else if (w == Py_None) {
424 // None is always less than the object
425 switch (op) {
426 case Py_NE:case Py_GT:case Py_GE:
427 Py_INCREF(Py_True);
428 return Py_True;
429 case Py_EQ:case Py_LT:case Py_LE:
430 Py_INCREF(Py_False);
431 return Py_False;
432 default: // Should never happen
433 return Py_NotImplemented;
434 }
435 } else {
436 /* We don't special case this comparison, we just let python handle
437 * it.
438 */
439 Py_INCREF(Py_NotImplemented);
440 return Py_NotImplemented;
441 }
442 /* Now we know that we have 2 StaticTuple objects, so let's compare them.
443 * This code is inspired from tuplerichcompare, except we know our
444 * objects are limited in scope, so we can inline some comparisons.
445 */
446 if (v == w) {
447 /* Identical pointers, we can shortcut this easily. */
448 switch (op) {
449 case Py_EQ:case Py_LE:case Py_GE:
450 Py_INCREF(Py_True);
451 return Py_True;
452 case Py_NE:case Py_LT:case Py_GT:
453 Py_INCREF(Py_False);
454 return Py_False;
455 }
456 }
457 if (op == Py_EQ
458 && _StaticTuple_is_interned(v_st)
459 && _StaticTuple_is_interned(w_st))
460 {
461 /* If both objects are interned, we know they are different if the
462 * pointer is not the same, which would have been handled by the
463 * previous if. No need to compare the entries.
464 */
465 Py_INCREF(Py_False);
466 return Py_False;
467 }
468
469 /* The only time we are likely to compare items of different lengths is in
470 * something like the interned_keys set. However, the hash is good enough
471 * that it is rare. Note that 'tuple_richcompare' also does not compare
472 * lengths here.
473 */
474 vlen = v_st->size;
475 wlen = w_st->size;
476 min_len = (vlen < wlen) ? vlen : wlen;
477 string_richcompare = PyString_Type.tp_richcompare;
478 for (i = 0; i < min_len; i++) {
479 PyObject *result = NULL;
480 v_obj = StaticTuple_GET_ITEM(v_st, i);
481 w_obj = StaticTuple_GET_ITEM(w_st, i);
482 if (v_obj == w_obj) {
483 /* Shortcut case, these must be identical */
484 continue;
485 }
486 if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj)) {
487 result = string_richcompare(v_obj, w_obj, Py_EQ);
488 } else if (StaticTuple_CheckExact(v_obj) &&
489 StaticTuple_CheckExact(w_obj))
490 {
491 /* Both are StaticTuple types, so recurse */
492 result = StaticTuple_richcompare(v_obj, w_obj, Py_EQ);
493 } else {
494 /* Fall back to generic richcompare */
495 result = PyObject_RichCompare(v_obj, w_obj, Py_EQ);
496 }
497 if (result == NULL) {
498 return NULL; /* There seems to be an error */
499 }
500 if (result == Py_False) {
501 // This entry is not identical, Shortcut for Py_EQ
502 if (op == Py_EQ) {
503 return result;
504 }
505 Py_DECREF(result);
506 break;
507 }
508 if (result != Py_True) {
509 /* We don't know *what* richcompare is returning, but it
510 * isn't something we recognize
511 */
512 PyErr_BadInternalCall();
513 Py_DECREF(result);
514 return NULL;
515 }
516 Py_DECREF(result);
517 }
518 if (i >= min_len) {
519 /* We walked off one of the lists, but everything compared equal so
520 * far. Just compare the size.
521 */
522 int cmp;
523 PyObject *res;
524 switch (op) {
525 case Py_LT: cmp = vlen < wlen; break;
526 case Py_LE: cmp = vlen <= wlen; break;
527 case Py_EQ: cmp = vlen == wlen; break;
528 case Py_NE: cmp = vlen != wlen; break;
529 case Py_GT: cmp = vlen > wlen; break;
530 case Py_GE: cmp = vlen >= wlen; break;
531 default: return NULL; /* cannot happen */
532 }
533 if (cmp)
534 res = Py_True;
535 else
536 res = Py_False;
537 Py_INCREF(res);
538 return res;
539 }
540 /* The last item differs, shortcut the Py_NE case */
541 if (op == Py_NE) {
542 Py_INCREF(Py_True);
543 return Py_True;
544 }
545 /* It is some other comparison, go ahead and do the real check. */
546 if (PyString_CheckExact(v_obj) && PyString_CheckExact(w_obj))
547 {
548 return string_richcompare(v_obj, w_obj, op);
549 } else if (StaticTuple_CheckExact(v_obj) &&
550 StaticTuple_CheckExact(w_obj))
551 {
552 /* Both are StaticTuple types, so recurse */
553 return StaticTuple_richcompare(v_obj, w_obj, op);
554 } else {
555 return PyObject_RichCompare(v_obj, w_obj, op);
556 }
557}
558
559
560static Py_ssize_t
561StaticTuple_length(StaticTuple *self)
562{
563 return self->size;
564}
565
566
567static PyObject *
568StaticTuple__is_interned(StaticTuple *self)
569{
570 if (_StaticTuple_is_interned(self)) {
571 Py_INCREF(Py_True);
572 return Py_True;
573 }
574 Py_INCREF(Py_False);
575 return Py_False;
576}
577
578static char StaticTuple__is_interned_doc[] = "_is_interned() => True/False\n"
579 "Check to see if this tuple has been interned.\n";
580
581
582static PyObject *
583StaticTuple_reduce(StaticTuple *self)
584{
585 PyObject *result = NULL, *as_tuple = NULL;
586
587 result = PyTuple_New(2);
588 if (!result) {
589 return NULL;
590 }
591 as_tuple = StaticTuple_as_tuple(self);
592 if (as_tuple == NULL) {
593 Py_DECREF(result);
594 return NULL;
595 }
596 Py_INCREF(&StaticTuple_Type);
597 PyTuple_SET_ITEM(result, 0, (PyObject *)&StaticTuple_Type);
598 PyTuple_SET_ITEM(result, 1, as_tuple);
599 return result;
600}
601
602static char StaticTuple_reduce_doc[] = "__reduce__() => tuple\n";
603
604
605static PyObject *
606StaticTuple_add(PyObject *v, PyObject *w)
607{
608 Py_ssize_t i, len_v, len_w;
609 PyObject *item;
610 StaticTuple *result;
611 /* StaticTuples and plain tuples may be added (concatenated) to
612 * StaticTuples.
613 */
614 if (StaticTuple_CheckExact(v)) {
615 len_v = ((StaticTuple*)v)->size;
616 } else if (PyTuple_Check(v)) {
617 len_v = PyTuple_GET_SIZE(v);
618 } else {
619 Py_INCREF(Py_NotImplemented);
620 return Py_NotImplemented;
621 }
622 if (StaticTuple_CheckExact(w)) {
623 len_w = ((StaticTuple*)w)->size;
624 } else if (PyTuple_Check(w)) {
625 len_w = PyTuple_GET_SIZE(w);
626 } else {
627 Py_INCREF(Py_NotImplemented);
628 return Py_NotImplemented;
629 }
630 result = StaticTuple_New(len_v + len_w);
631 if (result == NULL)
632 return NULL;
633 for (i = 0; i < len_v; ++i) {
634 // This returns a new reference, which we then 'steal' with
635 // StaticTuple_SET_ITEM
636 item = PySequence_GetItem(v, i);
637 if (item == NULL) {
638 Py_DECREF(result);
639 return NULL;
640 }
641 StaticTuple_SET_ITEM(result, i, item);
642 }
643 for (i = 0; i < len_w; ++i) {
644 item = PySequence_GetItem(w, i);
645 if (item == NULL) {
646 Py_DECREF(result);
647 return NULL;
648 }
649 StaticTuple_SET_ITEM(result, i+len_v, item);
650 }
651 if (!StaticTuple_check_items(result)) {
652 Py_DECREF(result);
653 return NULL;
654 }
655 return (PyObject *)result;
656}
657
658static PyObject *
659StaticTuple_item(StaticTuple *self, Py_ssize_t offset)
660{
The diff has been truncated for viewing.