Commit 8e204f73 authored by Pulkit Goyal's avatar Pulkit Goyal

merge default into stable for 5.4 release

--HG--
branch : stable
Pipeline #5150 passed with stage
in 39 minutes and 56 seconds
......@@ -64,6 +64,7 @@ doc:
$(MAKE) -C doc
cleanbutpackages:
rm -f hg.exe
-$(PYTHON) setup.py clean --all # ignore errors from this command
find contrib doc hgext hgext3rd i18n mercurial tests hgdemandimport \
\( -name '*.py[cdo]' -o -name '*.so' \) -exec rm -f '{}' ';'
......
......@@ -9,7 +9,6 @@ build/
| \.mypy_cache/
| \.venv/
| mercurial/thirdparty/
| contrib/python-zstandard/
'''
skip-string-normalization = true
quiet = true
......@@ -81,7 +81,7 @@ def runperfcommand(reponame, command, *args, **kwargs):
output = ui.popbuffer()
match = outputre.search(output)
if not match:
raise ValueError("Invalid output {0}".format(output))
raise ValueError("Invalid output {}".format(output))
return float(match.group(1))
......
......@@ -32,7 +32,7 @@ def check_compat_py2(f):
for node in ast.walk(root):
if isinstance(node, ast.ImportFrom):
if node.module == '__future__':
futures |= set(n.name for n in node.names)
futures |= {n.name for n in node.names}
elif isinstance(node, ast.Print):
haveprint = True
......
......@@ -226,6 +226,16 @@ static void execcmdserver(const struct cmdserveropts *opts)
}
argv[argsize - 1] = NULL;
const char *lc_ctype_env = getenv("LC_CTYPE");
if (lc_ctype_env == NULL) {
if (putenv("CHG_CLEAR_LC_CTYPE=") != 0)
abortmsgerrno("failed to putenv CHG_CLEAR_LC_CTYPE");
} else {
if (setenv("CHGORIG_LC_CTYPE", lc_ctype_env, 1) != 0) {
abortmsgerrno("failed to setenv CHGORIG_LC_CTYYPE");
}
}
if (putenv("CHGINTERNALMARK=") != 0)
abortmsgerrno("failed to putenv");
if (execvp(hgcmd, (char **)argv) < 0)
......@@ -364,8 +374,7 @@ static int runinstructions(struct cmdserveropts *opts, const char **insts)
/*
* Test whether the command is unsupported or not. This is not designed to
* cover all cases. But it's fast, does not depend on the server and does
* not return false positives.
* cover all cases. But it's fast, does not depend on the server.
*/
static int isunsupported(int argc, const char *argv[])
{
......@@ -378,7 +387,12 @@ static int isunsupported(int argc, const char *argv[])
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--") == 0)
break;
if (i == 0 && strcmp("serve", argv[i]) == 0)
/*
* there can be false positives but no false negative
* we cannot assume `serve` will always be first argument
* because global options can be passed before the command name
*/
if (strcmp("serve", argv[i]) == 0)
state |= SERVE;
else if (strcmp("-d", argv[i]) == 0 ||
strcmp("--daemon", argv[i]) == 0)
......
......@@ -6,7 +6,7 @@ rustfmt:command = rustfmt +nightly
rustfmt:pattern = set:**.rs
black:command = black --config=black.toml -
black:pattern = set:**.py - mercurial/thirdparty/** - "contrib/python-zstandard/**"
black:pattern = set:**.py - mercurial/thirdparty/**
# Mercurial doesn't have any Go code, but if we did this is how we
# would configure `hg fix` for Go:
......
......@@ -42,13 +42,13 @@ rust-cargo-test-py3:
test-py2:
<<: *runtests
variables:
RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
RUNTEST_ARGS: " --no-rust --blacklist /tmp/check-tests.txt"
TEST_HGMODULEPOLICY: "c"
test-py3:
<<: *runtests
variables:
RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
RUNTEST_ARGS: " --no-rust --blacklist /tmp/check-tests.txt"
PYTHON: python3
TEST_HGMODULEPOLICY: "c"
......@@ -69,13 +69,13 @@ test-py2-rust:
<<: *runtests
variables:
HGWITHRUSTEXT: cpython
RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
RUNTEST_ARGS: "--rust --blacklist /tmp/check-tests.txt"
TEST_HGMODULEPOLICY: "rust+c"
test-py3-rust:
<<: *runtests
variables:
HGWITHRUSTEXT: cpython
RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt"
RUNTEST_ARGS: "--rust --blacklist /tmp/check-tests.txt"
PYTHON: python3
TEST_HGMODULEPOLICY: "rust+c"
......@@ -392,9 +392,10 @@ def imported_modules(source, modulename, f, localmods, ignore_nested=False):
modnotfound = True
continue
yield found[1]
if modnotfound:
if modnotfound and dottedpath != modulename:
# "dottedpath" is a package, but imported because of non-module
# lookup
# specifically allow "from . import foo" from __init__.py
yield dottedpath
......
# Instructions:
#
# 1. cargo install --version 0.5.0 pyoxidizer
# 2. cd /path/to/hg
# 3. pyoxidizer build --path contrib/packaging [--release]
# 4. Run build/pyoxidizer/<arch>/<debug|release>/app/hg
#
# If you need to build again, you need to remove the build/lib.* and
# build/temp.* directories, otherwise PyOxidizer fails to pick up C
# extensions. This is a bug in PyOxidizer.
ROOT = CWD + "/../.."
set_build_path(ROOT + "/build/pyoxidizer")
def make_exe():
dist = default_python_distribution()
code = "import hgdemandimport; hgdemandimport.enable(); from mercurial import dispatch; dispatch.run()"
config = PythonInterpreterConfig(
raw_allocator = "system",
run_eval = code,
# We want to let the user load extensions from the file system
filesystem_importer = True,
# We need this to make resourceutil happy, since it looks for sys.frozen.
sys_frozen = True,
legacy_windows_stdio = True,
)
exe = dist.to_python_executable(
name = "hg",
config = config,
)
# Use setup.py install to build Mercurial and collect Python resources to
# embed in the executable.
resources = dist.setup_py_install(ROOT)
exe.add_python_resources(resources)
return exe
def make_install(exe):
m = FileManifest()
# `hg` goes in root directory.
m.add_python_resource(".", exe)
templates = glob(
include=[ROOT + "/mercurial/templates/**/*"],
strip_prefix = ROOT + "/mercurial/",
)
m.add_manifest(templates)
return m
register_target("exe", make_exe)
register_target("app", make_install, depends = ["exe"], default = True)
resolve_targets()
......@@ -1536,6 +1536,7 @@ def perfindex(ui, repo, **opts):
matters.
Example of useful set to test:
* tip
* 0
* -10:
......@@ -2522,7 +2523,7 @@ def perfdiffwd(ui, repo, **opts):
}
for diffopt in ('', 'w', 'b', 'B', 'wB'):
opts = dict((options[c], b'1') for c in diffopt)
opts = {options[c]: b'1' for c in diffopt}
def d():
ui.pushbuffer()
......@@ -3047,7 +3048,7 @@ def perfrevlogchunks(ui, repo, file_=None, engines=None, startrev=0, **opts):
# Verify engines argument.
if engines:
engines = set(e.strip() for e in engines.split(b','))
engines = {e.strip() for e in engines.split(b',')}
for engine in engines:
try:
util.compressionengines[engine]
......
#!/usr/bin/env python
#
# A small script to automatically reject idle Diffs
#
# you need to set the PHABBOT_USER and PHABBOT_TOKEN environment variable for authentication
from __future__ import absolute_import, print_function
import datetime
import os
import sys
import phabricator
MESSAGE = """There seems to have been no activities on this Diff for the past 3 Months.
By policy, we are automatically moving it out of the `need-review` state.
Please, move it back to `need-review` without hesitation if this diff should still be discussed.
:baymax:need-review-idle:
"""
PHAB_URL = "https://phab.mercurial-scm.org/api/"
USER = os.environ.get("PHABBOT_USER", "baymax")
TOKEN = os.environ.get("PHABBOT_TOKEN")
NOW = datetime.datetime.now()
# 3 months in seconds
DELAY = 60 * 60 * 24 * 30 * 3
def get_all_diff(phab):
"""Fetch all the diff that the need review"""
return phab.differential.query(
status="status-needs-review",
order="order-modified",
paths=[('HG', None)],
)
def filter_diffs(diffs, older_than):
"""filter diffs to only keep the one unmodified sin <older_than> seconds"""
olds = []
for d in diffs:
modified = int(d['dateModified'])
modified = datetime.datetime.fromtimestamp(modified)
d["idleFor"] = idle_for = NOW - modified
if idle_for.total_seconds() > older_than:
olds.append(d)
return olds
def nudge_diff(phab, diff):
"""Comment on the idle diff and reject it"""
diff_id = int(d['id'])
phab.differential.createcomment(
revision_id=diff_id, message=MESSAGE, action="reject"
)
if not USER:
print(
"not user specified please set PHABBOT_USER and PHABBOT_TOKEN",
file=sys.stderr,
)
elif not TOKEN:
print(
"not api-token specified please set PHABBOT_USER and PHABBOT_TOKEN",
file=sys.stderr,
)
sys.exit(1)
phab = phabricator.Phabricator(USER, host=PHAB_URL, token=TOKEN)
phab.connect()
phab.update_interfaces()
print('Hello "%s".' % phab.user.whoami()['realName'])
diffs = get_all_diff(phab)
print("Found %d Diffs" % len(diffs))
olds = filter_diffs(diffs, DELAY)
print("Found %d old Diffs" % len(olds))
for d in olds:
diff_id = d['id']
status = d['statusName']
modified = int(d['dateModified'])
idle_for = d["idleFor"]
msg = 'nudging D%s in "%s" state for %s'
print(msg % (diff_id, status, idle_for))
# uncomment to actually affect phab
nudge_diff(phab, d)
......@@ -52,7 +52,8 @@ SOURCES = [
# Headers whose preprocessed output will be fed into cdef().
HEADERS = [
os.path.join(HERE, "zstd", *p) for p in (("zstd.h",), ("dictBuilder", "zdict.h"),)
os.path.join(HERE, "zstd", *p)
for p in (("zstd.h",), ("dictBuilder", "zdict.h"),)
]
INCLUDE_DIRS = [
......@@ -139,7 +140,9 @@ def preprocess(path):
env = dict(os.environ)
if getattr(compiler, "_paths", None):
env["PATH"] = compiler._paths
process = subprocess.Popen(args + [input_file], stdout=subprocess.PIPE, env=env)
process = subprocess.Popen(
args + [input_file], stdout=subprocess.PIPE, env=env
)
output = process.communicate()[0]
ret = process.poll()
if ret:
......
......@@ -87,7 +87,9 @@ with open("c-ext/python-zstandard.h", "r") as fh:
break
if not version:
raise Exception("could not resolve package version; " "this should never happen")
raise Exception(
"could not resolve package version; " "this should never happen"
)
setup(
name="zstandard",
......
......@@ -138,12 +138,16 @@ def get_c_extension(
if not system_zstd:
sources.update([os.path.join(actual_root, p) for p in zstd_sources])
if support_legacy:
sources.update([os.path.join(actual_root, p) for p in zstd_sources_legacy])
sources.update(
[os.path.join(actual_root, p) for p in zstd_sources_legacy]
)
sources = list(sources)
include_dirs = set([os.path.join(actual_root, d) for d in ext_includes])
if not system_zstd:
include_dirs.update([os.path.join(actual_root, d) for d in zstd_includes])
include_dirs.update(
[os.path.join(actual_root, d) for d in zstd_includes]
)
if support_legacy:
include_dirs.update(
[os.path.join(actual_root, d) for d in zstd_includes_legacy]
......
......@@ -50,7 +50,9 @@ def make_cffi(cls):
os.environ.update(old_env)
if mod.backend != "cffi":
raise Exception("got the zstandard %s backend instead of cffi" % mod.backend)
raise Exception(
"got the zstandard %s backend instead of cffi" % mod.backend
)
# If CFFI version is available, dynamically construct test methods
# that use it.
......@@ -84,7 +86,9 @@ def make_cffi(cls):
fn.__func__.func_defaults,
fn.__func__.func_closure,
)
new_method = types.UnboundMethodType(new_fn, fn.im_self, fn.im_class)
new_method = types.UnboundMethodType(
new_fn, fn.im_self, fn.im_class
)
setattr(cls, name, new_method)
......@@ -194,4 +198,6 @@ if hypothesis:
expensive_settings = hypothesis.settings(deadline=None, max_examples=10000)
hypothesis.settings.register_profile("expensive", expensive_settings)
hypothesis.settings.load_profile(os.environ.get("HYPOTHESIS_PROFILE", "default"))
hypothesis.settings.load_profile(
os.environ.get("HYPOTHESIS_PROFILE", "default")
)
......@@ -67,7 +67,8 @@ class TestBufferWithSegments(TestCase):
self.skipTest("BufferWithSegments not available")
b = zstd.BufferWithSegments(
b"foofooxfooxy", b"".join([ss.pack(0, 3), ss.pack(3, 4), ss.pack(7, 5)])
b"foofooxfooxy",
b"".join([ss.pack(0, 3), ss.pack(3, 4), ss.pack(7, 5)]),
)
self.assertEqual(len(b), 3)
self.assertEqual(b.size, 12)
......@@ -83,17 +84,23 @@ class TestBufferWithSegmentsCollection(TestCase):
if not hasattr(zstd, "BufferWithSegmentsCollection"):
self.skipTest("BufferWithSegmentsCollection not available")
with self.assertRaisesRegex(ValueError, "must pass at least 1 argument"):
with self.assertRaisesRegex(
ValueError, "must pass at least 1 argument"
):
zstd.BufferWithSegmentsCollection()
def test_argument_validation(self):
if not hasattr(zstd, "BufferWithSegmentsCollection"):
self.skipTest("BufferWithSegmentsCollection not available")
with self.assertRaisesRegex(TypeError, "arguments must be BufferWithSegments"):
with self.assertRaisesRegex(
TypeError, "arguments must be BufferWithSegments"
):
zstd.BufferWithSegmentsCollection(None)
with self.assertRaisesRegex(TypeError, "arguments must be BufferWithSegments"):
with self.assertRaisesRegex(
TypeError, "arguments must be BufferWithSegments"
):
zstd.BufferWithSegmentsCollection(
zstd.BufferWithSegments(b"foo", ss.pack(0, 3)), None
)
......
......@@ -24,7 +24,9 @@ else:
def multithreaded_chunk_size(level, source_size=0):
params = zstd.ZstdCompressionParameters.from_level(level, source_size=source_size)
params = zstd.ZstdCompressionParameters.from_level(
level, source_size=source_size
)
return 1 << (params.window_log + 2)
......@@ -86,7 +88,9 @@ class TestCompressor_compress(TestCase):
# This matches the test for read_to_iter() below.
cctx = zstd.ZstdCompressor(level=1, write_content_size=False)
result = cctx.compress(b"f" * zstd.COMPRESSION_RECOMMENDED_INPUT_SIZE + b"o")
result = cctx.compress(
b"f" * zstd.COMPRESSION_RECOMMENDED_INPUT_SIZE + b"o"
)
self.assertEqual(
result,
b"\x28\xb5\x2f\xfd\x00\x40\x54\x00\x00"
......@@ -99,7 +103,9 @@ class TestCompressor_compress(TestCase):
result = cctx.compress(b"foo" * 256)
def test_no_magic(self):
params = zstd.ZstdCompressionParameters.from_level(1, format=zstd.FORMAT_ZSTD1)
params = zstd.ZstdCompressionParameters.from_level(
1, format=zstd.FORMAT_ZSTD1
)
cctx = zstd.ZstdCompressor(compression_params=params)
magic = cctx.compress(b"foobar")
......@@ -223,7 +229,8 @@ class TestCompressor_compress(TestCase):
self.assertEqual(
result,
b"\x28\xb5\x2f\xfd\x23\x8f\x55\x0f\x70\x03\x19\x00\x00" b"\x66\x6f\x6f",