view tests/test-commandserver.py.out @ 20742:3681de20b0a7

parsers: fail fast if Python has wrong minor version (issue4110) This change causes an informative ImportError to be raised when importing the parsers extension module if the minor version of the currently-running Python interpreter doesn't match that of the Python used when compiling the extension module. This change also exposes a parsers.versionerrortext constant in the C implementation of the module. Its presence can be used to determine whether this behavior is present in a version of the module. The value of the constant is the leading text of the ImportError raised and is set to "Python minor version mismatch". Here is an example of what the new error looks like: Traceback (most recent call last): File "test.py", line 1, in <module> import mercurial.parsers ImportError: Python minor version mismatch: The Mercurial extension modules were compiled with Python 2.7.6, but Mercurial is currently using Python with sys.hexversion=33883888: Python 2.5.6 (r256:88840, Nov 18 2012, 05:37:10) [GCC 4.2.1 Compatible Apple Clang 4.1 ((tags/Apple/clang-421.11.66))] at: /opt/local/Library/Frameworks/Python.framework/Versions/2.5/Resources/ Python.app/Contents/MacOS/Python The reason for raising an error in this scenario is that Python's C API is known not to be compatible from minor version to minor version, even if sys.api_version is the same. See for example this Python bug report about incompatibilities between 2.5 and 2.6+: http://bugs.python.org/issue8118 These incompatibilities can cause Mercurial to break in mysterious, unforeseen ways. For example, when Mercurial compiled with Python 2.7 was run with 2.5, the following crash occurred when running "hg status": http://bz.selenic.com/show_bug.cgi?id=4110 After this crash was fixed, running with Python 2.5 no longer crashes, but the following puzzling behavior still occurs: $ hg status ... File ".../mercurial/changelog.py", line 123, in __init__ revlog.revlog.__init__(self, opener, "00changelog.i") File ".../mercurial/revlog.py", line 251, in __init__ d = self._io.parseindex(i, self._inline) File ".../mercurial/revlog.py", line 158, in parseindex index, cache = parsers.parse_index2(data, inline) TypeError: data is not a string which can be reproduced more simply with: import mercurial.parsers as parsers parsers.parse_index2("", True) Both the crash and the TypeError occurred because the Python C API's PyString_Check() returns the wrong value when the C header files from Python 2.7 are run with Python 2.5. This is an example of an incompatibility of the sort mentioned in the Python bug report above. Failing fast with an informative error message results in a better user experience in cases like the above. The information in the ImportError also simplifies troubleshooting for those on Mercurial mailing lists, the bug tracker, etc. This patch only adds the version check to parsers.c, which is sufficient to affect command-line commands like "hg status" and "hg summary". An idea for a future improvement is to move the version-checking C code to a more central location, and have it run when importing all Mercurial extension modules and not just parsers.c.
author Chris Jerdonek <chris.jerdonek@gmail.com>
date Wed, 04 Dec 2013 20:38:27 -0800
parents e811b93f2cb1
children 9336bc7dca8e
line wrap: on
line source


testing hellomessage:

o, 'capabilities: getencoding runcommand\nencoding: ***'
 runcommand id
000000000000 tip

testing unknowncommand:

abort: unknown command unknowncommand

testing checkruncommand:

 runcommand 
Mercurial Distributed SCM

basic commands:

 add           add the specified files on the next commit
 annotate      show changeset information by line for each file
 clone         make a copy of an existing repository
 commit        commit the specified files or all outstanding changes
 diff          diff repository (or selected files)
 export        dump the header and diffs for one or more changesets
 forget        forget the specified files on the next commit
 init          create a new repository in the given directory
 log           show revision history of entire repository or files
 merge         merge working directory with another revision
 pull          pull changes from the specified source
 push          push changes to the specified destination
 remove        remove the specified files on the next commit
 serve         start stand-alone webserver
 status        show changed files in the working directory
 summary       summarize working directory state
 update        update working directory (or switch revisions)

use "hg help" for the full list of commands or "hg -v" for details
 runcommand id --quiet
000000000000
 runcommand id
000000000000 tip
 runcommand id --config ui.quiet=True
000000000000
 runcommand id
000000000000 tip
 runcommand id -runknown
abort: unknown revision 'unknown'!
 [255]

testing inputeof:

server exit code = 1

testing serverinput:

 runcommand import -
applying patch from stdin
 runcommand log
changeset:   0:eff892de26ec
tag:         tip
user:        test
date:        Thu Jan 01 00:00:00 1970 +0000
summary:     1


testing cwd:

 runcommand --cwd foo st bar
? bar
 runcommand st foo/bar
? foo/bar

testing localhgrc:

 runcommand showconfig
bundle.mainreporoot=$TESTTMP/repo
defaults.backout=-d "0 0"
defaults.commit=-d "0 0"
defaults.shelve=--date "0 0"
defaults.tag=-d "0 0"
ui.slash=True
ui.interactive=False
ui.foo=bar
 runcommand init foo
 runcommand -R foo showconfig ui defaults
defaults.backout=-d "0 0"
defaults.commit=-d "0 0"
defaults.shelve=--date "0 0"
defaults.tag=-d "0 0"
ui.slash=True
ui.interactive=False

testing hookoutput:

 runcommand --config hooks.pre-identify=python:test-commandserver.hook id
hook talking
now try to read something: 'some input'
eff892de26ec tip

testing outsidechanges:

 runcommand status
M a
 runcommand tip
changeset:   1:d3a0a68be6de
tag:         tip
user:        test
date:        Thu Jan 01 00:00:00 1970 +0000
summary:     2

 runcommand status

testing bookmarks:

 runcommand bookmarks
no bookmarks set
 runcommand bookmarks
   bm1                       1:d3a0a68be6de
   bm2                       1:d3a0a68be6de
 runcommand bookmarks
 * bm1                       1:d3a0a68be6de
   bm2                       1:d3a0a68be6de
 runcommand bookmarks bm3
 runcommand commit -Amm
 runcommand bookmarks
   bm1                       1:d3a0a68be6de
   bm2                       1:d3a0a68be6de
 * bm3                       2:aef17e88f5f0

testing tagscache:

 runcommand id -t -r 0

 runcommand id -t -r 0
foo

testing setphase:

 runcommand phase -r .
3: draft
 runcommand phase -r .
3: public

testing rollback:

 runcommand phase -r . -p
no phases changed
 [1]
 runcommand commit -Am.
 runcommand rollback
repository tip rolled back to revision 3 (undo commit)
working directory now based on revision 3
 runcommand phase -r .
3: public

testing branch:

 runcommand branch
default
marked working directory as branch foo
(branches are permanent and global, did you want a bookmark?)
 runcommand branch
foo
marked working directory as branch default
(branches are permanent and global, did you want a bookmark?)

testing hgignore:

 runcommand commit -Am.
adding .hgignore
 runcommand status -i -u
I ignored-file

testing phasecacheafterstrip:

 runcommand update -C 0
1 files updated, 0 files merged, 2 files removed, 0 files unresolved
 runcommand commit -Am. a
created new head
 runcommand log -Gq
@  5:731265503d86
|
| o  4:7966c8e3734d
| |
| o  3:b9b85890c400
| |
| o  2:aef17e88f5f0
| |
| o  1:d3a0a68be6de
|/
o  0:eff892de26ec

 runcommand phase -p .
 runcommand phase .
5: public
 runcommand branches
default                        1:731265503d86

testing obsolete:

 runcommand up null
0 files updated, 0 files merged, 1 files removed, 0 files unresolved
 runcommand phase -df tip
 runcommand log --hidden
changeset:   1:731265503d86
tag:         tip
user:        test
date:        Thu Jan 01 00:00:00 1970 +0000
summary:     .

changeset:   0:eff892de26ec
bookmark:    bm1
bookmark:    bm2
bookmark:    bm3
user:        test
date:        Thu Jan 01 00:00:00 1970 +0000
summary:     1

 runcommand log
changeset:   0:eff892de26ec
bookmark:    bm1
bookmark:    bm2
bookmark:    bm3
tag:         tip
user:        test
date:        Thu Jan 01 00:00:00 1970 +0000
summary:     1


testing mqoutsidechanges:

 runcommand qapplied
 runcommand qapplied
0.diff
 runcommand qpop --all
popping 0.diff
patch queue now empty
 runcommand qqueue --active
foo

testing hellomessage:

o, 'capabilities: getencoding runcommand\nencoding: ***'
 runcommand id
abort: there is no Mercurial repository here (.hg not found)
 [255]

testing startwithoutrepo:

 runcommand init repo2
 runcommand id -R repo2
000000000000 tip