Gregory Szorc <gregory.szorc@gmail.com> [Wed, 13 Jul 2016 20:41:07 -0700] rev 29556
tests: use sslutil.wrapserversocket()
Like the built-in HTTPS server, this code was using the ssl module
directly and only using TLS 1.0. Like the built-in HTTPS server,
we switch it to use sslutil.wrapserversocket() so it can follow better
practices.
Gregory Szorc <gregory.szorc@gmail.com> [Tue, 12 Jul 2016 23:12:03 -0700] rev 29555
hgweb: use sslutil.wrapserversocket()
This patch transitions the built-in HTTPS server to use sslutil for
creating the server socket.
As part of this transition, we implement developer-only config options
to control CA loading and whether to require client certificates. This
eliminates the need for the custom extension in test-https.t to define
these.
There is a slight change in behavior with regards to protocol
selection. Before, we would always use the TLS 1.0 constant to define
the protocol version. This would *only* use TLS 1.0. sslutil defaults
to TLS 1.0+. So this patch improves the security of `hg serve` out of
the box by allowing it to use TLS 1.1 and 1.2 (if available).
Gregory Szorc <gregory.szorc@gmail.com> [Thu, 14 Jul 2016 20:14:19 -0700] rev 29554
sslutil: implement wrapserversocket()
wrapsocket() is heavily tailored towards client use. In preparation
for converting the built-in server to use sslutil (as opposed to
the ssl module directly), we add wrapserversocket() for wrapping
a socket to be used on servers.
Gregory Szorc <gregory.szorc@gmail.com> [Wed, 13 Jul 2016 00:14:50 -0700] rev 29553
hgweb: pass ui into preparehttpserver
Upcoming patches will need the built-in HTTPS server to be more
configurable.
Kostia Balytskyi <ikostia@fb.com> [Thu, 14 Jul 2016 03:12:09 -0700] rev 29552
rebase: remove sortedstate-related confusion
The following rebase implementation details are frustrating:
- storing a list of sorted revision numbers in a field named sortedstate
- having sortedstate be a field of the rebaseruntime class
- using sortedstate[-1] as opposed to a more intuitive max(self.state) to
compute the latest revision in the state
This commit fixes those imperfections.
Kostia Balytskyi <ikostia@fb.com> [Thu, 14 Jul 2016 02:59:27 -0700] rev 29551
rebase: replace extrafn field with _makeextrafn invocations
As per Yuya's advice, we would like to slightly reduce the amount of state
which is stored in rebaseruntime class. In this case, we don't need to store
extrafn field, as we can produce the necessary value by calling _makeextrafn
and the perf overhead is negligible.
Gregory Szorc <gregory.szorc@gmail.com> [Mon, 04 Jul 2016 11:18:03 -0700] rev 29550
mercurial: implement a source transforming module loader on Python 3
The most painful part of ensuring Python code runs on both Python 2
and 3 is string encoding. Making this difficult is that string
literals in Python 2 are bytes and string literals in Python 3 are
unicode. So, to ensure consistent types are used, you have to
use "from __future__ import unicode_literals" and/or prefix literals
with their type (e.g. b'foo' or u'foo').
Nearly every string in Mercurial is bytes. So, to use the same source
code on both Python 2 and 3 would require prefixing nearly every
string literal with "b" to make it a byte literal. This is ugly and
not something mpm is willing to do at this point in time.
This patch implements a custom module loader on Python 3 that performs
source transformation to convert string literals (unicode in Python 3)
to byte literals. In effect, it changes Python 3's string literals to
behave like Python 2's.
In addition, the module loader recognizes well-known built-in
functions (getattr, setattr, hasattr) and methods (encode and decode)
that barf when bytes are used and prevents these from being rewritten.
This prevents excessive source changes to accommodate this change
(we would have to rewrite every occurrence of these functions passing
string literals otherwise).
The module loader is only used on Python packages belonging to
Mercurial.
The loader works by tokenizing the loaded source and replacing
"string" tokens if necessary. The modified token stream is
untokenized back to source and loaded like normal. This does add some
overhead. However, this all occurs before caching: .pyc files will
cache the transformed version. This means the transformation penalty
is only paid on first load.
As the extensive inline comments explain, the presence of a custom
source transformer invalidates assumptions made by Python's built-in
bytecode caching mechanism. So, we have to wrap bytecode loading and
writing and add an additional header to bytecode files to facilitate
additional cache validation when the source transformations
change in the future.
There are still a few things this code doesn't handle well, namely
support for zip files as module sources and for extensions. Since
Mercurial doesn't officially support Python 3 yet, I'm inclined to
leave these as to-do items: getting a basic module loading mechanism
in place to unblock further Python 3 porting effort is more important
than comprehensive module importing support.
check-py3-compat.py has been updated to ignore frames. This is
necessary because CPython has built-in code to strip frames from the
built-in importer. When our custom code is present, this doesn't work
and the frames get all messed up. The new code is not perfect. It
works for now. But once you start chasing import failures you find
some edge cases where the files aren't being printed properly. This
only burdens people doing future Python 3 porting work so I'm inclined
to punt on the issue: the most important thing is for the source
transforming module loader to land.
There was a bit of churn in test-check-py3-compat.t because we now
trip up on str/unicode/bytes failures as a result of source
transformation. This is unfortunate but what are you going to do.
It's worth noting that other approaches were investigated.
We considered using a custom file encoding whose decode() would
apply source transformations. This was rejected because it would
require each source file to declare its custom Mercurial encoding.
Furthermore, when changing the source transformation we'd need to
version bump the encoding name otherwise the module caching layer
wouldn't know the .pyc file was invalidated. This would mean mass
updating every file when the source transformation changes. Yuck.
We also considered transforming at the AST layer. However, Python's
ast module is quite gnarly and doing AST transforms is quite
complicated, even for trivial rewrites. There are whole Python packages
that exist to make AST transformations usable. AST transforms would
still require import machinery, so the choice was basically to
perform source-level, token-level, or ast-level transforms.
Token-level rewriting delivers the metadata we need to rewrite
intelligently while being relatively easy to understand. So it won.
General consensus seems to be that this approach is the best available
to avoid bulk rewriting of '' to b''. However, we aren't confident
that this approach will never be a future maintenance burden. This
approach does unblock serious Python 3 porting efforts. So we can
re-evaulate once more work is done to support Python 3.
Yuya Nishihara <yuya@tcha.org> [Fri, 15 Jul 2016 23:54:56 +0900] rev 29549
compat: define ssize_t as int on 32bit Windows, silences C4142 warning
It appears Python.h provides ssize_t, which is aliased to int.
https://hg.python.org/cpython/file/v2.7.11/PC/pyconfig.h#l205
Yuya Nishihara <yuya@tcha.org> [Sun, 22 May 2016 13:45:09 +0900] rev 29548
commandserver: drop old unixservice implementation
It's been superseded by unixforkingservice.
Yuya Nishihara <yuya@tcha.org> [Sun, 22 May 2016 13:36:37 +0900] rev 29547
chgserver: switch to new forking service
Threading and complex classes are no longer necessary. _autoexitloop() has
been replaced by polling cycle in the main thread.