annotate tests/test-url.py @ 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 56b1f39dd0c1
children 4b0fc75f9403
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
15398
474279be5add tests: fix readline escape characters in heredoctest.py/test-url.py
Brodie Rao <brodie@bitheap.org>
parents: 15018
diff changeset
1 import os
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
2
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
3 def check(a, b):
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
4 if a != b:
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
5 print (a, b)
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
6
12606
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
7 def cert(cn):
20685
56b1f39dd0c1 test-url: move from dict() construction to {} literals
Augie Fackler <raf@durin42.com>
parents: 15611
diff changeset
8 return {'subject': ((('commonName', cn),),)}
12606
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
9
14204
5fa21960b2f4 sslutil: extracted ssl methods from httpsconnection in url.py
Augie Fackler <durin42@gmail.com>
parents: 14076
diff changeset
10 from mercurial.sslutil import _verifycert
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
11
12724
66e7ba85585b test-url: remove trailing whitespace
Augie Fackler <durin42@gmail.com>
parents: 12606
diff changeset
12 # Test non-wildcard certificates
12606
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
13 check(_verifycert(cert('example.com'), 'example.com'),
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
14 None)
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
15 check(_verifycert(cert('example.com'), 'www.example.com'),
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
16 'certificate is for example.com')
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
17 check(_verifycert(cert('www.example.com'), 'example.com'),
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
18 'certificate is for www.example.com')
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
19
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
20 # Test wildcard certificates
12606
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
21 check(_verifycert(cert('*.example.com'), 'www.example.com'),
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
22 None)
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
23 check(_verifycert(cert('*.example.com'), 'example.com'),
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
24 'certificate is for *.example.com')
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
25 check(_verifycert(cert('*.example.com'), 'w.w.example.com'),
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
26 'certificate is for *.example.com')
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
27
13249
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
28 # Test subjectAltName
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
29 san_cert = {'subject': ((('commonName', 'example.com'),),),
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
30 'subjectAltName': (('DNS', '*.example.net'),
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
31 ('DNS', 'example.net'))}
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
32 check(_verifycert(san_cert, 'example.net'),
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
33 None)
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
34 check(_verifycert(san_cert, 'foo.example.net'),
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
35 None)
14666
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
36 # no fallback to subject commonName when subjectAltName has DNS
13249
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
37 check(_verifycert(san_cert, 'example.com'),
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
38 'certificate is for *.example.net, example.net')
14666
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
39 # fallback to subject commonName when no DNS in subjectAltName
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
40 san_cert = {'subject': ((('commonName', 'example.com'),),),
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
41 'subjectAltName': (('IP Address', '8.8.8.8'),)}
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
42 check(_verifycert(san_cert, 'example.com'), None)
13249
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
43
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
44 # Avoid some pitfalls
12606
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
45 check(_verifycert(cert('*.foo'), 'foo'),
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
46 'certificate is for *.foo')
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
47 check(_verifycert(cert('*o'), 'foo'),
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
48 'certificate is for *o')
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
49
12742
6ab4a7d3c179 url: validity (notBefore/notAfter) is checked by OpenSSL (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents: 12738
diff changeset
50 check(_verifycert({'subject': ()},
12606
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
51 'example.com'),
13249
75d0c38a0bca url: check subjectAltName when verifying ssl certificate
Yuya Nishihara <yuya@tcha.org>
parents: 13248
diff changeset
52 'no commonName or subjectAltName found in certificate')
12592
f2937d6492c5 url: verify correctness of https server certificates (issue2407)
Mads Kiilerich <mads@kiilerich.com>
parents:
diff changeset
53 check(_verifycert(None, 'example.com'),
12606
5c8353692123 test-url: refactor with shorter lines
Martin Geisler <mg@aragost.com>
parents: 12592
diff changeset
54 'no certificate received')
13248
00411a4fa1bb url: fix UnicodeDecodeError on certificate verification error
Yuya Nishihara <yuya@tcha.org>
parents: 12865
diff changeset
55
14666
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
56 # Unicode (IDN) certname isn't supported
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
57 check(_verifycert(cert(u'\u4f8b.jp'), 'example.jp'),
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
58 'IDN in certificate not supported')
27b080aa880a sslutil: fall back to commonName when no dNSName in subjectAltName (issue2798)
Nicolas Bareil <nico@chdir.org>
parents: 14313
diff changeset
59
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
60 import doctest
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
61
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
62 def test_url():
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
63 """
14076
924c82157d46 url: move URL parsing functions into util to improve startup time
Brodie Rao <brodie@bitheap.org>
parents: 13848
diff changeset
64 >>> from mercurial.util import url
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
65
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
66 This tests for edge cases in url.URL's parsing algorithm. Most of
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
67 these aren't useful for documentation purposes, so they aren't
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
68 part of the class's doc tests.
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
69
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
70 Query strings and fragments:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
71
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
72 >>> url('http://host/a?b#c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
73 <url scheme: 'http', host: 'host', path: 'a', query: 'b', fragment: 'c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
74 >>> url('http://host/a?')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
75 <url scheme: 'http', host: 'host', path: 'a'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
76 >>> url('http://host/a#b#c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
77 <url scheme: 'http', host: 'host', path: 'a', fragment: 'b#c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
78 >>> url('http://host/a#b?c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
79 <url scheme: 'http', host: 'host', path: 'a', fragment: 'b?c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
80 >>> url('http://host/?a#b')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
81 <url scheme: 'http', host: 'host', path: '', query: 'a', fragment: 'b'>
13827
f1823b9f073b url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents: 13817
diff changeset
82 >>> url('http://host/?a#b', parsequery=False)
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
83 <url scheme: 'http', host: 'host', path: '?a', fragment: 'b'>
13827
f1823b9f073b url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents: 13817
diff changeset
84 >>> url('http://host/?a#b', parsefragment=False)
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
85 <url scheme: 'http', host: 'host', path: '', query: 'a#b'>
13827
f1823b9f073b url: nuke some newly-introduced underbars in identifiers
Matt Mackall <mpm@selenic.com>
parents: 13817
diff changeset
86 >>> url('http://host/?a#b', parsequery=False, parsefragment=False)
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
87 <url scheme: 'http', host: 'host', path: '?a#b'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
88
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
89 IPv6 addresses:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
90
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
91 >>> url('ldap://[2001:db8::7]/c=GB?objectClass?one')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
92 <url scheme: 'ldap', host: '[2001:db8::7]', path: 'c=GB',
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
93 query: 'objectClass?one'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
94 >>> url('ldap://joe:xxx@[2001:db8::7]:80/c=GB?objectClass?one')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
95 <url scheme: 'ldap', user: 'joe', passwd: 'xxx', host: '[2001:db8::7]',
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
96 port: '80', path: 'c=GB', query: 'objectClass?one'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
97
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
98 Missing scheme, host, etc.:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
99
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
100 >>> url('://192.0.2.16:80/')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
101 <url path: '://192.0.2.16:80/'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
102 >>> url('http://mercurial.selenic.com')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
103 <url scheme: 'http', host: 'mercurial.selenic.com'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
104 >>> url('/foo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
105 <url path: '/foo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
106 >>> url('bundle:/foo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
107 <url scheme: 'bundle', path: '/foo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
108 >>> url('a?b#c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
109 <url path: 'a?b', fragment: 'c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
110 >>> url('http://x.com?arg=/foo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
111 <url scheme: 'http', host: 'x.com', query: 'arg=/foo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
112 >>> url('http://joe:xxx@/foo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
113 <url scheme: 'http', user: 'joe', passwd: 'xxx', path: 'foo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
114
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
115 Just a scheme and a path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
116
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
117 >>> url('mailto:John.Doe@example.com')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
118 <url scheme: 'mailto', path: 'John.Doe@example.com'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
119 >>> url('a:b:c:d')
13808
58b86b9149f1 url: fix tests
Matt Mackall <mpm@selenic.com>
parents: 13770
diff changeset
120 <url path: 'a:b:c:d'>
58b86b9149f1 url: fix tests
Matt Mackall <mpm@selenic.com>
parents: 13770
diff changeset
121 >>> url('aa:bb:cc:dd')
58b86b9149f1 url: fix tests
Matt Mackall <mpm@selenic.com>
parents: 13770
diff changeset
122 <url scheme: 'aa', path: 'bb:cc:dd'>
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
123
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
124 SSH examples:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
125
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
126 >>> url('ssh://joe@host//home/joe')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
127 <url scheme: 'ssh', user: 'joe', host: 'host', path: '/home/joe'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
128 >>> url('ssh://joe:xxx@host/src')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
129 <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', path: 'src'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
130 >>> url('ssh://joe:xxx@host')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
131 <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
132 >>> url('ssh://joe@host')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
133 <url scheme: 'ssh', user: 'joe', host: 'host'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
134 >>> url('ssh://host')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
135 <url scheme: 'ssh', host: 'host'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
136 >>> url('ssh://')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
137 <url scheme: 'ssh'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
138 >>> url('ssh:')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
139 <url scheme: 'ssh'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
140
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
141 Non-numeric port:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
142
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
143 >>> url('http://example.com:dd')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
144 <url scheme: 'http', host: 'example.com', port: 'dd'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
145 >>> url('ssh://joe:xxx@host:ssh/foo')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
146 <url scheme: 'ssh', user: 'joe', passwd: 'xxx', host: 'host', port: 'ssh',
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
147 path: 'foo'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
148
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
149 Bad authentication credentials:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
150
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
151 >>> url('http://joe@joeville:123@4:@host/a?b#c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
152 <url scheme: 'http', user: 'joe@joeville', passwd: '123@4:',
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
153 host: 'host', path: 'a', query: 'b', fragment: 'c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
154 >>> url('http://!*#?/@!*#?/:@host/a?b#c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
155 <url scheme: 'http', host: '!*', fragment: '?/@!*#?/:@host/a?b#c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
156 >>> url('http://!*#?@!*#?:@host/a?b#c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
157 <url scheme: 'http', host: '!*', fragment: '?@!*#?:@host/a?b#c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
158 >>> url('http://!*@:!*@@host/a?b#c')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
159 <url scheme: 'http', user: '!*@', passwd: '!*@', host: 'host',
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
160 path: 'a', query: 'b', fragment: 'c'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
161
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
162 File paths:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
163
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
164 >>> url('a/b/c/d.g.f')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
165 <url path: 'a/b/c/d.g.f'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
166 >>> url('/x///z/y/')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
167 <url path: '/x///z/y/'>
13848
b2798c1defff url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
168 >>> url('/foo:bar')
b2798c1defff url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
169 <url path: '/foo:bar'>
b2798c1defff url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
170 >>> url('\\\\foo:bar')
b2798c1defff url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
171 <url path: '\\\\foo:bar'>
b2798c1defff url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
172 >>> url('./foo:bar')
b2798c1defff url: be stricter about detecting schemes
Brodie Rao <brodie@bitheap.org>
parents: 13827
diff changeset
173 <url path: './foo:bar'>
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
174
13817
7f18bab2c0b0 url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents: 13808
diff changeset
175 Non-localhost file URL:
7f18bab2c0b0 url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents: 13808
diff changeset
176
7f18bab2c0b0 url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents: 13808
diff changeset
177 >>> u = url('file://mercurial.selenic.com/foo')
7f18bab2c0b0 url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents: 13808
diff changeset
178 Traceback (most recent call last):
7f18bab2c0b0 url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents: 13808
diff changeset
179 File "<stdin>", line 1, in ?
7f18bab2c0b0 url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents: 13808
diff changeset
180 Abort: file:// URLs can only refer to localhost
7f18bab2c0b0 url: abort on file:// URLs with non-localhost hosts
Brodie Rao <brodie@bitheap.org>
parents: 13808
diff changeset
181
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
182 Empty URL:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
183
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
184 >>> u = url('')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
185 >>> u
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
186 <url path: ''>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
187 >>> str(u)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
188 ''
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
189
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
190 Empty path with query string:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
191
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
192 >>> str(url('http://foo/?bar'))
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
193 'http://foo/?bar'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
194
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
195 Invalid path:
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
196
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
197 >>> u = url('http://foo/bar')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
198 >>> u.path = 'bar'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
199 >>> str(u)
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
200 'http://foo/bar'
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
201
14313
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
202 >>> u = url('file:/foo/bar/baz')
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
203 >>> u
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
204 <url scheme: 'file', path: '/foo/bar/baz'>
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
205 >>> str(u)
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
206 'file:///foo/bar/baz'
15018
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
207 >>> u.localpath()
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
208 '/foo/bar/baz'
14313
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
209
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
210 >>> u = url('file:///foo/bar/baz')
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
211 >>> u
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
212 <url scheme: 'file', path: '/foo/bar/baz'>
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
213 >>> str(u)
14313
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
214 'file:///foo/bar/baz'
15018
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
215 >>> u.localpath()
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
216 '/foo/bar/baz'
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
217
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
218 >>> u = url('file:///f:oo/bar/baz')
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
219 >>> u
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
220 <url scheme: 'file', path: 'f:oo/bar/baz'>
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
221 >>> str(u)
15611
ec8a49c46d7e merge with stable
Matt Mackall <mpm@selenic.com>
parents: 15513 15609
diff changeset
222 'file:///f:oo/bar/baz'
15018
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
223 >>> u.localpath()
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
224 'f:oo/bar/baz'
14313
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
225
15496
396e83d635a6 url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents: 15398
diff changeset
226 >>> u = url('file://localhost/f:oo/bar/baz')
396e83d635a6 url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents: 15398
diff changeset
227 >>> u
396e83d635a6 url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents: 15398
diff changeset
228 <url scheme: 'file', host: 'localhost', path: 'f:oo/bar/baz'>
396e83d635a6 url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents: 15398
diff changeset
229 >>> str(u)
15513
646759147717 merge with stable
Matt Mackall <mpm@selenic.com>
parents: 15452 15496
diff changeset
230 'file://localhost/f:oo/bar/baz'
15496
396e83d635a6 url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents: 15398
diff changeset
231 >>> u.localpath()
396e83d635a6 url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents: 15398
diff changeset
232 'f:oo/bar/baz'
396e83d635a6 url: handle file://localhost/c:/foo "correctly"
Mads Kiilerich <mads@kiilerich.com>
parents: 15398
diff changeset
233
14313
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
234 >>> u = url('file:foo/bar/baz')
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
235 >>> u
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
236 <url scheme: 'file', path: 'foo/bar/baz'>
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
237 >>> str(u)
a389dd285282 util: make str(url) return file:/// for abs paths again
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14204
diff changeset
238 'file:foo/bar/baz'
15018
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
239 >>> u.localpath()
e89f62dcd723 url: really handle urls of the form file:///c:/foo/bar/ correctly
Mads Kiilerich <mads@kiilerich.com>
parents: 14666
diff changeset
240 'foo/bar/baz'
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
241 """
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
242
15398
474279be5add tests: fix readline escape characters in heredoctest.py/test-url.py
Brodie Rao <brodie@bitheap.org>
parents: 15018
diff changeset
243 if 'TERM' in os.environ:
474279be5add tests: fix readline escape characters in heredoctest.py/test-url.py
Brodie Rao <brodie@bitheap.org>
parents: 15018
diff changeset
244 del os.environ['TERM']
474279be5add tests: fix readline escape characters in heredoctest.py/test-url.py
Brodie Rao <brodie@bitheap.org>
parents: 15018
diff changeset
245
13770
4e8f2310f310 url: provide url object
Brodie Rao <brodie@bitheap.org>
parents: 13249
diff changeset
246 doctest.testmod(optionflags=doctest.NORMALIZE_WHITESPACE)