--- a/Makefile Tue Mar 22 03:19:01 2022 +0100
+++ b/Makefile Fri Mar 25 11:33:12 2022 -0400
@@ -151,12 +151,9 @@
$(MAKE) -f $(HGROOT)/contrib/Makefile.python PYTHONVER=$* PREFIX=$(HGPYTHONS)/$* python )
cd tests && $(HGPYTHONS)/$*/bin/python run-tests.py $(TESTFLAGS)
-rust-tests: py_feature = $(shell $(PYTHON) -c \
- 'import sys; print(["python27-bin", "python3-bin"][sys.version_info[0] >= 3])')
rust-tests:
cd $(HGROOT)/rust/hg-cpython \
- && $(CARGO) test --quiet --all \
- --no-default-features --features "$(py_feature) $(HG_RUST_FEATURES)"
+ && $(CARGO) test --quiet --all --features "$(HG_RUST_FEATURES)"
check-code:
hg manifest | xargs python contrib/check-code.py
--- a/contrib/automation/hgautomation/aws.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/automation/hgautomation/aws.py Fri Mar 25 11:33:12 2022 -0400
@@ -919,17 +919,12 @@
'SecurityGroupIds': [c.security_groups['linux-dev-1'].id],
}
- requirements2_path = (
- pathlib.Path(__file__).parent.parent / 'linux-requirements-py2.txt'
- )
requirements3_path = (
pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.txt'
)
requirements35_path = (
pathlib.Path(__file__).parent.parent / 'linux-requirements-py3.5.txt'
)
- with requirements2_path.open('r', encoding='utf-8') as fh:
- requirements2 = fh.read()
with requirements3_path.open('r', encoding='utf-8') as fh:
requirements3 = fh.read()
with requirements35_path.open('r', encoding='utf-8') as fh:
@@ -941,7 +936,6 @@
{
'instance_config': config,
'bootstrap_script': BOOTSTRAP_DEBIAN,
- 'requirements_py2': requirements2,
'requirements_py3': requirements3,
'requirements_py35': requirements35,
}
@@ -977,10 +971,6 @@
fh.write(BOOTSTRAP_DEBIAN)
fh.chmod(0o0700)
- with sftp.open('%s/requirements-py2.txt' % home, 'wb') as fh:
- fh.write(requirements2)
- fh.chmod(0o0700)
-
with sftp.open('%s/requirements-py3.txt' % home, 'wb') as fh:
fh.write(requirements3)
fh.chmod(0o0700)
--- a/contrib/automation/hgautomation/cli.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/automation/hgautomation/cli.py Fri Mar 25 11:33:12 2022 -0400
@@ -65,7 +65,6 @@
def build_inno(
hga: HGAutomation,
aws_region,
- python_version,
arch,
revision,
version,
@@ -80,21 +79,18 @@
windows.synchronize_hg(SOURCE_ROOT, revision, instance)
- for py_version in python_version:
- for a in arch:
- windows.build_inno_installer(
- instance.winrm_client,
- py_version,
- a,
- DIST_PATH,
- version=version,
- )
+ for a in arch:
+ windows.build_inno_installer(
+ instance.winrm_client,
+ a,
+ DIST_PATH,
+ version=version,
+ )
def build_wix(
hga: HGAutomation,
aws_region,
- python_version,
arch,
revision,
version,
@@ -109,15 +105,13 @@
windows.synchronize_hg(SOURCE_ROOT, revision, instance)
- for py_version in python_version:
- for a in arch:
- windows.build_wix_installer(
- instance.winrm_client,
- py_version,
- a,
- DIST_PATH,
- version=version,
- )
+ for a in arch:
+ windows.build_wix_installer(
+ instance.winrm_client,
+ a,
+ DIST_PATH,
+ version=version,
+ )
def build_windows_wheel(
@@ -158,7 +152,7 @@
windows.synchronize_hg(SOURCE_ROOT, revision, instance)
- for py_version in ("2.7", "3.7", "3.8", "3.9", "3.10"):
+ for py_version in ("3.7", "3.8", "3.9", "3.10"):
for arch in ("x86", "x64"):
windows.purge_hg(winrm_client)
windows.build_wheel(
@@ -168,15 +162,14 @@
dest_path=DIST_PATH,
)
- for py_version in (2, 3):
- for arch in ('x86', 'x64'):
- windows.purge_hg(winrm_client)
- windows.build_inno_installer(
- winrm_client, py_version, arch, DIST_PATH, version=version
- )
- windows.build_wix_installer(
- winrm_client, py_version, arch, DIST_PATH, version=version
- )
+ for arch in ('x86', 'x64'):
+ windows.purge_hg(winrm_client)
+ windows.build_inno_installer(
+ winrm_client, arch, DIST_PATH, version=version
+ )
+ windows.build_wix_installer(
+ winrm_client, arch, DIST_PATH, version=version
+ )
def terminate_ec2_instances(hga: HGAutomation, aws_region):
@@ -340,14 +333,6 @@
help='Build Inno Setup installer(s)',
)
sp.add_argument(
- '--python-version',
- help='Which version of Python to target',
- choices={2, 3},
- type=int,
- nargs='*',
- default=[3],
- )
- sp.add_argument(
'--arch',
help='Architecture to build for',
choices={'x86', 'x64'},
@@ -377,7 +362,7 @@
sp.add_argument(
'--python-version',
help='Python version to build for',
- choices={'2.7', '3.7', '3.8', '3.9', '3.10'},
+ choices={'3.7', '3.8', '3.9', '3.10'},
nargs='*',
default=['3.8'],
)
@@ -402,14 +387,6 @@
sp = subparsers.add_parser('build-wix', help='Build WiX installer(s)')
sp.add_argument(
- '--python-version',
- help='Which version of Python to target',
- choices={2, 3},
- type=int,
- nargs='*',
- default=[3],
- )
- sp.add_argument(
'--arch',
help='Architecture to build for',
choices={'x86', 'x64'},
@@ -469,9 +446,7 @@
'--python-version',
help='Python version to use',
choices={
- 'system2',
'system3',
- '2.7',
'3.5',
'3.6',
'3.7',
@@ -480,7 +455,7 @@
'pypy3.5',
'pypy3.6',
},
- default='system2',
+ default='system3',
)
sp.add_argument(
'test_flags',
@@ -501,8 +476,8 @@
sp.add_argument(
'--python-version',
help='Python version to use',
- choices={'2.7', '3.5', '3.6', '3.7', '3.8', '3.9', '3.10'},
- default='2.7',
+ choices={'3.5', '3.6', '3.7', '3.8', '3.9', '3.10'},
+ default='3.9',
)
sp.add_argument(
'--arch',
--- a/contrib/automation/hgautomation/linux.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/automation/hgautomation/linux.py Fri Mar 25 11:33:12 2022 -0400
@@ -25,7 +25,6 @@
}
INSTALL_PYTHONS = r'''
-PYENV2_VERSIONS="2.7.17 pypy2.7-7.2.0"
PYENV3_VERSIONS="3.5.10 3.6.13 3.7.10 3.8.10 3.9.5 pypy3.5-7.0.0 pypy3.6-7.3.3 pypy3.7-7.3.3"
git clone https://github.com/pyenv/pyenv.git /hgdev/pyenv
@@ -46,13 +45,6 @@
wget -O ${VIRTUALENV_TARBALL} --progress dot:mega https://files.pythonhosted.org/packages/66/f0/6867af06d2e2f511e4e1d7094ff663acdebc4f15d4a0cb0fed1007395124/${VIRTUALENV_TARBALL}
echo "${VIRTUALENV_SHA256} ${VIRTUALENV_TARBALL}" | sha256sum --check -
-for v in ${PYENV2_VERSIONS}; do
- pyenv install -v ${v}
- ${PYENV_ROOT}/versions/${v}/bin/python get-pip.py
- ${PYENV_ROOT}/versions/${v}/bin/pip install ${VIRTUALENV_TARBALL}
- ${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/requirements-py2.txt
-done
-
for v in ${PYENV3_VERSIONS}; do
pyenv install -v ${v}
${PYENV_ROOT}/versions/${v}/bin/python get-pip.py
@@ -72,7 +64,7 @@
${PYENV_ROOT}/versions/${v}/bin/pip install -r /hgdev/${REQUIREMENTS}
done
-pyenv global ${PYENV2_VERSIONS} ${PYENV3_VERSIONS} system
+pyenv global ${PYENV3_VERSIONS} system
'''.lstrip().replace(
'\r\n', '\n'
)
@@ -274,17 +266,8 @@
netbase \
ntfs-3g \
nvme-cli \
- pyflakes \
pyflakes3 \
- pylint \
pylint3 \
- python-all-dev \
- python-dev \
- python-docutils \
- python-fuzzywuzzy \
- python-pygments \
- python-subversion \
- python-vcr \
python3-boto3 \
python3-dev \
python3-docutils \
@@ -532,7 +515,7 @@
hg_bin = source_path / 'hg'
res = subprocess.run(
- ['python2.7', str(hg_bin), 'log', '-r', revision, '-T', '{node}'],
+ ['python3', str(hg_bin), 'log', '-r', revision, '-T', '{node}'],
cwd=str(source_path),
env=env,
check=True,
@@ -542,7 +525,7 @@
full_revision = res.stdout.decode('ascii')
args = [
- 'python2.7',
+ 'python3',
str(hg_bin),
'--config',
'ui.ssh=ssh -F %s' % ssh_config,
@@ -595,9 +578,7 @@
print('running tests')
- if python_version == 'system2':
- python = '/usr/bin/python2'
- elif python_version == 'system3':
+ if python_version == 'system3':
python = '/usr/bin/python3'
elif python_version.startswith('pypy'):
python = '/hgdev/pyenv/shims/%s' % python_version
--- a/contrib/automation/hgautomation/windows.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/automation/hgautomation/windows.py Fri Mar 25 11:33:12 2022 -0400
@@ -19,30 +19,6 @@
from .winrm import run_powershell
-# PowerShell commands to activate a Visual Studio 2008 environment.
-# This is essentially a port of vcvarsall.bat to PowerShell.
-ACTIVATE_VC9_AMD64 = r'''
-Write-Output "activating Visual Studio 2008 environment for AMD64"
-$root = "$env:LOCALAPPDATA\Programs\Common\Microsoft\Visual C++ for Python\9.0"
-$Env:VCINSTALLDIR = "${root}\VC\"
-$Env:WindowsSdkDir = "${root}\WinSDK\"
-$Env:PATH = "${root}\VC\Bin\amd64;${root}\WinSDK\Bin\x64;${root}\WinSDK\Bin;$Env:PATH"
-$Env:INCLUDE = "${root}\VC\Include;${root}\WinSDK\Include;$Env:PATH"
-$Env:LIB = "${root}\VC\Lib\amd64;${root}\WinSDK\Lib\x64;$Env:LIB"
-$Env:LIBPATH = "${root}\VC\Lib\amd64;${root}\WinSDK\Lib\x64;$Env:LIBPATH"
-'''.lstrip()
-
-ACTIVATE_VC9_X86 = r'''
-Write-Output "activating Visual Studio 2008 environment for x86"
-$root = "$env:LOCALAPPDATA\Programs\Common\Microsoft\Visual C++ for Python\9.0"
-$Env:VCINSTALLDIR = "${root}\VC\"
-$Env:WindowsSdkDir = "${root}\WinSDK\"
-$Env:PATH = "${root}\VC\Bin;${root}\WinSDK\Bin;$Env:PATH"
-$Env:INCLUDE = "${root}\VC\Include;${root}\WinSDK\Include;$Env:INCLUDE"
-$Env:LIB = "${root}\VC\Lib;${root}\WinSDK\Lib;$Env:LIB"
-$Env:LIBPATH = "${root}\VC\lib;${root}\WinSDK\Lib;$Env:LIBPATH"
-'''.lstrip()
-
HG_PURGE = r'''
$Env:PATH = "C:\hgdev\venv-bootstrap\Scripts;$Env:PATH"
Set-Location C:\hgdev\src
@@ -78,14 +54,6 @@
}}
'''
-BUILD_INNO_PYTHON2 = r'''
-Set-Location C:\hgdev\src
-$python = "C:\hgdev\python27-{arch}\python.exe"
-C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py inno --python $python {extra_args}
-if ($LASTEXITCODE -ne 0) {{
- throw "process exited non-0: $LASTEXITCODE"
-}}
-'''.lstrip()
BUILD_WHEEL = r'''
Set-Location C:\hgdev\src
@@ -105,14 +73,6 @@
}}
'''
-BUILD_WIX_PYTHON2 = r'''
-Set-Location C:\hgdev\src
-$python = "C:\hgdev\python27-{arch}\python.exe"
-C:\hgdev\python37-x64\python.exe contrib\packaging\packaging.py wix --python $python {extra_args}
-if ($LASTEXITCODE -ne 0) {{
- throw "process exited non-0: $LASTEXITCODE"
-}}
-'''
RUN_TESTS = r'''
C:\hgdev\MinGW\msys\1.0\bin\sh.exe --login -c "cd /c/hgdev/src/tests && /c/hgdev/{python_path}/python.exe run-tests.py {test_flags}"
@@ -121,8 +81,7 @@
}}
'''
-WHEEL_FILENAME_PYTHON27_X86 = 'mercurial-{version}-cp27-cp27m-win32.whl'
-WHEEL_FILENAME_PYTHON27_X64 = 'mercurial-{version}-cp27-cp27m-win_amd64.whl'
+
WHEEL_FILENAME_PYTHON37_X86 = 'mercurial-{version}-cp37-cp37m-win32.whl'
WHEEL_FILENAME_PYTHON37_X64 = 'mercurial-{version}-cp37-cp37m-win_amd64.whl'
WHEEL_FILENAME_PYTHON38_X86 = 'mercurial-{version}-cp38-cp38-win32.whl'
@@ -132,13 +91,9 @@
WHEEL_FILENAME_PYTHON310_X86 = 'mercurial-{version}-cp310-cp310-win32.whl'
WHEEL_FILENAME_PYTHON310_X64 = 'mercurial-{version}-cp310-cp310-win_amd64.whl'
-EXE_FILENAME_PYTHON2_X86 = 'Mercurial-{version}-x86-python2.exe'
-EXE_FILENAME_PYTHON2_X64 = 'Mercurial-{version}-x64-python2.exe'
EXE_FILENAME_PYTHON3_X86 = 'Mercurial-{version}-x86.exe'
EXE_FILENAME_PYTHON3_X64 = 'Mercurial-{version}-x64.exe'
-MSI_FILENAME_PYTHON2_X86 = 'mercurial-{version}-x86-python2.msi'
-MSI_FILENAME_PYTHON2_X64 = 'mercurial-{version}-x64-python2.msi'
MSI_FILENAME_PYTHON3_X86 = 'mercurial-{version}-x86.msi'
MSI_FILENAME_PYTHON3_X64 = 'mercurial-{version}-x64.msi'
@@ -147,14 +102,6 @@
X86_USER_AGENT_PATTERN = '.*Windows.*'
X64_USER_AGENT_PATTERN = '.*Windows.*(WOW|x)64.*'
-EXE_PYTHON2_X86_DESCRIPTION = (
- 'Mercurial {version} Inno Setup installer - x86 Windows (Python 2) '
- '- does not require admin rights'
-)
-EXE_PYTHON2_X64_DESCRIPTION = (
- 'Mercurial {version} Inno Setup installer - x64 Windows (Python 2) '
- '- does not require admin rights'
-)
# TODO remove Python version once Python 2 is dropped.
EXE_PYTHON3_X86_DESCRIPTION = (
'Mercurial {version} Inno Setup installer - x86 Windows (Python 3) '
@@ -164,14 +111,6 @@
'Mercurial {version} Inno Setup installer - x64 Windows (Python 3) '
'- does not require admin rights'
)
-MSI_PYTHON2_X86_DESCRIPTION = (
- 'Mercurial {version} MSI installer - x86 Windows (Python 2) '
- '- requires admin rights'
-)
-MSI_PYTHON2_X64_DESCRIPTION = (
- 'Mercurial {version} MSI installer - x64 Windows (Python 2) '
- '- requires admin rights'
-)
MSI_PYTHON3_X86_DESCRIPTION = (
'Mercurial {version} MSI installer - x86 Windows (Python 3) '
'- requires admin rights'
@@ -182,15 +121,6 @@
)
-def get_vc_prefix(arch):
- if arch == 'x86':
- return ACTIVATE_VC9_X86
- elif arch == 'x64':
- return ACTIVATE_VC9_AMD64
- else:
- raise ValueError('illegal arch: %s; must be x86 or x64' % arch)
-
-
def fix_authorized_keys_permissions(winrm_client, path):
commands = [
'$ErrorActionPreference = "Stop"',
@@ -261,7 +191,7 @@
hg_bin = hg_repo / 'hg'
res = subprocess.run(
- ['python2.7', str(hg_bin), 'log', '-r', revision, '-T', '{node}'],
+ ['python3', str(hg_bin), 'log', '-r', revision, '-T', '{node}'],
cwd=str(hg_repo),
env=env,
check=True,
@@ -271,7 +201,7 @@
full_revision = res.stdout.decode('ascii')
args = [
- 'python2.7',
+ 'python3',
hg_bin,
'--config',
'ui.ssh=ssh -F %s' % ssh_config,
@@ -334,7 +264,6 @@
def build_inno_installer(
winrm_client,
- python_version: int,
arch: str,
dest_path: pathlib.Path,
version=None,
@@ -344,37 +273,23 @@
Using a WinRM client, remote commands are executed to build
a Mercurial Inno Setup installer.
"""
- print(
- 'building Inno Setup installer for Python %d %s'
- % (python_version, arch)
- )
+ print('building Inno Setup installer for %s' % arch)
- if python_version == 3:
- # TODO fix this limitation in packaging code
- if not version:
- raise Exception(
- "version string is required when building for Python 3"
- )
+ # TODO fix this limitation in packaging code
+ if not version:
+ raise Exception("version string is required when building for Python 3")
- if arch == "x86":
- target_triple = "i686-pc-windows-msvc"
- elif arch == "x64":
- target_triple = "x86_64-pc-windows-msvc"
- else:
- raise Exception("unhandled arch: %s" % arch)
+ if arch == "x86":
+ target_triple = "i686-pc-windows-msvc"
+ elif arch == "x64":
+ target_triple = "x86_64-pc-windows-msvc"
+ else:
+ raise Exception("unhandled arch: %s" % arch)
- ps = BUILD_INNO_PYTHON3.format(
- pyoxidizer_target=target_triple,
- version=version,
- )
- else:
- extra_args = []
- if version:
- extra_args.extend(['--version', version])
-
- ps = get_vc_prefix(arch) + BUILD_INNO_PYTHON2.format(
- arch=arch, extra_args=' '.join(extra_args)
- )
+ ps = BUILD_INNO_PYTHON3.format(
+ pyoxidizer_target=target_triple,
+ version=version,
+ )
run_powershell(winrm_client, ps)
copy_latest_dist(winrm_client, '*.exe', dest_path)
@@ -394,17 +309,12 @@
python_version=python_version.replace(".", ""), arch=arch
)
- # Python 2.7 requires an activated environment.
- if python_version == "2.7":
- ps = get_vc_prefix(arch) + ps
-
run_powershell(winrm_client, ps)
copy_latest_dist(winrm_client, '*.whl', dest_path)
def build_wix_installer(
winrm_client,
- python_version: int,
arch: str,
dest_path: pathlib.Path,
version=None,
@@ -413,34 +323,23 @@
Using a WinRM client, remote commands are executed to build a WiX installer.
"""
- print('Building WiX installer for Python %d %s' % (python_version, arch))
+ print('Building WiX installer for %s' % arch)
- if python_version == 3:
- # TODO fix this limitation in packaging code
- if not version:
- raise Exception(
- "version string is required when building for Python 3"
- )
+ # TODO fix this limitation in packaging code
+ if not version:
+ raise Exception("version string is required when building for Python 3")
- if arch == "x86":
- target_triple = "i686-pc-windows-msvc"
- elif arch == "x64":
- target_triple = "x86_64-pc-windows-msvc"
- else:
- raise Exception("unhandled arch: %s" % arch)
+ if arch == "x86":
+ target_triple = "i686-pc-windows-msvc"
+ elif arch == "x64":
+ target_triple = "x86_64-pc-windows-msvc"
+ else:
+ raise Exception("unhandled arch: %s" % arch)
- ps = BUILD_WIX_PYTHON3.format(
- pyoxidizer_target=target_triple,
- version=version,
- )
- else:
- extra_args = []
- if version:
- extra_args.extend(['--version', version])
-
- ps = get_vc_prefix(arch) + BUILD_WIX_PYTHON2.format(
- arch=arch, extra_args=' '.join(extra_args)
- )
+ ps = BUILD_WIX_PYTHON3.format(
+ pyoxidizer_target=target_triple,
+ version=version,
+ )
run_powershell(winrm_client, ps)
copy_latest_dist(winrm_client, '*.msi', dest_path)
@@ -474,8 +373,6 @@
def resolve_wheel_artifacts(dist_path: pathlib.Path, version: str):
return (
- dist_path / WHEEL_FILENAME_PYTHON27_X86.format(version=version),
- dist_path / WHEEL_FILENAME_PYTHON27_X64.format(version=version),
dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version),
dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version),
dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version),
@@ -489,8 +386,6 @@
def resolve_all_artifacts(dist_path: pathlib.Path, version: str):
return (
- dist_path / WHEEL_FILENAME_PYTHON27_X86.format(version=version),
- dist_path / WHEEL_FILENAME_PYTHON27_X64.format(version=version),
dist_path / WHEEL_FILENAME_PYTHON37_X86.format(version=version),
dist_path / WHEEL_FILENAME_PYTHON37_X64.format(version=version),
dist_path / WHEEL_FILENAME_PYTHON38_X86.format(version=version),
@@ -499,24 +394,16 @@
dist_path / WHEEL_FILENAME_PYTHON39_X64.format(version=version),
dist_path / WHEEL_FILENAME_PYTHON310_X86.format(version=version),
dist_path / WHEEL_FILENAME_PYTHON310_X64.format(version=version),
- dist_path / EXE_FILENAME_PYTHON2_X86.format(version=version),
- dist_path / EXE_FILENAME_PYTHON2_X64.format(version=version),
dist_path / EXE_FILENAME_PYTHON3_X86.format(version=version),
dist_path / EXE_FILENAME_PYTHON3_X64.format(version=version),
- dist_path / MSI_FILENAME_PYTHON2_X86.format(version=version),
- dist_path / MSI_FILENAME_PYTHON2_X64.format(version=version),
dist_path / MSI_FILENAME_PYTHON3_X86.format(version=version),
dist_path / MSI_FILENAME_PYTHON3_X64.format(version=version),
)
def generate_latest_dat(version: str):
- python2_x86_exe_filename = EXE_FILENAME_PYTHON2_X86.format(version=version)
- python2_x64_exe_filename = EXE_FILENAME_PYTHON2_X64.format(version=version)
python3_x86_exe_filename = EXE_FILENAME_PYTHON3_X86.format(version=version)
python3_x64_exe_filename = EXE_FILENAME_PYTHON3_X64.format(version=version)
- python2_x86_msi_filename = MSI_FILENAME_PYTHON2_X86.format(version=version)
- python2_x64_msi_filename = MSI_FILENAME_PYTHON2_X64.format(version=version)
python3_x86_msi_filename = MSI_FILENAME_PYTHON3_X86.format(version=version)
python3_x64_msi_filename = MSI_FILENAME_PYTHON3_X64.format(version=version)
@@ -536,20 +423,6 @@
EXE_PYTHON3_X64_DESCRIPTION.format(version=version),
),
(
- '9',
- version,
- X86_USER_AGENT_PATTERN,
- '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x86_exe_filename),
- EXE_PYTHON2_X86_DESCRIPTION.format(version=version),
- ),
- (
- '9',
- version,
- X64_USER_AGENT_PATTERN,
- '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x64_exe_filename),
- EXE_PYTHON2_X64_DESCRIPTION.format(version=version),
- ),
- (
'10',
version,
X86_USER_AGENT_PATTERN,
@@ -563,20 +436,6 @@
'%s/%s' % (MERCURIAL_SCM_BASE_URL, python3_x64_msi_filename),
MSI_PYTHON3_X64_DESCRIPTION.format(version=version),
),
- (
- '9',
- version,
- X86_USER_AGENT_PATTERN,
- '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x86_msi_filename),
- MSI_PYTHON2_X86_DESCRIPTION.format(version=version),
- ),
- (
- '9',
- version,
- X64_USER_AGENT_PATTERN,
- '%s/%s' % (MERCURIAL_SCM_BASE_URL, python2_x64_msi_filename),
- MSI_PYTHON2_X64_DESCRIPTION.format(version=version),
- ),
)
lines = ['\t'.join(e) for e in entries]
--- a/contrib/automation/linux-requirements-py2.txt Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,129 +0,0 @@
-#
-# This file is autogenerated by pip-compile
-# To update, run:
-#
-# pip-compile --generate-hashes --output-file=contrib/automation/linux-requirements-py2.txt contrib/automation/linux-requirements.txt.in
-#
-astroid==1.6.6 \
- --hash=sha256:87de48a92e29cedf7210ffa853d11441e7ad94cb47bacd91b023499b51cbc756 \
- --hash=sha256:d25869fc7f44f1d9fb7d24fd7ea0639656f5355fc3089cd1f3d18c6ec6b124c7 \
- # via pylint
-backports.functools-lru-cache==1.6.1 \
- --hash=sha256:0bada4c2f8a43d533e4ecb7a12214d9420e66eb206d54bf2d682581ca4b80848 \
- --hash=sha256:8fde5f188da2d593bd5bc0be98d9abc46c95bb8a9dde93429570192ee6cc2d4a \
- # via astroid, isort, pylint
-bzr==2.7.0 ; python_version <= "2.7" and platform_python_implementation == "CPython" \
- --hash=sha256:c9f6bbe0a50201dadc5fddadd94ba50174193c6cf6e39e16f6dd0ad98a1df338 \
- # via -r contrib/automation/linux-requirements.txt.in
-configparser==4.0.2 \
- --hash=sha256:254c1d9c79f60c45dfde850850883d5aaa7f19a23f13561243a050d5a7c3fe4c \
- --hash=sha256:c7d282687a5308319bf3d2e7706e575c635b0a470342641c93bea0ea3b5331df \
- # via pylint
-contextlib2==0.6.0.post1 \
- --hash=sha256:01f490098c18b19d2bd5bb5dc445b2054d2fa97f09a4280ba2c5f3c394c8162e \
- --hash=sha256:3355078a159fbb44ee60ea80abd0d87b80b78c248643b49aa6d94673b413609b \
- # via vcrpy
-docutils==0.16 \
- --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \
- --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \
- # via -r contrib/automation/linux-requirements.txt.in
-enum34==1.1.10 \
- --hash=sha256:a98a201d6de3f2ab3db284e70a33b0f896fbf35f8086594e8c9e74b909058d53 \
- --hash=sha256:c3858660960c984d6ab0ebad691265180da2b43f07e061c0f8dca9ef3cffd328 \
- --hash=sha256:cce6a7477ed816bd2542d03d53db9f0db935dd013b70f336a95c73979289f248 \
- # via astroid
-funcsigs==1.0.2 \
- --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
- --hash=sha256:a7bb0f2cf3a3fd1ab2732cb49eba4252c2af4240442415b4abce3b87022a8f50 \
- # via mock
-futures==3.3.0 \
- --hash=sha256:49b3f5b064b6e3afc3316421a3f25f66c137ae88f068abbf72830170033c5e16 \
- --hash=sha256:7e033af76a5e35f58e56da7a91e687706faf4e7bdfb2cbc3f2cca6b9bcda9794 \
- # via isort
-fuzzywuzzy==0.18.0 \
- --hash=sha256:45016e92264780e58972dca1b3d939ac864b78437422beecebb3095f8efd00e8 \
- --hash=sha256:928244b28db720d1e0ee7587acf660ea49d7e4c632569cad4f1cd7e68a5f0993 \
- # via -r contrib/automation/linux-requirements.txt.in
-isort==4.3.21 \
- --hash=sha256:54da7e92468955c4fceacd0c86bd0ec997b0e1ee80d97f67c35a78b719dccab1 \
- --hash=sha256:6e811fcb295968434526407adb8796944f1988c5b65e8139058f2014cbe100fd \
- # via pylint
-lazy-object-proxy==1.5.1 \
- --hash=sha256:00b78a97a79d0dfefa584d44dd1aba9668d3de7ec82335ba0ff51d53ef107143 \
- --hash=sha256:042b54fd71c2092e6d10e5e66fa60f65c5954f8145e809f5d9f394c9b13d32ee \
- --hash=sha256:11f87dc06eb5f376cc6d5f0c19a1b4dca202035622777c4ce8e5b72c87b035d6 \
- --hash=sha256:19ae6f6511a02008ef3554e158c41bb2a8e5c8455935b98d6da076d9f152fd7c \
- --hash=sha256:22c1935c6f8e3d6ea2e169eb03928adbdb8a2251d2890f8689368d65e70aa176 \
- --hash=sha256:30ef2068f4f94660144515380ef04b93d15add2214eab8be4cd46ebc900d681c \
- --hash=sha256:33da47ba3a581860ddd3d38c950a5fe950ca389f7123edd0d6ab0bc473499fe7 \
- --hash=sha256:3e8698dc384857413580012f4ca322d89e63ef20fc3d4635a5b606d6d4b61f6a \
- --hash=sha256:4fdd7113fc5143c72dacf415079eec42fcbe69cc9d3d291b4ca742e3a9455807 \
- --hash=sha256:63b6d9a5077d54db271fcc6772440f7380ec3fa559d0e2497dbfae2f47c2c814 \
- --hash=sha256:8133b63b05f12751cddd8e3e7f02ba39dc7cfa7d2ba99d80d7436f0ba26d6b75 \
- --hash=sha256:89b8e5780e49753e2b4cd5aab45d3df092ddcbba3de2c4d4492a029588fe1758 \
- --hash=sha256:8d82e27cbbea6edb8821751806f39f5dcfd7b46a5e23d27b98d6d8c8ec751df8 \
- --hash=sha256:92cedd6e26712505adb1c17fab64651a498cc0102a80ba562ff4a2451088f57a \
- --hash=sha256:9723364577b79ad9958a68851fe2acb94da6fd25170c595516a8289e6a129043 \
- --hash=sha256:c484020ad26973a14a7cb1e1d2e0bfe97cf6803273ae9bd154e0213cc74bad49 \
- --hash=sha256:c697bd1b333b3e6abdff04ef9f5fb4b1936633d9cc4e28d90606705c9083254c \
- --hash=sha256:d0f7e14ff3424639d33e6bc449e77e4b345e52c21bbd6f6004a1d219196e2664 \
- --hash=sha256:db2df3eff7ed3e6813638686f1bb5934d1a0662d9d3b4196b5164a86be3a1e8f \
- --hash=sha256:edbcb4c5efabd93ede05b272296a5a78a67e9b6e82ba7f51a07b8103db06ce01 \
- --hash=sha256:ef355fb3802e0fc5a71dadb65a3c317bfc9bdf567d357f8e0b1900b432ffe486 \
- --hash=sha256:fe2f61fed5817bf8db01d9a72309ed5990c478a077e9585b58740c26774bce39 \
- # via astroid
-mccabe==0.6.1 \
- --hash=sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42 \
- --hash=sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f \
- # via pylint
-mock==3.0.5 \
- --hash=sha256:83657d894c90d5681d62155c82bda9c1187827525880eda8ff5df4ec813437c3 \
- --hash=sha256:d157e52d4e5b938c550f39eb2fd15610db062441a9c2747d3dbfa9298211d0f8 \
- # via vcrpy
-pyflakes==2.2.0 \
- --hash=sha256:0d94e0e05a19e57a99444b6ddcf9a6eb2e5c68d3ca1e98e90707af8152c90a92 \
- --hash=sha256:35b2d75ee967ea93b55750aa9edbbf72813e06a66ba54438df2cfac9e3c27fc8 \
- # via -r contrib/automation/linux-requirements.txt.in
-pygments==2.5.2 \
- --hash=sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b \
- --hash=sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe \
- # via -r contrib/automation/linux-requirements.txt.in
-pylint==1.9.5 \
- --hash=sha256:367e3d49813d349a905390ac27989eff82ab84958731c5ef0bef867452cfdc42 \
- --hash=sha256:97a42df23d436c70132971d1dcb9efad2fe5c0c6add55b90161e773caf729300 \
- # via -r contrib/automation/linux-requirements.txt.in
-python-levenshtein==0.12.0 \
- --hash=sha256:033a11de5e3d19ea25c9302d11224e1a1898fe5abd23c61c7c360c25195e3eb1 \
- # via -r contrib/automation/linux-requirements.txt.in
-pyyaml==5.3.1 \
- --hash=sha256:06a0d7ba600ce0b2d2fe2e78453a470b5a6e000a985dd4a4e54e436cc36b0e97 \
- --hash=sha256:240097ff019d7c70a4922b6869d8a86407758333f02203e0fc6ff79c5dcede76 \
- --hash=sha256:4f4b913ca1a7319b33cfb1369e91e50354d6f07a135f3b901aca02aa95940bd2 \
- --hash=sha256:69f00dca373f240f842b2931fb2c7e14ddbacd1397d57157a9b005a6a9942648 \
- --hash=sha256:73f099454b799e05e5ab51423c7bcf361c58d3206fa7b0d555426b1f4d9a3eaf \
- --hash=sha256:74809a57b329d6cc0fdccee6318f44b9b8649961fa73144a98735b0aaf029f1f \
- --hash=sha256:7739fc0fa8205b3ee8808aea45e968bc90082c10aef6ea95e855e10abf4a37b2 \
- --hash=sha256:95f71d2af0ff4227885f7a6605c37fd53d3a106fcab511b8860ecca9fcf400ee \
- --hash=sha256:b8eac752c5e14d3eca0e6dd9199cd627518cb5ec06add0de9d32baeee6fe645d \
- --hash=sha256:cc8955cfbfc7a115fa81d85284ee61147059a753344bc51098f3ccd69b0d7e0c \
- --hash=sha256:d13155f591e6fcc1ec3b30685d50bf0711574e2c0dfffd7644babf8b5102ca1a \
- # via vcrpy
-singledispatch==3.4.0.3 \
- --hash=sha256:5b06af87df13818d14f08a028e42f566640aef80805c3b50c5056b086e3c2b9c \
- --hash=sha256:833b46966687b3de7f438c761ac475213e53b306740f1abfaa86e1d1aae56aa8 \
- # via astroid, pylint
-six==1.15.0 \
- --hash=sha256:30639c035cdb23534cd4aa2dd52c3bf48f06e5f4a941509c8bafd8ce11080259 \
- --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
- # via astroid, mock, pylint, singledispatch, vcrpy
-vcrpy==3.0.0 \
- --hash=sha256:21168d5ae14263a833d4b71acfd8278d8841114f24be1b4ab4a5719d0c7f07bc \
- --hash=sha256:a2e6b653a627f9f3d6ded4d68587e470b91e4c1444e7dae939510dfeacb65276 \
- # via -r contrib/automation/linux-requirements.txt.in
-wrapt==1.12.1 \
- --hash=sha256:b62ffa81fb85f4332a4f609cab4ac40709470da05643a082ec1eb88e6d9b97d7 \
- # via astroid, vcrpy
-
-# WARNING: The following packages were not pinned, but pip requires them to be
-# pinned when the requirements file includes hashes. Consider using the --allow-unsafe flag.
-# setuptools
--- a/contrib/bdiff-torture.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/bdiff-torture.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# Randomized torture test generation for bdiff
-from __future__ import absolute_import, print_function
import random
import sys
--- a/contrib/benchmarks/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/benchmarks/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -31,7 +31,6 @@
$ asv --config contrib/asv.conf.json preview
'''
-from __future__ import absolute_import
import functools
import os
--- a/contrib/benchmarks/perf.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/benchmarks/perf.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from . import perfbench
--- a/contrib/benchmarks/revset.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/benchmarks/revset.py Fri Mar 25 11:33:12 2022 -0400
@@ -10,7 +10,6 @@
Each revset benchmark is parameterized with variants (first, last, sort, ...)
'''
-from __future__ import absolute_import
import os
import string
--- a/contrib/byteify-strings.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/byteify-strings.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import argparse
import contextlib
--- a/contrib/casesmash.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/casesmash.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
import __builtin__
import os
from mercurial import util
--- a/contrib/catapipe.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/catapipe.py Fri Mar 25 11:33:12 2022 -0400
@@ -34,7 +34,6 @@
HGCATAPULTSERVERPIPE environment variable, which both run-tests and hg
understand. To trace *only* run-tests, use HGTESTCATAPULTSERVERPIPE instead.
"""
-from __future__ import absolute_import, print_function
import argparse
import json
--- a/contrib/check-code.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/check-code.py Fri Mar 25 11:33:12 2022 -0400
@@ -19,7 +19,6 @@
* ONLY use no--check-code for skipping entire files from external sources
"""
-from __future__ import absolute_import, print_function
import glob
import keyword
import optparse
@@ -344,16 +343,6 @@
"linebreak after :",
),
(
- r'class\s[^( \n]+:',
- "old-style class, use class foo(object)",
- r'#.*old-style',
- ),
- (
- r'class\s[^( \n]+\(\):',
- "class foo() creates old style object, use class foo(object)",
- r'#.*old-style',
- ),
- (
r'\b(%s)\('
% '|'.join(k for k in keyword.kwlist if k not in ('print', 'exec')),
"Python keyword is not a function",
@@ -431,26 +420,6 @@
"module-level @cachefunc is risky, please avoid",
),
(
- r'^import Queue',
- "don't use Queue, use pycompat.queue.Queue + "
- "pycompat.queue.Empty",
- ),
- (
- r'^import cStringIO',
- "don't use cStringIO.StringIO, use util.stringio",
- ),
- (r'^import urllib', "don't use urllib, use util.urlreq/util.urlerr"),
- (
- r'^import SocketServer',
- "don't use SockerServer, use util.socketserver",
- ),
- (r'^import urlparse', "don't use urlparse, use util.urlreq"),
- (r'^import xmlrpclib', "don't use xmlrpclib, use util.xmlrpclib"),
- (r'^import cPickle', "don't use cPickle, use util.pickle"),
- (r'^import pickle', "don't use pickle, use util.pickle"),
- (r'^import httplib', "don't use httplib, use util.httplib"),
- (r'^import BaseHTTPServer', "use util.httpserver instead"),
- (
r'^(from|import) mercurial\.(cext|pure|cffi)',
"use mercurial.policy.importmod instead",
),
@@ -789,7 +758,7 @@
preparefilters(filters)
-class norepeatlogger(object):
+class norepeatlogger:
def __init__(self):
self._lastseen = None
--- a/contrib/check-commit Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/check-commit Fri Mar 25 11:33:12 2022 -0400
@@ -15,7 +15,6 @@
#
# See also: https://mercurial-scm.org/wiki/ContributingChanges
-from __future__ import absolute_import, print_function
import os
import re
--- a/contrib/check-config.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/check-config.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import re
import sys
--- a/contrib/check-py3-compat.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/check-py3-compat.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import ast
import importlib
@@ -17,31 +16,6 @@
import warnings
-def check_compat_py2(f):
- """Check Python 3 compatibility for a file with Python 2"""
- with open(f, 'rb') as fh:
- content = fh.read()
- root = ast.parse(content)
-
- # Ignore empty files.
- if not root.body:
- return
-
- futures = set()
- haveprint = False
- for node in ast.walk(root):
- if isinstance(node, ast.ImportFrom):
- if node.module == '__future__':
- futures |= {n.name for n in node.names}
- elif isinstance(node, ast.Print):
- haveprint = True
-
- if 'absolute_import' not in futures:
- print('%s not using absolute_import' % f)
- if haveprint and 'print_function' not in futures:
- print('%s requires print_function' % f)
-
-
def check_compat_py3(f):
"""Check Python 3 compatibility of a file with Python 3."""
with open(f, 'rb') as fh:
@@ -94,23 +68,19 @@
if __name__ == '__main__':
- if sys.version_info[0] == 2:
- fn = check_compat_py2
- else:
- # check_compat_py3 will import every filename we specify as long as it
- # starts with one of a few prefixes. It does this by converting
- # specified filenames like 'mercurial/foo.py' to 'mercurial.foo' and
- # importing that. When running standalone (not as part of a test), this
- # means we actually import the installed versions, not the files we just
- # specified. When running as test-check-py3-compat.t, we technically
- # would import the correct paths, but it's cleaner to have both cases
- # use the same import logic.
- sys.path.insert(0, '.')
- fn = check_compat_py3
+ # check_compat_py3 will import every filename we specify as long as it
+ # starts with one of a few prefixes. It does this by converting
+ # specified filenames like 'mercurial/foo.py' to 'mercurial.foo' and
+ # importing that. When running standalone (not as part of a test), this
+ # means we actually import the installed versions, not the files we just
+ # specified. When running as test-check-py3-compat.t, we technically
+ # would import the correct paths, but it's cleaner to have both cases
+ # use the same import logic.
+ sys.path.insert(0, '.')
for f in sys.argv[1:]:
with warnings.catch_warnings(record=True) as warns:
- fn(f)
+ check_compat_py3(f)
for w in warns:
print(
--- a/contrib/debugcmdserver.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/debugcmdserver.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# $ ./hg serve --cmds pipe | ./contrib/debugcmdserver.py -
# o, 52 -> 'capabilities: getencoding runcommand\nencoding: UTF-8'
-from __future__ import absolute_import, print_function
import struct
import sys
--- a/contrib/debugshell.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/debugshell.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
# debugshell extension
"""a python shell with repo, changelog & manifest objects"""
-from __future__ import absolute_import
import code
import mercurial
import sys
--- a/contrib/dumprevlog Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/dumprevlog Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
# Dump revlogs as raw data stream
# $ find .hg/store/ -name "*.i" | xargs dumprevlog > repo.dump
-from __future__ import absolute_import, print_function
import sys
from mercurial.node import hex
--- a/contrib/fuzz/dirs_corpus.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/fuzz/dirs_corpus.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import argparse
import zipfile
--- a/contrib/fuzz/dirstate_corpus.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/fuzz/dirstate_corpus.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import argparse
import os
import zipfile
--- a/contrib/fuzz/fm1readmarkers_corpus.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/fuzz/fm1readmarkers_corpus.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import argparse
import zipfile
--- a/contrib/fuzz/manifest_corpus.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/fuzz/manifest_corpus.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import argparse
import zipfile
--- a/contrib/fuzz/mpatch_corpus.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/fuzz/mpatch_corpus.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import argparse
import os
import struct
@@ -22,7 +20,7 @@
if sys.version_info[0] < 3:
- class py2reprhack(object):
+ class py2reprhack:
def __repr__(self):
"""Py2 calls __repr__ for `bytes(foo)`, forward to __bytes__"""
return self.__bytes__()
@@ -30,7 +28,7 @@
else:
- class py2reprhack(object):
+ class py2reprhack:
"""Not needed on py3."""
--- a/contrib/fuzz/revlog_corpus.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/fuzz/revlog_corpus.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import argparse
import os
import zipfile
--- a/contrib/genosxversion.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/genosxversion.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
#!/usr/bin/env python2
-from __future__ import absolute_import, print_function
import argparse
import os
--- a/contrib/heptapod-ci.yml Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/heptapod-ci.yml Fri Mar 25 11:33:12 2022 -0400
@@ -30,27 +30,17 @@
- echo "$RUNTEST_ARGS"
- HGTESTS_ALLOW_NETIO="$TEST_HGTESTS_ALLOW_NETIO" HGMODULEPOLICY="$TEST_HGMODULEPOLICY" "$PYTHON" tests/run-tests.py --color=always $RUNTEST_ARGS
-checks-py2:
- <<: *runtests
- variables:
- RUNTEST_ARGS: "--time --test-list /tmp/check-tests.txt"
-
-checks-py3:
+checks:
<<: *runtests
variables:
RUNTEST_ARGS: "--time --test-list /tmp/check-tests.txt"
PYTHON: python3
-rust-cargo-test-py2: &rust_cargo_test
- <<: *all
+rust-cargo-test:
stage: tests
script:
- echo "python used, $PYTHON"
- make rust-tests
-
-rust-cargo-test-py3:
- stage: tests
- <<: *rust_cargo_test
variables:
PYTHON: python3
@@ -72,14 +62,7 @@
./contrib/phab-refresh-stack.sh --comment "$DEFAULT_COMMENT";
fi
-test-py2:
- <<: *runtests
- variables:
- RUNTEST_ARGS: " --no-rust --blacklist /tmp/check-tests.txt"
- TEST_HGMODULEPOLICY: "c"
- TEST_HGTESTS_ALLOW_NETIO: "1"
-
-test-py3:
+test-c:
<<: *runtests
variables:
RUNTEST_ARGS: " --no-rust --blacklist /tmp/check-tests.txt"
@@ -87,27 +70,14 @@
TEST_HGMODULEPOLICY: "c"
TEST_HGTESTS_ALLOW_NETIO: "1"
-test-py2-pure:
- <<: *runtests
- variables:
- RUNTEST_ARGS: "--pure --blacklist /tmp/check-tests.txt"
- TEST_HGMODULEPOLICY: "py"
-
-test-py3-pure:
+test-pure:
<<: *runtests
variables:
RUNTEST_ARGS: "--pure --blacklist /tmp/check-tests.txt"
PYTHON: python3
TEST_HGMODULEPOLICY: "py"
-test-py2-rust:
- <<: *runtests
- variables:
- HGWITHRUSTEXT: cpython
- RUNTEST_ARGS: "--rust --blacklist /tmp/check-tests.txt"
- TEST_HGMODULEPOLICY: "rust+c"
-
-test-py3-rust:
+test-rust:
<<: *runtests
variables:
HGWITHRUSTEXT: cpython
@@ -115,7 +85,7 @@
PYTHON: python3
TEST_HGMODULEPOLICY: "rust+c"
-test-py3-rhg:
+test-rhg:
<<: *runtests
variables:
HGWITHRUSTEXT: cpython
@@ -123,20 +93,14 @@
PYTHON: python3
TEST_HGMODULEPOLICY: "rust+c"
-test-py2-chg:
- <<: *runtests
- variables:
- RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt --chg"
- TEST_HGMODULEPOLICY: "c"
-
-test-py3-chg:
+test-chg:
<<: *runtests
variables:
PYTHON: python3
RUNTEST_ARGS: "--blacklist /tmp/check-tests.txt --chg"
TEST_HGMODULEPOLICY: "c"
-check-pytype-py3:
+check-pytype:
extends: .runtests_template
before_script:
- hg clone . /tmp/mercurial-ci/ --noupdate --config phases.publish=no
@@ -174,7 +138,7 @@
- C:/MinGW/msys/1.0/bin/sh.exe --login -c 'cd "$OLDPWD" && HGTESTS_ALLOW_NETIO="$TEST_HGTESTS_ALLOW_NETIO" HGMODULEPOLICY="$TEST_HGMODULEPOLICY" $PYTHON tests/run-tests.py --color=always $RUNTEST_ARGS'
-windows-py3:
+windows:
<<: *windows_runtests
tags:
- windows
@@ -183,7 +147,7 @@
RUNTEST_ARGS: "--blacklist C:/Temp/check-tests.txt"
PYTHON: py -3
-windows-py3-pyox:
+windows-pyox:
<<: *windows_runtests
tags:
- windows
--- a/contrib/hg-ssh Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/hg-ssh Fri Mar 25 11:33:12 2022 -0400
@@ -28,7 +28,6 @@
You can also add a --read-only flag to allow read-only access to a key, e.g.:
command="hg-ssh --read-only repos/*"
"""
-from __future__ import absolute_import
import os
import re
--- a/contrib/hgclient.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/hgclient.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# A minimal client for Mercurial's command server
-from __future__ import absolute_import, print_function
import io
import os
@@ -50,7 +49,7 @@
return server
-class unixconnection(object):
+class unixconnection:
def __init__(self, sockpath):
self.sock = sock = socket.socket(socket.AF_UNIX)
sock.connect(sockpath)
@@ -63,7 +62,7 @@
self.sock.close()
-class unixserver(object):
+class unixserver:
def __init__(self, sockpath, logpath=None, repopath=None):
self.sockpath = sockpath
cmdline = [b'hg', b'serve', b'--cmdserver', b'unix', b'-a', sockpath]
--- a/contrib/import-checker.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/import-checker.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
-from __future__ import absolute_import, print_function
import ast
import collections
@@ -20,10 +19,11 @@
import testparseutil
-# Whitelist of modules that symbols can be directly imported from.
+# Allow list of modules that symbols can be directly imported from.
allowsymbolimports = (
'__future__',
'breezy',
+ 'concurrent',
'hgclient',
'mercurial',
'mercurial.hgweb.common',
@@ -46,9 +46,10 @@
'mercurial.thirdparty.attr',
'mercurial.thirdparty.zope',
'mercurial.thirdparty.zope.interface',
+ 'typing',
)
-# Whitelist of symbols that can be directly imported.
+# Allow list of symbols that can be directly imported.
directsymbols = ('demandimport',)
# Modules that must be aliased because they are commonly confused with
@@ -58,21 +59,6 @@
}
-def usingabsolute(root):
- """Whether absolute imports are being used."""
- if sys.version_info[0] >= 3:
- return True
-
- for node in ast.walk(root):
- if isinstance(node, ast.ImportFrom):
- if node.module == '__future__':
- for n in node.names:
- if n.name == 'absolute_import':
- return True
-
- return False
-
-
def walklocal(root):
"""Recursively yield all descendant nodes but not in a different scope"""
todo = collections.deque(ast.iter_child_nodes(root))
@@ -402,21 +388,10 @@
def verify_import_convention(module, source, localmods):
- """Verify imports match our established coding convention.
-
- We have 2 conventions: legacy and modern. The modern convention is in
- effect when using absolute imports.
+ """Verify imports match our established coding convention."""
+ root = ast.parse(source)
- The legacy convention only looks for mixed imports. The modern convention
- is much more thorough.
- """
- root = ast.parse(source)
- absolute = usingabsolute(root)
-
- if absolute:
- return verify_modern_convention(module, root, localmods)
- else:
- return verify_stdlib_on_own_line(root)
+ return verify_modern_convention(module, root, localmods)
def verify_modern_convention(module, root, localmods, root_col_offset=0):
@@ -617,33 +592,6 @@
)
-def verify_stdlib_on_own_line(root):
- """Given some python source, verify that stdlib imports are done
- in separate statements from relative local module imports.
-
- >>> list(verify_stdlib_on_own_line(ast.parse('import sys, foo')))
- [('mixed imports\\n stdlib: sys\\n relative: foo', 1)]
- >>> list(verify_stdlib_on_own_line(ast.parse('import sys, os')))
- []
- >>> list(verify_stdlib_on_own_line(ast.parse('import foo, bar')))
- []
- """
- for node in ast.walk(root):
- if isinstance(node, ast.Import):
- from_stdlib = {False: [], True: []}
- for n in node.names:
- from_stdlib[n.name in stdlib_modules].append(n.name)
- if from_stdlib[True] and from_stdlib[False]:
- yield (
- 'mixed imports\n stdlib: %s\n relative: %s'
- % (
- ', '.join(sorted(from_stdlib[True])),
- ', '.join(sorted(from_stdlib[False])),
- ),
- node.lineno,
- )
-
-
class CircularImport(Exception):
pass
@@ -679,7 +627,6 @@
All module names recorded in `imports` should be absolute one.
- >>> from __future__ import print_function
>>> imports = {'top.foo': ['top.bar', 'os.path', 'top.qux'],
... 'top.bar': ['top.baz', 'sys'],
... 'top.baz': ['top.foo'],
--- a/contrib/memory.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/memory.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,8 +11,6 @@
prints it to ``stderr`` on exit.
'''
-from __future__ import absolute_import
-
def memusage(ui):
"""Report memory usage of the current process."""
--- a/contrib/packaging/hgpackaging/cli.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/packaging/hgpackaging/cli.py Fri Mar 25 11:33:12 2022 -0400
@@ -20,13 +20,7 @@
SOURCE_DIR = HERE.parent.parent.parent
-def build_inno(pyoxidizer_target=None, python=None, iscc=None, version=None):
- if not pyoxidizer_target and not python:
- raise Exception("--python required unless building with PyOxidizer")
-
- if python and not os.path.isabs(python):
- raise Exception("--python arg must be an absolute path")
-
+def build_inno(pyoxidizer_target, iscc=None, version=None):
if iscc:
iscc = pathlib.Path(iscc)
else:
@@ -38,59 +32,30 @@
build_dir = SOURCE_DIR / "build"
- if pyoxidizer_target:
- inno.build_with_pyoxidizer(
- SOURCE_DIR, build_dir, pyoxidizer_target, iscc, version=version
- )
- else:
- inno.build_with_py2exe(
- SOURCE_DIR,
- build_dir,
- pathlib.Path(python),
- iscc,
- version=version,
- )
+ inno.build_with_pyoxidizer(
+ SOURCE_DIR, build_dir, pyoxidizer_target, iscc, version=version
+ )
def build_wix(
+ pyoxidizer_target,
name=None,
- pyoxidizer_target=None,
- python=None,
version=None,
sign_sn=None,
sign_cert=None,
sign_password=None,
sign_timestamp_url=None,
- extra_packages_script=None,
extra_wxs=None,
extra_features=None,
extra_pyoxidizer_vars=None,
):
- if not pyoxidizer_target and not python:
- raise Exception("--python required unless building with PyOxidizer")
-
- if python and not os.path.isabs(python):
- raise Exception("--python arg must be an absolute path")
-
kwargs = {
"source_dir": SOURCE_DIR,
"version": version,
+ "target_triple": pyoxidizer_target,
+ "extra_pyoxidizer_vars": extra_pyoxidizer_vars,
}
- if pyoxidizer_target:
- fn = wix.build_installer_pyoxidizer
- kwargs["target_triple"] = pyoxidizer_target
- kwargs["extra_pyoxidizer_vars"] = extra_pyoxidizer_vars
- else:
- fn = wix.build_installer_py2exe
- kwargs["python_exe"] = pathlib.Path(python)
-
- if extra_packages_script:
- if pyoxidizer_target:
- raise Exception(
- "pyoxidizer does not support --extra-packages-script"
- )
- kwargs["extra_packages_script"] = extra_packages_script
if extra_wxs:
kwargs["extra_wxs"] = dict(
thing.split("=") for thing in extra_wxs.split(",")
@@ -107,7 +72,7 @@
"timestamp_url": sign_timestamp_url,
}
- fn(**kwargs)
+ wix.build_installer_pyoxidizer(**kwargs)
def get_parser():
@@ -119,9 +84,9 @@
sp.add_argument(
"--pyoxidizer-target",
choices={"i686-pc-windows-msvc", "x86_64-pc-windows-msvc"},
+ required=True,
help="Build with PyOxidizer targeting this host triple",
)
- sp.add_argument("--python", help="path to python.exe to use")
sp.add_argument("--iscc", help="path to iscc.exe to use")
sp.add_argument(
"--version",
@@ -137,9 +102,9 @@
sp.add_argument(
"--pyoxidizer-target",
choices={"i686-pc-windows-msvc", "x86_64-pc-windows-msvc"},
+ required=True,
help="Build with PyOxidizer targeting this host triple",
)
- sp.add_argument("--python", help="Path to Python executable to use")
sp.add_argument(
"--sign-sn",
help="Subject name (or fragment thereof) of certificate "
@@ -155,12 +120,6 @@
)
sp.add_argument("--version", help="Version string to use")
sp.add_argument(
- "--extra-packages-script",
- help=(
- "Script to execute to include extra packages in " "py2exe binary."
- ),
- )
- sp.add_argument(
"--extra-wxs", help="CSV of path_to_wxs_file=working_dir_for_wxs_file"
)
sp.add_argument(
--- a/contrib/packaging/hgpackaging/downloads.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/packaging/hgpackaging/downloads.py Fri Mar 25 11:33:12 2022 -0400
@@ -25,48 +25,6 @@
'size': 715086,
'sha256': '411f94974492fd2ecf52590cb05b1023530aec67e64154a88b1e4ebcd9c28588',
},
- 'py2exe': {
- 'url': 'https://versaweb.dl.sourceforge.net/project/py2exe/py2exe/0.6.9/py2exe-0.6.9.zip',
- 'size': 149687,
- 'sha256': '6bd383312e7d33eef2e43a5f236f9445e4f3e0f6b16333c6f183ed445c44ddbd',
- 'version': '0.6.9',
- },
- # The VC9 CRT merge modules aren't readily available on most systems because
- # they are only installed as part of a full Visual Studio 2008 install.
- # While we could potentially extract them from a Visual Studio 2008
- # installer, it is easier to just fetch them from a known URL.
- 'vc9-crt-x86-msm': {
- 'url': 'https://github.com/indygreg/vc90-merge-modules/raw/9232f8f0b2135df619bf7946eaa176b4ac35ccff/Microsoft_VC90_CRT_x86.msm',
- 'size': 615424,
- 'sha256': '837e887ef31b332feb58156f429389de345cb94504228bb9a523c25a9dd3d75e',
- },
- 'vc9-crt-x86-msm-policy': {
- 'url': 'https://github.com/indygreg/vc90-merge-modules/raw/9232f8f0b2135df619bf7946eaa176b4ac35ccff/policy_9_0_Microsoft_VC90_CRT_x86.msm',
- 'size': 71168,
- 'sha256': '3fbcf92e3801a0757f36c5e8d304e134a68d5cafd197a6df7734ae3e8825c940',
- },
- 'vc9-crt-x64-msm': {
- 'url': 'https://github.com/indygreg/vc90-merge-modules/raw/9232f8f0b2135df619bf7946eaa176b4ac35ccff/Microsoft_VC90_CRT_x86_x64.msm',
- 'size': 662528,
- 'sha256': '50d9639b5ad4844a2285269c7551bf5157ec636e32396ddcc6f7ec5bce487a7c',
- },
- 'vc9-crt-x64-msm-policy': {
- 'url': 'https://github.com/indygreg/vc90-merge-modules/raw/9232f8f0b2135df619bf7946eaa176b4ac35ccff/policy_9_0_Microsoft_VC90_CRT_x86_x64.msm',
- 'size': 71168,
- 'sha256': '0550ea1929b21239134ad3a678c944ba0f05f11087117b6cf0833e7110686486',
- },
- 'virtualenv': {
- 'url': 'https://files.pythonhosted.org/packages/37/db/89d6b043b22052109da35416abc3c397655e4bd3cff031446ba02b9654fa/virtualenv-16.4.3.tar.gz',
- 'size': 3713208,
- 'sha256': '984d7e607b0a5d1329425dd8845bd971b957424b5ba664729fab51ab8c11bc39',
- 'version': '16.4.3',
- },
- 'wix': {
- 'url': 'https://github.com/wixtoolset/wix3/releases/download/wix3111rtm/wix311-binaries.zip',
- 'size': 34358269,
- 'sha256': '37f0a533b0978a454efb5dc3bd3598becf9660aaf4287e55bf68ca6b527d051d',
- 'version': '3.11.1',
- },
}
--- a/contrib/packaging/hgpackaging/inno.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/packaging/hgpackaging/inno.py Fri Mar 25 11:33:12 2022 -0400
@@ -14,29 +14,13 @@
import jinja2
-from .py2exe import (
- build_py2exe,
- stage_install,
-)
from .pyoxidizer import create_pyoxidizer_install_layout
from .util import (
- find_legacy_vc_runtime_files,
normalize_windows_version,
process_install_rules,
read_version_py,
)
-EXTRA_PACKAGES = {
- 'dulwich',
- 'keyring',
- 'pygments',
- 'win32ctypes',
-}
-
-EXTRA_INCLUDES = {
- '_curses',
- '_curses_panel',
-}
EXTRA_INSTALL_RULES = [
('contrib/win32/mercurial.ini', 'defaultrc/mercurial.rc'),
@@ -47,80 +31,6 @@
}
-def build_with_py2exe(
- source_dir: pathlib.Path,
- build_dir: pathlib.Path,
- python_exe: pathlib.Path,
- iscc_exe: pathlib.Path,
- version=None,
-):
- """Build the Inno installer using py2exe.
-
- Build files will be placed in ``build_dir``.
-
- py2exe's setup.py doesn't use setuptools. It doesn't have modern logic
- for finding the Python 2.7 toolchain. So, we require the environment
- to already be configured with an active toolchain.
- """
- if not iscc_exe.exists():
- raise Exception('%s does not exist' % iscc_exe)
-
- vc_x64 = r'\x64' in os.environ.get('LIB', '')
- arch = 'x64' if vc_x64 else 'x86'
- inno_build_dir = build_dir / ('inno-py2exe-%s' % arch)
- staging_dir = inno_build_dir / 'stage'
-
- requirements_txt = (
- source_dir / 'contrib' / 'packaging' / 'requirements-windows-py2.txt'
- )
-
- inno_build_dir.mkdir(parents=True, exist_ok=True)
-
- build_py2exe(
- source_dir,
- build_dir,
- python_exe,
- 'inno',
- requirements_txt,
- extra_packages=EXTRA_PACKAGES,
- extra_includes=EXTRA_INCLUDES,
- )
-
- # Purge the staging directory for every build so packaging is
- # pristine.
- if staging_dir.exists():
- print('purging %s' % staging_dir)
- shutil.rmtree(staging_dir)
-
- # Now assemble all the packaged files into the staging directory.
- stage_install(source_dir, staging_dir)
-
- # We also install some extra files.
- process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir)
-
- # hg.exe depends on VC9 runtime DLLs. Copy those into place.
- for f in find_legacy_vc_runtime_files(vc_x64):
- if f.name.endswith('.manifest'):
- basename = 'Microsoft.VC90.CRT.manifest'
- else:
- basename = f.name
-
- dest_path = staging_dir / basename
-
- print('copying %s to %s' % (f, dest_path))
- shutil.copyfile(f, dest_path)
-
- build_installer(
- source_dir,
- inno_build_dir,
- staging_dir,
- iscc_exe,
- version,
- arch="x64" if vc_x64 else None,
- suffix="-python2",
- )
-
-
def build_with_pyoxidizer(
source_dir: pathlib.Path,
build_dir: pathlib.Path,
--- a/contrib/packaging/hgpackaging/py2exe.py Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,248 +0,0 @@
-# py2exe.py - Functionality for performing py2exe builds.
-#
-# Copyright 2019 Gregory Szorc <gregory.szorc@gmail.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-# no-check-code because Python 3 native.
-
-import os
-import pathlib
-import subprocess
-
-from .downloads import download_entry
-from .util import (
- extract_tar_to_directory,
- extract_zip_to_directory,
- process_install_rules,
- python_exe_info,
-)
-
-
-STAGING_RULES = [
- ('contrib/bash_completion', 'contrib/'),
- ('contrib/hgk', 'contrib/hgk.tcl'),
- ('contrib/hgweb.fcgi', 'contrib/'),
- ('contrib/hgweb.wsgi', 'contrib/'),
- ('contrib/logo-droplets.svg', 'contrib/'),
- ('contrib/mercurial.el', 'contrib/'),
- ('contrib/mq.el', 'contrib/'),
- ('contrib/tcsh_completion', 'contrib/'),
- ('contrib/tcsh_completion_build.sh', 'contrib/'),
- ('contrib/vim/*', 'contrib/vim/'),
- ('contrib/win32/postinstall.txt', 'ReleaseNotes.txt'),
- ('contrib/win32/ReadMe.html', 'ReadMe.html'),
- ('contrib/xml.rnc', 'contrib/'),
- ('contrib/zsh_completion', 'contrib/'),
- ('dist/hg.exe', './'),
- ('dist/lib/*.dll', 'lib/'),
- ('dist/lib/*.pyd', 'lib/'),
- ('dist/lib/library.zip', 'lib/'),
- ('dist/Microsoft.VC*.CRT.manifest', './'),
- ('dist/msvc*.dll', './'),
- ('dist/python*.dll', './'),
- ('doc/*.html', 'doc/'),
- ('doc/style.css', 'doc/'),
- ('mercurial/helptext/**/*.txt', 'helptext/'),
- ('mercurial/defaultrc/*.rc', 'defaultrc/'),
- ('mercurial/locale/**/*', 'locale/'),
- ('mercurial/templates/**/*', 'templates/'),
- ('COPYING', 'Copying.txt'),
-]
-
-# List of paths to exclude from the staging area.
-STAGING_EXCLUDES = [
- 'doc/hg-ssh.8.html',
-]
-
-
-def build_py2exe(
- source_dir: pathlib.Path,
- build_dir: pathlib.Path,
- python_exe: pathlib.Path,
- build_name: str,
- venv_requirements_txt: pathlib.Path,
- extra_packages=None,
- extra_excludes=None,
- extra_dll_excludes=None,
- extra_packages_script=None,
- extra_includes=None,
-):
- """Build Mercurial with py2exe.
-
- Build files will be placed in ``build_dir``.
-
- py2exe's setup.py doesn't use setuptools. It doesn't have modern logic
- for finding the Python 2.7 toolchain. So, we require the environment
- to already be configured with an active toolchain.
- """
- if 'VCINSTALLDIR' not in os.environ:
- raise Exception(
- 'not running from a Visual C++ build environment; '
- 'execute the "Visual C++ <version> Command Prompt" '
- 'application shortcut or a vcsvarsall.bat file'
- )
-
- # Identity x86/x64 and validate the environment matches the Python
- # architecture.
- vc_x64 = r'\x64' in os.environ['LIB']
-
- py_info = python_exe_info(python_exe)
-
- if vc_x64:
- if py_info['arch'] != '64bit':
- raise Exception(
- 'architecture mismatch: Visual C++ environment '
- 'is configured for 64-bit but Python is 32-bit'
- )
- else:
- if py_info['arch'] != '32bit':
- raise Exception(
- 'architecture mismatch: Visual C++ environment '
- 'is configured for 32-bit but Python is 64-bit'
- )
-
- if py_info['py3']:
- raise Exception('Only Python 2 is currently supported')
-
- build_dir.mkdir(exist_ok=True)
-
- gettext_pkg, gettext_entry = download_entry('gettext', build_dir)
- gettext_dep_pkg = download_entry('gettext-dep', build_dir)[0]
- virtualenv_pkg, virtualenv_entry = download_entry('virtualenv', build_dir)
- py2exe_pkg, py2exe_entry = download_entry('py2exe', build_dir)
-
- venv_path = build_dir / (
- 'venv-%s-%s' % (build_name, 'x64' if vc_x64 else 'x86')
- )
-
- gettext_root = build_dir / ('gettext-win-%s' % gettext_entry['version'])
-
- if not gettext_root.exists():
- extract_zip_to_directory(gettext_pkg, gettext_root)
- extract_zip_to_directory(gettext_dep_pkg, gettext_root)
-
- # This assumes Python 2. We don't need virtualenv on Python 3.
- virtualenv_src_path = build_dir / (
- 'virtualenv-%s' % virtualenv_entry['version']
- )
- virtualenv_py = virtualenv_src_path / 'virtualenv.py'
-
- if not virtualenv_src_path.exists():
- extract_tar_to_directory(virtualenv_pkg, build_dir)
-
- py2exe_source_path = build_dir / ('py2exe-%s' % py2exe_entry['version'])
-
- if not py2exe_source_path.exists():
- extract_zip_to_directory(py2exe_pkg, build_dir)
-
- if not venv_path.exists():
- print('creating virtualenv with dependencies')
- subprocess.run(
- [str(python_exe), str(virtualenv_py), str(venv_path)], check=True
- )
-
- venv_python = venv_path / 'Scripts' / 'python.exe'
- venv_pip = venv_path / 'Scripts' / 'pip.exe'
-
- subprocess.run(
- [str(venv_pip), 'install', '-r', str(venv_requirements_txt)], check=True
- )
-
- # Force distutils to use VC++ settings from environment, which was
- # validated above.
- env = dict(os.environ)
- env['DISTUTILS_USE_SDK'] = '1'
- env['MSSdk'] = '1'
-
- if extra_packages_script:
- more_packages = set(
- subprocess.check_output(extra_packages_script, cwd=build_dir)
- .split(b'\0')[-1]
- .strip()
- .decode('utf-8')
- .splitlines()
- )
- if more_packages:
- if not extra_packages:
- extra_packages = more_packages
- else:
- extra_packages |= more_packages
-
- if extra_packages:
- env['HG_PY2EXE_EXTRA_PACKAGES'] = ' '.join(sorted(extra_packages))
- hgext3rd_extras = sorted(
- e for e in extra_packages if e.startswith('hgext3rd.')
- )
- if hgext3rd_extras:
- env['HG_PY2EXE_EXTRA_INSTALL_PACKAGES'] = ' '.join(hgext3rd_extras)
- if extra_includes:
- env['HG_PY2EXE_EXTRA_INCLUDES'] = ' '.join(sorted(extra_includes))
- if extra_excludes:
- env['HG_PY2EXE_EXTRA_EXCLUDES'] = ' '.join(sorted(extra_excludes))
- if extra_dll_excludes:
- env['HG_PY2EXE_EXTRA_DLL_EXCLUDES'] = ' '.join(
- sorted(extra_dll_excludes)
- )
-
- py2exe_py_path = venv_path / 'Lib' / 'site-packages' / 'py2exe'
- if not py2exe_py_path.exists():
- print('building py2exe')
- subprocess.run(
- [str(venv_python), 'setup.py', 'install'],
- cwd=py2exe_source_path,
- env=env,
- check=True,
- )
-
- # Register location of msgfmt and other binaries.
- env['PATH'] = '%s%s%s' % (
- env['PATH'],
- os.pathsep,
- str(gettext_root / 'bin'),
- )
-
- print('building Mercurial')
- subprocess.run(
- [str(venv_python), 'setup.py', 'py2exe', 'build_doc', '--html'],
- cwd=str(source_dir),
- env=env,
- check=True,
- )
-
-
-def stage_install(
- source_dir: pathlib.Path, staging_dir: pathlib.Path, lower_case=False
-):
- """Copy all files to be installed to a directory.
-
- This allows packaging to simply walk a directory tree to find source
- files.
- """
- if lower_case:
- rules = []
- for source, dest in STAGING_RULES:
- # Only lower directory names.
- if '/' in dest:
- parent, leaf = dest.rsplit('/', 1)
- dest = '%s/%s' % (parent.lower(), leaf)
- rules.append((source, dest))
- else:
- rules = STAGING_RULES
-
- process_install_rules(rules, source_dir, staging_dir)
-
- # Write out a default editor.rc file to configure notepad as the
- # default editor.
- with (staging_dir / 'defaultrc' / 'editor.rc').open(
- 'w', encoding='utf-8'
- ) as fh:
- fh.write('[ui]\neditor = notepad\n')
-
- # Purge any files we don't want to be there.
- for f in STAGING_EXCLUDES:
- p = staging_dir / f
- if p.exists():
- print('removing %s' % p)
- p.unlink()
--- a/contrib/packaging/hgpackaging/util.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/packaging/hgpackaging/util.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,23 +7,15 @@
# no-check-code because Python 3 native.
-import distutils.version
-import getpass
import glob
import os
import pathlib
import re
import shutil
import subprocess
-import tarfile
import zipfile
-def extract_tar_to_directory(source: pathlib.Path, dest: pathlib.Path):
- with tarfile.open(source, 'r') as tf:
- tf.extractall(dest)
-
-
def extract_zip_to_directory(source: pathlib.Path, dest: pathlib.Path):
with zipfile.ZipFile(source, 'r') as zf:
zf.extractall(dest)
@@ -81,59 +73,6 @@
raise Exception("could not find vcruntime140.dll")
-def find_legacy_vc_runtime_files(x64=False):
- """Finds Visual C++ Runtime DLLs to include in distribution."""
- winsxs = pathlib.Path(os.environ['SYSTEMROOT']) / 'WinSxS'
-
- prefix = 'amd64' if x64 else 'x86'
-
- candidates = sorted(
- p
- for p in os.listdir(winsxs)
- if p.lower().startswith('%s_microsoft.vc90.crt_' % prefix)
- )
-
- for p in candidates:
- print('found candidate VC runtime: %s' % p)
-
- # Take the newest version.
- version = candidates[-1]
-
- d = winsxs / version
-
- return [
- d / 'msvcm90.dll',
- d / 'msvcp90.dll',
- d / 'msvcr90.dll',
- winsxs / 'Manifests' / ('%s.manifest' % version),
- ]
-
-
-def windows_10_sdk_info():
- """Resolves information about the Windows 10 SDK."""
-
- base = pathlib.Path(os.environ['ProgramFiles(x86)']) / 'Windows Kits' / '10'
-
- if not base.is_dir():
- raise Exception('unable to find Windows 10 SDK at %s' % base)
-
- # Find the latest version.
- bin_base = base / 'bin'
-
- versions = [v for v in os.listdir(bin_base) if v.startswith('10.')]
- version = sorted(versions, reverse=True)[0]
-
- bin_version = bin_base / version
-
- return {
- 'root': base,
- 'version': version,
- 'bin_root': bin_version,
- 'bin_x86': bin_version / 'x86',
- 'bin_x64': bin_version / 'x64',
- }
-
-
def normalize_windows_version(version):
"""Normalize Mercurial version string so WiX/Inno accepts it.
@@ -194,93 +133,6 @@
return '.'.join('%d' % x for x in versions[0:4])
-def find_signtool():
- """Find signtool.exe from the Windows SDK."""
- sdk = windows_10_sdk_info()
-
- for key in ('bin_x64', 'bin_x86'):
- p = sdk[key] / 'signtool.exe'
-
- if p.exists():
- return p
-
- raise Exception('could not find signtool.exe in Windows 10 SDK')
-
-
-def sign_with_signtool(
- file_path,
- description,
- subject_name=None,
- cert_path=None,
- cert_password=None,
- timestamp_url=None,
-):
- """Digitally sign a file with signtool.exe.
-
- ``file_path`` is file to sign.
- ``description`` is text that goes in the signature.
-
- The signing certificate can be specified by ``cert_path`` or
- ``subject_name``. These correspond to the ``/f`` and ``/n`` arguments
- to signtool.exe, respectively.
-
- The certificate password can be specified via ``cert_password``. If
- not provided, you will be prompted for the password.
-
- ``timestamp_url`` is the URL of a RFC 3161 timestamp server (``/tr``
- argument to signtool.exe).
- """
- if cert_path and subject_name:
- raise ValueError('cannot specify both cert_path and subject_name')
-
- while cert_path and not cert_password:
- cert_password = getpass.getpass('password for %s: ' % cert_path)
-
- args = [
- str(find_signtool()),
- 'sign',
- '/v',
- '/fd',
- 'sha256',
- '/d',
- description,
- ]
-
- if cert_path:
- args.extend(['/f', str(cert_path), '/p', cert_password])
- elif subject_name:
- args.extend(['/n', subject_name])
-
- if timestamp_url:
- args.extend(['/tr', timestamp_url, '/td', 'sha256'])
-
- args.append(str(file_path))
-
- print('signing %s' % file_path)
- subprocess.run(args, check=True)
-
-
-PRINT_PYTHON_INFO = '''
-import platform; print("%s:%s" % (platform.architecture()[0], platform.python_version()))
-'''.strip()
-
-
-def python_exe_info(python_exe: pathlib.Path):
- """Obtain information about a Python executable."""
-
- res = subprocess.check_output([str(python_exe), '-c', PRINT_PYTHON_INFO])
-
- arch, version = res.decode('utf-8').split(':')
-
- version = distutils.version.LooseVersion(version)
-
- return {
- 'arch': arch,
- 'version': version,
- 'py3': version >= distutils.version.LooseVersion('3'),
- }
-
-
def process_install_rules(
rules: list, source_dir: pathlib.Path, dest_dir: pathlib.Path
):
--- a/contrib/packaging/hgpackaging/wix.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/packaging/hgpackaging/wix.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,376 +7,16 @@
# no-check-code because Python 3 native.
-import collections
import json
import os
import pathlib
-import re
import shutil
-import subprocess
import typing
-import uuid
-import xml.dom.minidom
-from .downloads import download_entry
-from .py2exe import (
- build_py2exe,
- stage_install,
-)
from .pyoxidizer import (
build_docs_html,
- create_pyoxidizer_install_layout,
run_pyoxidizer,
)
-from .util import (
- extract_zip_to_directory,
- normalize_windows_version,
- process_install_rules,
- sign_with_signtool,
-)
-
-
-EXTRA_PACKAGES = {
- 'dulwich',
- 'distutils',
- 'keyring',
- 'pygments',
- 'win32ctypes',
-}
-
-EXTRA_INCLUDES = {
- '_curses',
- '_curses_panel',
-}
-
-EXTRA_INSTALL_RULES = [
- ('contrib/packaging/wix/COPYING.rtf', 'COPYING.rtf'),
- ('contrib/win32/mercurial.ini', 'defaultrc/mercurial.rc'),
-]
-
-STAGING_REMOVE_FILES = [
- # We use the RTF variant.
- 'copying.txt',
-]
-
-SHORTCUTS = {
- # hg.1.html'
- 'hg.file.5d3e441c_28d9_5542_afd0_cdd4234f12d5': {
- 'Name': 'Mercurial Command Reference',
- },
- # hgignore.5.html
- 'hg.file.5757d8e0_f207_5e10_a2ec_3ba0a062f431': {
- 'Name': 'Mercurial Ignore Files',
- },
- # hgrc.5.html
- 'hg.file.92e605fd_1d1a_5dc6_9fc0_5d2998eb8f5e': {
- 'Name': 'Mercurial Configuration Files',
- },
-}
-
-
-def find_version(source_dir: pathlib.Path):
- version_py = source_dir / 'mercurial' / '__version__.py'
-
- with version_py.open('r', encoding='utf-8') as fh:
- source = fh.read().strip()
-
- m = re.search('version = b"(.*)"', source)
- return m.group(1)
-
-
-def ensure_vc90_merge_modules(build_dir):
- x86 = (
- download_entry(
- 'vc9-crt-x86-msm',
- build_dir,
- local_name='microsoft.vcxx.crt.x86_msm.msm',
- )[0],
- download_entry(
- 'vc9-crt-x86-msm-policy',
- build_dir,
- local_name='policy.x.xx.microsoft.vcxx.crt.x86_msm.msm',
- )[0],
- )
-
- x64 = (
- download_entry(
- 'vc9-crt-x64-msm',
- build_dir,
- local_name='microsoft.vcxx.crt.x64_msm.msm',
- )[0],
- download_entry(
- 'vc9-crt-x64-msm-policy',
- build_dir,
- local_name='policy.x.xx.microsoft.vcxx.crt.x64_msm.msm',
- )[0],
- )
- return {
- 'x86': x86,
- 'x64': x64,
- }
-
-
-def run_candle(wix, cwd, wxs, source_dir, defines=None):
- args = [
- str(wix / 'candle.exe'),
- '-nologo',
- str(wxs),
- '-dSourceDir=%s' % source_dir,
- ]
-
- if defines:
- args.extend('-d%s=%s' % define for define in sorted(defines.items()))
-
- subprocess.run(args, cwd=str(cwd), check=True)
-
-
-def make_files_xml(staging_dir: pathlib.Path, is_x64) -> str:
- """Create XML string listing every file to be installed."""
-
- # We derive GUIDs from a deterministic file path identifier.
- # We shoehorn the name into something that looks like a URL because
- # the UUID namespaces are supposed to work that way (even though
- # the input data probably is never validated).
-
- doc = xml.dom.minidom.parseString(
- '<?xml version="1.0" encoding="utf-8"?>'
- '<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi">'
- '</Wix>'
- )
-
- # Assemble the install layout by directory. This makes it easier to
- # emit XML, since each directory has separate entities.
- manifest = collections.defaultdict(dict)
-
- for root, dirs, files in os.walk(staging_dir):
- dirs.sort()
-
- root = pathlib.Path(root)
- rel_dir = root.relative_to(staging_dir)
-
- for i in range(len(rel_dir.parts)):
- parent = '/'.join(rel_dir.parts[0 : i + 1])
- manifest.setdefault(parent, {})
-
- for f in sorted(files):
- full = root / f
- manifest[str(rel_dir).replace('\\', '/')][full.name] = full
-
- component_groups = collections.defaultdict(list)
-
- # Now emit a <Fragment> for each directory.
- # Each directory is composed of a <DirectoryRef> pointing to its parent
- # and defines child <Directory>'s and a <Component> with all the files.
- for dir_name, entries in sorted(manifest.items()):
- # The directory id is derived from the path. But the root directory
- # is special.
- if dir_name == '.':
- parent_directory_id = 'INSTALLDIR'
- else:
- parent_directory_id = 'hg.dir.%s' % dir_name.replace(
- '/', '.'
- ).replace('-', '_')
-
- fragment = doc.createElement('Fragment')
- directory_ref = doc.createElement('DirectoryRef')
- directory_ref.setAttribute('Id', parent_directory_id)
-
- # Add <Directory> entries for immediate children directories.
- for possible_child in sorted(manifest.keys()):
- if (
- dir_name == '.'
- and '/' not in possible_child
- and possible_child != '.'
- ):
- child_directory_id = ('hg.dir.%s' % possible_child).replace(
- '-', '_'
- )
- name = possible_child
- else:
- if not possible_child.startswith('%s/' % dir_name):
- continue
- name = possible_child[len(dir_name) + 1 :]
- if '/' in name:
- continue
-
- child_directory_id = 'hg.dir.%s' % possible_child.replace(
- '/', '.'
- ).replace('-', '_')
-
- directory = doc.createElement('Directory')
- directory.setAttribute('Id', child_directory_id)
- directory.setAttribute('Name', name)
- directory_ref.appendChild(directory)
-
- # Add <Component>s for files in this directory.
- for rel, source_path in sorted(entries.items()):
- if dir_name == '.':
- full_rel = rel
- else:
- full_rel = '%s/%s' % (dir_name, rel)
-
- component_unique_id = (
- 'https://www.mercurial-scm.org/wix-installer/0/component/%s'
- % full_rel
- )
- component_guid = uuid.uuid5(uuid.NAMESPACE_URL, component_unique_id)
- component_id = 'hg.component.%s' % str(component_guid).replace(
- '-', '_'
- )
-
- component = doc.createElement('Component')
-
- component.setAttribute('Id', component_id)
- component.setAttribute('Guid', str(component_guid).upper())
- component.setAttribute('Win64', 'yes' if is_x64 else 'no')
-
- # Assign this component to a top-level group.
- if dir_name == '.':
- component_groups['ROOT'].append(component_id)
- elif '/' in dir_name:
- component_groups[dir_name[0 : dir_name.index('/')]].append(
- component_id
- )
- else:
- component_groups[dir_name].append(component_id)
-
- unique_id = (
- 'https://www.mercurial-scm.org/wix-installer/0/%s' % full_rel
- )
- file_guid = uuid.uuid5(uuid.NAMESPACE_URL, unique_id)
-
- # IDs have length limits. So use GUID to derive them.
- file_guid_normalized = str(file_guid).replace('-', '_')
- file_id = 'hg.file.%s' % file_guid_normalized
-
- file_element = doc.createElement('File')
- file_element.setAttribute('Id', file_id)
- file_element.setAttribute('Source', str(source_path))
- file_element.setAttribute('KeyPath', 'yes')
- file_element.setAttribute('ReadOnly', 'yes')
-
- component.appendChild(file_element)
- directory_ref.appendChild(component)
-
- fragment.appendChild(directory_ref)
- doc.documentElement.appendChild(fragment)
-
- for group, component_ids in sorted(component_groups.items()):
- fragment = doc.createElement('Fragment')
- component_group = doc.createElement('ComponentGroup')
- component_group.setAttribute('Id', 'hg.group.%s' % group)
-
- for component_id in component_ids:
- component_ref = doc.createElement('ComponentRef')
- component_ref.setAttribute('Id', component_id)
- component_group.appendChild(component_ref)
-
- fragment.appendChild(component_group)
- doc.documentElement.appendChild(fragment)
-
- # Add <Shortcut> to files that have it defined.
- for file_id, metadata in sorted(SHORTCUTS.items()):
- els = doc.getElementsByTagName('File')
- els = [el for el in els if el.getAttribute('Id') == file_id]
-
- if not els:
- raise Exception('could not find File[Id=%s]' % file_id)
-
- for el in els:
- shortcut = doc.createElement('Shortcut')
- shortcut.setAttribute('Id', 'hg.shortcut.%s' % file_id)
- shortcut.setAttribute('Directory', 'ProgramMenuDir')
- shortcut.setAttribute('Icon', 'hgIcon.ico')
- shortcut.setAttribute('IconIndex', '0')
- shortcut.setAttribute('Advertise', 'yes')
- for k, v in sorted(metadata.items()):
- shortcut.setAttribute(k, v)
-
- el.appendChild(shortcut)
-
- return doc.toprettyxml()
-
-
-def build_installer_py2exe(
- source_dir: pathlib.Path,
- python_exe: pathlib.Path,
- msi_name='mercurial',
- version=None,
- extra_packages_script=None,
- extra_wxs: typing.Optional[typing.Dict[str, str]] = None,
- extra_features: typing.Optional[typing.List[str]] = None,
- signing_info: typing.Optional[typing.Dict[str, str]] = None,
-):
- """Build a WiX MSI installer using py2exe.
-
- ``source_dir`` is the path to the Mercurial source tree to use.
- ``arch`` is the target architecture. either ``x86`` or ``x64``.
- ``python_exe`` is the path to the Python executable to use/bundle.
- ``version`` is the Mercurial version string. If not defined,
- ``mercurial/__version__.py`` will be consulted.
- ``extra_packages_script`` is a command to be run to inject extra packages
- into the py2exe binary. It should stage packages into the virtualenv and
- print a null byte followed by a newline-separated list of packages that
- should be included in the exe.
- ``extra_wxs`` is a dict of {wxs_name: working_dir_for_wxs_build}.
- ``extra_features`` is a list of additional named Features to include in
- the build. These must match Feature names in one of the wxs scripts.
- """
- arch = 'x64' if r'\x64' in os.environ.get('LIB', '') else 'x86'
-
- hg_build_dir = source_dir / 'build'
-
- requirements_txt = (
- source_dir / 'contrib' / 'packaging' / 'requirements-windows-py2.txt'
- )
-
- build_py2exe(
- source_dir,
- hg_build_dir,
- python_exe,
- 'wix',
- requirements_txt,
- extra_packages=EXTRA_PACKAGES,
- extra_packages_script=extra_packages_script,
- extra_includes=EXTRA_INCLUDES,
- )
-
- build_dir = hg_build_dir / ('wix-%s' % arch)
- staging_dir = build_dir / 'stage'
-
- build_dir.mkdir(exist_ok=True)
-
- # Purge the staging directory for every build so packaging is pristine.
- if staging_dir.exists():
- print('purging %s' % staging_dir)
- shutil.rmtree(staging_dir)
-
- stage_install(source_dir, staging_dir, lower_case=True)
-
- # We also install some extra files.
- process_install_rules(EXTRA_INSTALL_RULES, source_dir, staging_dir)
-
- # And remove some files we don't want.
- for f in STAGING_REMOVE_FILES:
- p = staging_dir / f
- if p.exists():
- print('removing %s' % p)
- p.unlink()
-
- return run_wix_packaging(
- source_dir,
- build_dir,
- staging_dir,
- arch,
- version=version,
- python2=True,
- msi_name=msi_name,
- suffix="-python2",
- extra_wxs=extra_wxs,
- extra_features=extra_features,
- signing_info=signing_info,
- )
def build_installer_pyoxidizer(
@@ -454,133 +94,3 @@
return {
"msi_path": dist_path,
}
-
-
-def run_wix_packaging(
- source_dir: pathlib.Path,
- build_dir: pathlib.Path,
- staging_dir: pathlib.Path,
- arch: str,
- version: str,
- python2: bool,
- msi_name: typing.Optional[str] = "mercurial",
- suffix: str = "",
- extra_wxs: typing.Optional[typing.Dict[str, str]] = None,
- extra_features: typing.Optional[typing.List[str]] = None,
- signing_info: typing.Optional[typing.Dict[str, str]] = None,
-):
- """Invokes WiX to package up a built Mercurial.
-
- ``signing_info`` is a dict defining properties to facilitate signing the
- installer. Recognized keys include ``name``, ``subject_name``,
- ``cert_path``, ``cert_password``, and ``timestamp_url``. If populated,
- we will sign both the hg.exe and the .msi using the signing credentials
- specified.
- """
-
- orig_version = version or find_version(source_dir)
- version = normalize_windows_version(orig_version)
- print('using version string: %s' % version)
- if version != orig_version:
- print('(normalized from: %s)' % orig_version)
-
- if signing_info:
- sign_with_signtool(
- staging_dir / "hg.exe",
- "%s %s" % (signing_info["name"], version),
- subject_name=signing_info["subject_name"],
- cert_path=signing_info["cert_path"],
- cert_password=signing_info["cert_password"],
- timestamp_url=signing_info["timestamp_url"],
- )
-
- wix_dir = source_dir / 'contrib' / 'packaging' / 'wix'
-
- wix_pkg, wix_entry = download_entry('wix', build_dir)
- wix_path = build_dir / ('wix-%s' % wix_entry['version'])
-
- if not wix_path.exists():
- extract_zip_to_directory(wix_pkg, wix_path)
-
- if python2:
- ensure_vc90_merge_modules(build_dir)
-
- source_build_rel = pathlib.Path(os.path.relpath(source_dir, build_dir))
-
- defines = {'Platform': arch}
-
- # Derive a .wxs file with the staged files.
- manifest_wxs = build_dir / 'stage.wxs'
- with manifest_wxs.open('w', encoding='utf-8') as fh:
- fh.write(make_files_xml(staging_dir, is_x64=arch == 'x64'))
-
- run_candle(wix_path, build_dir, manifest_wxs, staging_dir, defines=defines)
-
- for source, rel_path in sorted((extra_wxs or {}).items()):
- run_candle(wix_path, build_dir, source, rel_path, defines=defines)
-
- source = wix_dir / 'mercurial.wxs'
- defines['Version'] = version
- defines['Comments'] = 'Installs Mercurial version %s' % version
-
- if python2:
- defines["PythonVersion"] = "2"
- defines['VCRedistSrcDir'] = str(build_dir)
- else:
- defines["PythonVersion"] = "3"
-
- if (staging_dir / "lib").exists():
- defines["MercurialHasLib"] = "1"
-
- if extra_features:
- assert all(';' not in f for f in extra_features)
- defines['MercurialExtraFeatures'] = ';'.join(extra_features)
-
- run_candle(wix_path, build_dir, source, source_build_rel, defines=defines)
-
- msi_path = (
- source_dir
- / 'dist'
- / ('%s-%s-%s%s.msi' % (msi_name, orig_version, arch, suffix))
- )
-
- args = [
- str(wix_path / 'light.exe'),
- '-nologo',
- '-ext',
- 'WixUIExtension',
- '-sw1076',
- '-spdb',
- '-o',
- str(msi_path),
- ]
-
- for source, rel_path in sorted((extra_wxs or {}).items()):
- assert source.endswith('.wxs')
- source = os.path.basename(source)
- args.append(str(build_dir / ('%s.wixobj' % source[:-4])))
-
- args.extend(
- [
- str(build_dir / 'stage.wixobj'),
- str(build_dir / 'mercurial.wixobj'),
- ]
- )
-
- subprocess.run(args, cwd=str(source_dir), check=True)
-
- print('%s created' % msi_path)
-
- if signing_info:
- sign_with_signtool(
- msi_path,
- "%s %s" % (signing_info["name"], version),
- subject_name=signing_info["subject_name"],
- cert_path=signing_info["cert_path"],
- cert_password=signing_info["cert_password"],
- timestamp_url=signing_info["timestamp_url"],
- )
-
- return {
- 'msi_path': msi_path,
- }
--- a/contrib/packaging/requirements-windows-py2.txt Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,59 +0,0 @@
-#
-# This file is autogenerated by pip-compile
-# To update, run:
-#
-# pip-compile --generate-hashes --output-file=contrib/packaging/requirements-windows-py2.txt contrib/packaging/requirements-windows.txt.in
-#
-certifi==2021.5.30 \
- --hash=sha256:2bbf76fd432960138b3ef6dda3dde0544f27cbf8546c458e60baf371917ba9ee \
- --hash=sha256:50b1e4f8446b06f41be7dd6338db18e0990601dce795c2b1686458aa7e8fa7d8 \
- # via dulwich
-configparser==4.0.2 \
- --hash=sha256:254c1d9c79f60c45dfde850850883d5aaa7f19a23f13561243a050d5a7c3fe4c \
- --hash=sha256:c7d282687a5308319bf3d2e7706e575c635b0a470342641c93bea0ea3b5331df \
- # via entrypoints
-docutils==0.16 \
- --hash=sha256:0c5b78adfbf7762415433f5515cd5c9e762339e23369dbe8000d84a4bf4ab3af \
- --hash=sha256:c2de3a60e9e7d07be26b7f2b00ca0309c207e06c100f9cc2a94931fc75a478fc \
- # via -r contrib/packaging/requirements-windows.txt.in
-dulwich==0.19.16 ; python_version <= "2.7" \
- --hash=sha256:10699277c6268d0c16febe141a5b1c1a6e9744f3144c2d2de1706f4b1adafe63 \
- --hash=sha256:267160904e9a1cb6c248c5efc53597a35d038ecc6f60bdc4546b3053bed11982 \
- --hash=sha256:4e3aba5e4844e7c700721c1fc696987ea820ee3528a03604dc4e74eff4196826 \
- --hash=sha256:60bb2c2c92f5025c1b53a556304008f0f624c98ae36f22d870e056b2d4236c11 \
- --hash=sha256:dddae02d372fc3b5cfb0046d0f62246ef281fa0c088df7601ab5916607add94b \
- --hash=sha256:f00d132082b8fcc2eb0d722abc773d4aeb5558c1475d7edd1f0f571146c29db9 \
- --hash=sha256:f74561c448bfb6f04c07de731c1181ae4280017f759b0bb04fa5770aa84ca850 \
- # via -r contrib/packaging/requirements-windows.txt.in
-entrypoints==0.3 \
- --hash=sha256:589f874b313739ad35be6e0cd7efde2a4e9b6fea91edcc34e58ecbb8dbe56d19 \
- --hash=sha256:c70dd71abe5a8c85e55e12c19bd91ccfeec11a6e99044204511f9ed547d48451 \
- # via keyring
-keyring==18.0.1 \
- --hash=sha256:67d6cc0132bd77922725fae9f18366bb314fd8f95ff4d323a4df41890a96a838 \
- --hash=sha256:7b29ebfcf8678c4da531b2478a912eea01e80007e5ddca9ee0c7038cb3489ec6 \
- # via -r contrib/packaging/requirements-windows.txt.in
-pygments==2.5.2 \
- --hash=sha256:2a3fe295e54a20164a9df49c75fa58526d3be48e14aceba6d6b1e8ac0bfd6f1b \
- --hash=sha256:98c8aa5a9f778fcd1026a17361ddaf7330d1b7c62ae97c3bb0ae73e0b9b6b0fe \
- # via -r contrib/packaging/requirements-windows.txt.in
-pywin32-ctypes==0.2.0 \
- --hash=sha256:24ffc3b341d457d48e8922352130cf2644024a4ff09762a2261fd34c36ee5942 \
- --hash=sha256:9dc2d991b3479cc2df15930958b674a48a227d5361d413827a4cfd0b5876fc98 \
- # via -r contrib/packaging/requirements-windows.txt.in, keyring
-urllib3==1.25.11 \
- --hash=sha256:8d7eaa5a82a1cac232164990f04874c594c9453ec55eef02eab885aa02fc17a2 \
- --hash=sha256:f5321fbe4bf3fefa0efd0bfe7fb14e90909eb62a48ccda331726b4319897dd5e \
- # via dulwich
-windows-curses==2.1.0 \
- --hash=sha256:261fde5680d1ce4ce116908996b9a3cfb0ffb03ea68d42240f62b56a9fa6af2c \
- --hash=sha256:66034dc9a705d87308cc9ea90836f4ee60008a1d5e2c1d34ace627f60268158b \
- --hash=sha256:669caad3ae16faf2d201d7ab3b8af418a2fd074d8a39d60ca26f3acb34b6afe5 \
- --hash=sha256:73bd3eebccfda55330783f165151de115bfa238d1332f0b2e224b550d6187840 \
- --hash=sha256:89a6d973f88cfe49b41ea80164dcbec209d296e0cec34a02002578b0bf464a64 \
- --hash=sha256:8ba7c000d7ffa5452bbd0966b96e69261e4f117ebe510aeb8771a9650197b7f0 \
- --hash=sha256:97084c6b37b1534f6a28a514d521dfae402f77dcbad42b14ee32e8d5bdc13648 \
- --hash=sha256:9e474a181f96d60429a4766145628264e60b72e7715876f9135aeb2e842f9433 \
- --hash=sha256:cfe64c30807c146ef8d094412f90f2a2c81ad6aefff3ebfe8e37aabe2f801303 \
- --hash=sha256:ff8c67f74b88944d99fa9d22971c05c335bc74f149120f0a69340c2c3a595497 \
- # via -r contrib/packaging/requirements-windows.txt.in
--- a/contrib/packaging/requirements-windows.txt.in Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/packaging/requirements-windows.txt.in Fri Mar 25 11:33:12 2022 -0400
@@ -1,13 +1,11 @@
docutils
-# Pinned to an old version because 0.20 drops Python 3 compatibility.
-dulwich < 0.20 ; python_version <= '2.7'
-dulwich ; python_version >= '3'
+dulwich
# Needed by the release note tooling
fuzzywuzzy
keyring
-pygit2 ; python_version >= '3'
+pygit2
pygments
# Needed by the phabricator tests
--- a/contrib/perf-utils/perf-revlog-write-plot.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/perf-utils/perf-revlog-write-plot.py Fri Mar 25 11:33:12 2022 -0400
@@ -9,7 +9,6 @@
# various plot related to write performance in a revlog
#
# usage: perf-revlog-write-plot.py details.json
-from __future__ import absolute_import, print_function
import json
import re
--- a/contrib/perf-utils/search-discovery-case Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/perf-utils/search-discovery-case Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This use a subsetmaker extension (next to this script) to generate a steam of
# random discovery instance. When interesting case are discovered, information
# about them are print on the stdout.
-from __future__ import print_function
import json
import os
--- a/contrib/perf.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/perf.py Fri Mar 25 11:33:12 2022 -0400
@@ -54,7 +54,6 @@
# - make perf command for recent feature work correctly with early
# Mercurial
-from __future__ import absolute_import
import contextlib
import functools
import gc
@@ -370,7 +369,7 @@
return len
-class noop(object):
+class noop:
"""dummy context manager"""
def __enter__(self):
@@ -414,7 +413,7 @@
# available since 2.2 (or ae5f92e154d3)
from mercurial import node
- class defaultformatter(object):
+ class defaultformatter:
"""Minimized composition of baseformatter and plainformatter"""
def __init__(self, ui, topic, opts):
@@ -653,7 +652,7 @@
origvalue = getattr(obj, _sysstr(name))
- class attrutil(object):
+ class attrutil:
def set(self, newvalue):
setattr(obj, _sysstr(name), newvalue)
@@ -2943,7 +2942,7 @@
fm.end()
-class _faketr(object):
+class _faketr:
def add(s, x, y, z=None):
return None
--- a/contrib/phab-clean.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/phab-clean.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# 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
--- a/contrib/python-hook-examples.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/python-hook-examples.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
'''
Examples of useful python hooks for Mercurial.
'''
-from __future__ import absolute_import
from mercurial import (
patch,
util,
--- a/contrib/python-zstandard/make_cffi.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/python-zstandard/make_cffi.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
# This software may be modified and distributed under the terms
# of the BSD license. See the LICENSE file for details.
-from __future__ import absolute_import
import cffi
import distutils.ccompiler
--- a/contrib/python-zstandard/setup.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/python-zstandard/setup.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be modified and distributed under the terms
# of the BSD license. See the LICENSE file for details.
-from __future__ import print_function
from distutils.version import LooseVersion
import os
--- a/contrib/python-zstandard/tests/test_module_attributes.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/python-zstandard/tests/test_module_attributes.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import unicode_literals
-
import unittest
import zstandard as zstd
--- a/contrib/python-zstandard/zstandard/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/python-zstandard/zstandard/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
"""Python interface to the Zstandard (zstd) compression library."""
-from __future__ import absolute_import, unicode_literals
# This module serves 2 roles:
#
--- a/contrib/python-zstandard/zstandard/cffi.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/python-zstandard/zstandard/cffi.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
"""Python interface to the Zstandard (zstd) compression library."""
-from __future__ import absolute_import, unicode_literals
# This should match what the C extension exports.
__all__ = [
--- a/contrib/python3-ratchet.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/python3-ratchet.py Fri Mar 25 11:33:12 2022 -0400
@@ -15,8 +15,6 @@
$ python3 ../contrib/python3-ratchet.py \
> --working-tests=../contrib/python3-whitelist
"""
-from __future__ import print_function
-from __future__ import absolute_import
import argparse
import json
--- a/contrib/revsetbenchmarks.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/revsetbenchmarks.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
#
# call with --help for details
-from __future__ import absolute_import, print_function
import math
import optparse # cannot use argparse, python 2.7 only
import os
--- a/contrib/showstack.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/showstack.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
r"""dump stack trace when receiving SIGQUIT (Ctrl-\) or SIGINFO (Ctrl-T on BSDs)
"""
-from __future__ import absolute_import, print_function
import signal
import sys
import traceback
--- a/contrib/simplemerge Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/simplemerge Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-from __future__ import absolute_import
import getopt
import sys
--- a/contrib/synthrepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/synthrepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -36,7 +36,6 @@
- Symlinks and binary files are ignored
'''
-from __future__ import absolute_import
import bisect
import collections
import itertools
@@ -213,7 +212,7 @@
for filename, mar, lineadd, lineremove, isbin in parsegitdiff(diff):
if isbin:
continue
- added = sum(pycompat.itervalues(lineadd), 0)
+ added = sum(lineadd.values(), 0)
if mar == 'm':
if added and lineremove:
lineschanged[
--- a/contrib/testparseutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/testparseutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import abc
import re
@@ -80,7 +79,7 @@
####################
-class embeddedmatcher(object): # pytype: disable=ignored-metaclass
+class embeddedmatcher: # pytype: disable=ignored-metaclass
"""Base class to detect embedded code fragments in *.t test script"""
__metaclass__ = abc.ABCMeta
@@ -157,7 +156,7 @@
:ends: line number (1-origin), at which embedded code ends (exclusive)
:code: extracted embedded code, which is single-stringified
- >>> class ambigmatcher(object):
+ >>> class ambigmatcher:
... # mock matcher class to examine implementation of
... # "ambiguous matching" corner case
... def __init__(self, desc, matchfunc):
--- a/contrib/undumprevlog Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/undumprevlog Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# $ hg init
# $ undumprevlog < repo.dump
-from __future__ import absolute_import, print_function
import sys
from mercurial.node import bin
--- a/contrib/win32/hgwebdir_wsgi.py Tue Mar 22 03:19:01 2022 +0100
+++ b/contrib/win32/hgwebdir_wsgi.py Fri Mar 25 11:33:12 2022 -0400
@@ -78,7 +78,6 @@
# - Restart the web server and see if things are running.
#
-from __future__ import absolute_import
# Configuration file location
hgweb_config = r'c:\your\directory\wsgi.config'
--- a/doc/check-seclevel.py Tue Mar 22 03:19:01 2022 +0100
+++ b/doc/check-seclevel.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
#
# checkseclevel - checking section title levels in each online help document
-from __future__ import absolute_import
import optparse
import os
--- a/doc/docchecker Tue Mar 22 03:19:01 2022 +0100
+++ b/doc/docchecker Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import os
import re
--- a/doc/gendoc.py Tue Mar 22 03:19:01 2022 +0100
+++ b/doc/gendoc.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
where DOC is the name of a document
"""
-from __future__ import absolute_import
import os
import sys
--- a/doc/hgmanpage.py Tue Mar 22 03:19:01 2022 +0100
+++ b/doc/hgmanpage.py Fri Mar 25 11:33:12 2022 -0400
@@ -41,7 +41,6 @@
by the command whatis or apropos.
"""
-from __future__ import absolute_import
__docformat__ = 'reStructuredText'
@@ -113,7 +112,7 @@
self.output = visitor.astext()
-class Table(object):
+class Table:
def __init__(self):
self._rows = []
self._options = ['center']
@@ -313,7 +312,7 @@
pass
def list_start(self, node):
- class enum_char(object):
+ class enum_char:
enum_style = {
'bullet': '\\(bu',
'emdash': '\\(em',
--- a/doc/runrst Tue Mar 22 03:19:01 2022 +0100
+++ b/doc/runrst Fri Mar 25 11:33:12 2022 -0400
@@ -12,7 +12,6 @@
where WRITER is the name of a Docutils writer such as 'html' or 'manpage'
"""
-from __future__ import absolute_import
import sys
--- a/hg Tue Mar 22 03:19:01 2022 +0100
+++ b/hg Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
import sys
@@ -44,10 +43,9 @@
with tracing.log('hg script'):
# enable importing on demand to reduce startup time
try:
- if sys.version_info[0] < 3 or sys.version_info >= (3, 6):
- import hgdemandimport
+ import hgdemandimport
- hgdemandimport.enable()
+ hgdemandimport.enable()
except ImportError:
sys.stderr.write(
"abort: couldn't find mercurial libraries in [%s]\n"
--- a/hgdemandimport/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgdemandimport/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,15 +11,11 @@
# demand loading is per-package. Keeping demandimport in the mercurial package
# would disable demand loading for any modules in mercurial.
-from __future__ import absolute_import
import os
import sys
-if sys.version_info[0] >= 3:
- from . import demandimportpy3 as demandimport
-else:
- from . import demandimportpy2 as demandimport
+from . import demandimportpy3 as demandimport
# Full module names which can't be lazy imported.
# Extensions can add to this set.
--- a/hgdemandimport/demandimportpy2.py Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,326 +0,0 @@
-# demandimport.py - global demand-loading of modules for Mercurial
-#
-# Copyright 2006, 2007 Olivia Mackall <olivia@selenic.com>
-#
-# This software may be used and distributed according to the terms of the
-# GNU General Public License version 2 or any later version.
-
-'''
-demandimport - automatic demandloading of modules
-
-To enable this module, do:
-
- import demandimport; demandimport.enable()
-
-Imports of the following forms will be demand-loaded:
-
- import a, b.c
- import a.b as c
- from a import b,c # a will be loaded immediately
-
-These imports will not be delayed:
-
- from a import *
- b = __import__(a)
-'''
-
-from __future__ import absolute_import
-
-import __builtin__ as builtins
-import contextlib
-import sys
-
-from . import tracing
-
-contextmanager = contextlib.contextmanager
-
-_origimport = __import__
-
-nothing = object()
-
-
-def _hgextimport(importfunc, name, globals, *args, **kwargs):
- try:
- return importfunc(name, globals, *args, **kwargs)
- except ImportError:
- if not globals:
- raise
- # extensions are loaded with "hgext_" prefix
- hgextname = 'hgext_%s' % name
- nameroot = hgextname.split('.', 1)[0]
- contextroot = globals.get('__name__', '').split('.', 1)[0]
- if nameroot != contextroot:
- raise
- # retry to import with "hgext_" prefix
- return importfunc(hgextname, globals, *args, **kwargs)
-
-
-class _demandmod(object):
- """module demand-loader and proxy
-
- Specify 1 as 'level' argument at construction, to import module
- relatively.
- """
-
- def __init__(self, name, globals, locals, level):
- if '.' in name:
- head, rest = name.split('.', 1)
- after = [rest]
- else:
- head = name
- after = []
- object.__setattr__(
- self, "_data", (head, globals, locals, after, level, set())
- )
- object.__setattr__(self, "_module", None)
-
- def _extend(self, name):
- """add to the list of submodules to load"""
- self._data[3].append(name)
-
- def _addref(self, name):
- """Record that the named module ``name`` imports this module.
-
- References to this proxy class having the name of this module will be
- replaced at module load time. We assume the symbol inside the importing
- module is identical to the "head" name of this module. We don't
- actually know if "as X" syntax is being used to change the symbol name
- because this information isn't exposed to __import__.
- """
- self._data[5].add(name)
-
- def _load(self):
- if not self._module:
- with tracing.log('demandimport %s', self._data[0]):
- head, globals, locals, after, level, modrefs = self._data
- mod = _hgextimport(
- _origimport, head, globals, locals, None, level
- )
- if mod is self:
- # In this case, _hgextimport() above should imply
- # _demandimport(). Otherwise, _hgextimport() never
- # returns _demandmod. This isn't intentional behavior,
- # in fact. (see also issue5304 for detail)
- #
- # If self._module is already bound at this point, self
- # should be already _load()-ed while _hgextimport().
- # Otherwise, there is no way to import actual module
- # as expected, because (re-)invoking _hgextimport()
- # should cause same result.
- # This is reason why _load() returns without any more
- # setup but assumes self to be already bound.
- mod = self._module
- assert mod and mod is not self, "%s, %s" % (self, mod)
- return
-
- # load submodules
- def subload(mod, p):
- h, t = p, None
- if '.' in p:
- h, t = p.split('.', 1)
- if getattr(mod, h, nothing) is nothing:
- setattr(
- mod,
- h,
- _demandmod(p, mod.__dict__, mod.__dict__, level=1),
- )
- elif t:
- subload(getattr(mod, h), t)
-
- for x in after:
- subload(mod, x)
-
- # Replace references to this proxy instance with the
- # actual module.
- if locals:
- if locals.get(head) is self:
- locals[head] = mod
- elif locals.get(head + 'mod') is self:
- locals[head + 'mod'] = mod
-
- for modname in modrefs:
- modref = sys.modules.get(modname, None)
- if modref and getattr(modref, head, None) is self:
- setattr(modref, head, mod)
-
- object.__setattr__(self, "_module", mod)
-
- def __repr__(self):
- if self._module:
- return "<proxied module '%s'>" % self._data[0]
- return "<unloaded module '%s'>" % self._data[0]
-
- def __call__(self, *args, **kwargs):
- raise TypeError("%s object is not callable" % repr(self))
-
- def __getattr__(self, attr):
- self._load()
- return getattr(self._module, attr)
-
- def __setattr__(self, attr, val):
- self._load()
- setattr(self._module, attr, val)
-
- @property
- def __dict__(self):
- self._load()
- return self._module.__dict__
-
- @property
- def __doc__(self):
- self._load()
- return self._module.__doc__
-
-
-_pypy = '__pypy__' in sys.builtin_module_names
-
-
-def _demandimport(name, globals=None, locals=None, fromlist=None, level=-1):
- if locals is None or name in ignores or fromlist == ('*',):
- # these cases we can't really delay
- return _hgextimport(_origimport, name, globals, locals, fromlist, level)
- elif not fromlist:
- # import a [as b]
- if '.' in name: # a.b
- base, rest = name.split('.', 1)
- # email.__init__ loading email.mime
- if globals and globals.get('__name__', None) == base:
- return _origimport(name, globals, locals, fromlist, level)
- # if a is already demand-loaded, add b to its submodule list
- if base in locals:
- if isinstance(locals[base], _demandmod):
- locals[base]._extend(rest)
- return locals[base]
- return _demandmod(name, globals, locals, level)
- else:
- # There is a fromlist.
- # from a import b,c,d
- # from . import b,c,d
- # from .a import b,c,d
-
- # level == -1: relative and absolute attempted (Python 2 only).
- # level >= 0: absolute only (Python 2 w/ absolute_import and Python 3).
- # The modern Mercurial convention is to use absolute_import everywhere,
- # so modern Mercurial code will have level >= 0.
-
- # The name of the module the import statement is located in.
- globalname = globals.get('__name__')
-
- def processfromitem(mod, attr):
- """Process an imported symbol in the import statement.
-
- If the symbol doesn't exist in the parent module, and if the
- parent module is a package, it must be a module. We set missing
- modules up as _demandmod instances.
- """
- symbol = getattr(mod, attr, nothing)
- nonpkg = getattr(mod, '__path__', nothing) is nothing
- if symbol is nothing:
- if nonpkg:
- # do not try relative import, which would raise ValueError,
- # and leave unknown attribute as the default __import__()
- # would do. the missing attribute will be detected later
- # while processing the import statement.
- return
- mn = '%s.%s' % (mod.__name__, attr)
- if mn in ignores:
- importfunc = _origimport
- else:
- importfunc = _demandmod
- symbol = importfunc(attr, mod.__dict__, locals, level=1)
- setattr(mod, attr, symbol)
-
- # Record the importing module references this symbol so we can
- # replace the symbol with the actual module instance at load
- # time.
- if globalname and isinstance(symbol, _demandmod):
- symbol._addref(globalname)
-
- def chainmodules(rootmod, modname):
- # recurse down the module chain, and return the leaf module
- mod = rootmod
- for comp in modname.split('.')[1:]:
- obj = getattr(mod, comp, nothing)
- if obj is nothing:
- obj = _demandmod(comp, mod.__dict__, mod.__dict__, level=1)
- setattr(mod, comp, obj)
- elif mod.__name__ + '.' + comp in sys.modules:
- # prefer loaded module over attribute (issue5617)
- obj = sys.modules[mod.__name__ + '.' + comp]
- mod = obj
- return mod
-
- if level >= 0:
- if name:
- # "from a import b" or "from .a import b" style
- rootmod = _hgextimport(
- _origimport, name, globals, locals, level=level
- )
- mod = chainmodules(rootmod, name)
- elif _pypy:
- # PyPy's __import__ throws an exception if invoked
- # with an empty name and no fromlist. Recreate the
- # desired behaviour by hand.
- mn = globalname
- mod = sys.modules[mn]
- if getattr(mod, '__path__', nothing) is nothing:
- mn = mn.rsplit('.', 1)[0]
- mod = sys.modules[mn]
- if level > 1:
- mn = mn.rsplit('.', level - 1)[0]
- mod = sys.modules[mn]
- else:
- mod = _hgextimport(
- _origimport, name, globals, locals, level=level
- )
-
- for x in fromlist:
- processfromitem(mod, x)
-
- return mod
-
- # But, we still need to support lazy loading of standard library and 3rd
- # party modules. So handle level == -1.
- mod = _hgextimport(_origimport, name, globals, locals)
- mod = chainmodules(mod, name)
-
- for x in fromlist:
- processfromitem(mod, x)
-
- return mod
-
-
-ignores = set()
-
-
-def init(ignoreset):
- global ignores
- ignores = ignoreset
-
-
-def isenabled():
- return builtins.__import__ == _demandimport
-
-
-def enable():
- """enable global demand-loading of modules"""
- builtins.__import__ = _demandimport
-
-
-def disable():
- """disable global demand-loading of modules"""
- builtins.__import__ = _origimport
-
-
-@contextmanager
-def deactivated():
- """context manager for disabling demandimport in 'with' blocks"""
- demandenabled = isenabled()
- if demandenabled:
- disable()
-
- try:
- yield
- finally:
- if demandenabled:
- enable()
--- a/hgdemandimport/demandimportpy3.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgdemandimport/demandimportpy3.py Fri Mar 25 11:33:12 2022 -0400
@@ -24,7 +24,6 @@
"""
# This line is unnecessary, but it satisfies test-check-py3-compat.t.
-from __future__ import absolute_import
import contextlib
import importlib.util
@@ -34,12 +33,6 @@
_deactivated = False
-# Python 3.5's LazyLoader doesn't work for some reason.
-# https://bugs.python.org/issue26186 is a known issue with extension
-# importing. But it appears to not have a meaningful effect with
-# Mercurial.
-_supported = sys.version_info[0:2] >= (3, 6)
-
class _lazyloaderex(importlib.util.LazyLoader):
"""This is a LazyLoader except it also follows the _deactivated global and
@@ -55,7 +48,7 @@
super().exec_module(module)
-class LazyFinder(object):
+class LazyFinder:
"""A wrapper around a ``MetaPathFinder`` that makes loaders lazy.
``sys.meta_path`` finders have their ``find_spec()`` called to locate a
@@ -145,9 +138,6 @@
def enable():
- if not _supported:
- return
-
new_finders = []
for finder in sys.meta_path:
new_finders.append(
--- a/hgdemandimport/tracing.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgdemandimport/tracing.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import os
--- a/hgext/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
--- a/hgext/absorb.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/absorb.py Fri Mar 25 11:33:12 2022 -0400
@@ -31,7 +31,6 @@
# * Converge getdraftstack() with other code in core
# * move many attributes on fixupstate to be private
-from __future__ import absolute_import
import collections
@@ -84,7 +83,7 @@
defaultdict = collections.defaultdict
-class nullui(object):
+class nullui:
"""blank ui object doing nothing"""
debugflag = False
@@ -98,7 +97,7 @@
return nullfunc
-class emptyfilecontext(object):
+class emptyfilecontext:
"""minimal filecontext representing an empty file"""
def __init__(self, repo):
@@ -278,7 +277,7 @@
)
-class filefixupstate(object):
+class filefixupstate:
"""state needed to apply fixups to a single file
internally, it keeps file contents of several revisions and a linelog.
@@ -656,7 +655,7 @@
)
-class fixupstate(object):
+class fixupstate:
"""state needed to run absorb
internally, it keeps paths and filefixupstates.
@@ -734,7 +733,7 @@
def apply(self):
"""apply fixups to individual filefixupstates"""
- for path, state in pycompat.iteritems(self.fixupmap):
+ for path, state in self.fixupmap.items():
if self.ui.debugflag:
self.ui.write(_(b'applying fixups to %s\n') % path)
state.apply()
@@ -742,10 +741,7 @@
@property
def chunkstats(self):
"""-> {path: chunkstats}. collect chunkstats from filefixupstates"""
- return {
- path: state.chunkstats
- for path, state in pycompat.iteritems(self.fixupmap)
- }
+ return {path: state.chunkstats for path, state in self.fixupmap.items()}
def commit(self):
"""commit changes. update self.finalnode, self.replacemap"""
@@ -763,7 +759,7 @@
chunkstats = self.chunkstats
if ui.verbose:
# chunkstats for each file
- for path, stat in pycompat.iteritems(chunkstats):
+ for path, stat in chunkstats.items():
if stat[0]:
ui.write(
_(b'%s: %d of %d chunk(s) applied\n')
@@ -846,7 +842,7 @@
repo = self.repo
needupdate = [
(name, self.replacemap[hsh])
- for name, hsh in pycompat.iteritems(repo._bookmarks)
+ for name, hsh in repo._bookmarks.items()
if hsh in self.replacemap
]
changes = []
@@ -909,7 +905,7 @@
# ctx changes more files (not a subset of memworkingcopy)
if not set(ctx.files()).issubset(set(memworkingcopy)):
return False
- for path, content in pycompat.iteritems(memworkingcopy):
+ for path, content in memworkingcopy.items():
if path not in pctx or path not in ctx:
return False
fctx = ctx[path]
@@ -952,7 +948,7 @@
def _cleanupoldcommits(self):
replacements = {
k: ([v] if v is not None else [])
- for k, v in pycompat.iteritems(self.replacemap)
+ for k, v in self.replacemap.items()
}
if replacements:
scmutil.cleanupnodes(
@@ -1002,7 +998,7 @@
if not path or not info:
continue
patchmap[path].append(info)
- for path, patches in pycompat.iteritems(patchmap):
+ for path, patches in patchmap.items():
if path not in ctx or not patches:
continue
patches.sort(reverse=True)
--- a/hgext/acl.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/acl.py Fri Mar 25 11:33:12 2022 -0400
@@ -213,7 +213,6 @@
'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/amend.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/amend.py Fri Mar 25 11:33:12 2022 -0400
@@ -10,7 +10,6 @@
``commit --amend`` but does not prompt an editor.
"""
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/automv.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/automv.py Fri Mar 25 11:33:12 2022 -0400
@@ -24,7 +24,6 @@
#
# See http://markmail.org/thread/5pxnljesvufvom57 for context.
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/beautifygraph.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/beautifygraph.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,7 +11,6 @@
A terminal with UTF-8 support and monospace narrow text are required.
'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/blackbox.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/blackbox.py Fri Mar 25 11:33:12 2022 -0400
@@ -42,7 +42,6 @@
"""
-from __future__ import absolute_import
import re
@@ -106,7 +105,7 @@
_lastlogger = loggingutil.proxylogger()
-class blackboxlogger(object):
+class blackboxlogger:
def __init__(self, ui, repo):
self._repo = repo
self._trackedevents = set(ui.configlist(b'blackbox', b'track'))
--- a/hgext/bookflow.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/bookflow.py Fri Mar 25 11:33:12 2022 -0400
@@ -13,7 +13,6 @@
:hg up|co NAME: switch to bookmark
:hg push -B .: push active bookmark
"""
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/bugzilla.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/bugzilla.py Fri Mar 25 11:33:12 2022 -0400
@@ -291,7 +291,6 @@
Changeset commit comment. Bug 1234.
'''
-from __future__ import absolute_import
import json
import re
@@ -435,7 +434,7 @@
)
-class bzaccess(object):
+class bzaccess:
'''Base class for access to Bugzilla.'''
def __init__(self, ui):
@@ -691,7 +690,7 @@
# Bugzilla via XMLRPC interface.
-class cookietransportrequest(object):
+class cookietransportrequest:
"""A Transport request method that retains cookies over its lifetime.
The regular xmlrpclib transports ignore cookies. Which causes
@@ -1096,7 +1095,7 @@
pass
-class bugzilla(object):
+class bugzilla:
# supported versions of bugzilla. different versions have
# different schemas.
_versions = {
--- a/hgext/censor.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/censor.py Fri Mar 25 11:33:12 2022 -0400
@@ -28,7 +28,6 @@
ignore censored data and merely report that it was encountered.
"""
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial.node import short
--- a/hgext/children.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/children.py Fri Mar 25 11:33:12 2022 -0400
@@ -14,7 +14,6 @@
"children(REV)"` instead.
'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/churn.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/churn.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
'''command to display statistics about repository history'''
-from __future__ import absolute_import, division
import datetime
import os
--- a/hgext/clonebundles.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/clonebundles.py Fri Mar 25 11:33:12 2022 -0400
@@ -202,7 +202,6 @@
Mercurial server when the bundle hosting service fails.
"""
-from __future__ import absolute_import
from mercurial import (
bundlecaches,
--- a/hgext/closehead.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/closehead.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
'''close arbitrary heads without checking them out first'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/commitextras.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/commitextras.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
'''adds a new flag extras to commit (ADVANCED)'''
-from __future__ import absolute_import
import re
--- a/hgext/convert/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
'''import revisions from foreign VCS repositories into Mercurial'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import registrar
--- a/hgext/convert/bzr.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/bzr.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
# This module is for handling Breezy imports or `brz`, but it's also compatible
# with Bazaar or `bzr`, that was formerly known as Bazaar-NG;
# it cannot access `bar` repositories, but they were never used very much.
-from __future__ import absolute_import
import os
@@ -16,7 +15,6 @@
from mercurial import (
demandimport,
error,
- pycompat,
util,
)
from . import common
@@ -210,7 +208,7 @@
if not branch.supports_tags():
return {}
tagdict = branch.tags.get_tag_dict()
- for name, rev in pycompat.iteritems(tagdict):
+ for name, rev in tagdict.items():
bytetags[self.recode(name)] = rev
return bytetags
--- a/hgext/convert/common.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/common.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,12 +4,12 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import base64
import datetime
import errno
import os
+import pickle
import re
import shlex
import subprocess
@@ -25,7 +25,6 @@
)
from mercurial.utils import procutil
-pickle = util.pickle
propertycache = util.propertycache
@@ -35,7 +34,7 @@
return d.encode('latin1')
-class _shlexpy3proxy(object):
+class _shlexpy3proxy:
def __init__(self, l):
self._l = l
@@ -128,7 +127,7 @@
SKIPREV = b'SKIP'
-class commit(object):
+class commit:
def __init__(
self,
author,
@@ -158,7 +157,7 @@
self.ctx = ctx # for hg to hg conversions
-class converter_source(object):
+class converter_source:
"""Conversion source interface"""
def __init__(self, ui, repotype, path=None, revs=None):
@@ -247,7 +246,7 @@
if not encoding:
encoding = self.encoding or b'utf-8'
- if isinstance(s, pycompat.unicode):
+ if isinstance(s, str):
return s.encode("utf-8")
try:
return s.decode(pycompat.sysstr(encoding)).encode("utf-8")
@@ -308,7 +307,7 @@
return True
-class converter_sink(object):
+class converter_sink:
"""Conversion sink (target) interface"""
def __init__(self, ui, repotype, path):
@@ -404,7 +403,7 @@
raise NotImplementedError
-class commandline(object):
+class commandline:
def __init__(self, ui, command):
self.ui = ui
self.command = command
@@ -418,7 +417,7 @@
def _cmdline(self, cmd, *args, **kwargs):
kwargs = pycompat.byteskwargs(kwargs)
cmdline = [self.command, cmd] + list(args)
- for k, v in pycompat.iteritems(kwargs):
+ for k, v in kwargs.items():
if len(k) == 1:
cmdline.append(b'-' + k)
else:
@@ -553,7 +552,7 @@
if err.errno != errno.ENOENT:
raise
return
- for i, line in enumerate(util.iterfile(fp)):
+ for i, line in enumerate(fp):
line = line.splitlines()[0].rstrip()
if not line:
# Ignore blank lines
--- a/hgext/convert/convcmd.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/convcmd.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import os
@@ -87,7 +86,7 @@
def recode(s):
- if isinstance(s, pycompat.unicode):
+ if isinstance(s, str):
return s.encode(pycompat.sysstr(orig_encoding), 'replace')
else:
return s.decode('utf-8').encode(
@@ -177,7 +176,7 @@
raise error.Abort(_(b'%s: unknown repository type') % path)
-class progresssource(object):
+class progresssource:
def __init__(self, ui, source, filecount):
self.ui = ui
self.source = source
@@ -199,7 +198,7 @@
self.progress.complete()
-class converter(object):
+class converter:
def __init__(self, ui, source, dest, revmapfile, opts):
self.source = source
@@ -243,7 +242,7 @@
m = {}
try:
fp = open(path, b'rb')
- for i, line in enumerate(util.iterfile(fp)):
+ for i, line in enumerate(fp):
line = line.splitlines()[0].rstrip()
if not line:
# Ignore blank lines
@@ -585,9 +584,7 @@
# write another hash correspondence to override the
# previous one so we don't end up with extra tag heads
tagsparents = [
- e
- for e in pycompat.iteritems(self.map)
- if e[1] == tagsparent
+ e for e in self.map.items() if e[1] == tagsparent
]
if tagsparents:
self.map[tagsparents[0][0]] = nrev
--- a/hgext/convert/cvs.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/cvs.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
@@ -19,7 +18,6 @@
from mercurial import (
encoding,
error,
- pycompat,
util,
)
from mercurial.utils import (
@@ -317,7 +315,7 @@
if full:
raise error.Abort(_(b"convert from cvs does not support --full"))
self._parse()
- return sorted(pycompat.iteritems(self.files[rev])), {}, set()
+ return sorted(self.files[rev].items()), {}, set()
def getcommit(self, rev):
self._parse()
--- a/hgext/convert/cvsps.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/cvsps.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,10 +4,10 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import functools
import os
+import pickle
import re
from mercurial.i18n import _
@@ -25,10 +25,8 @@
stringutil,
)
-pickle = util.pickle
-
-class logentry(object):
+class logentry:
"""Class logentry has the following attributes:
.author - author name as CVS knows it
.branch - name of branch this revision is on
@@ -468,7 +466,7 @@
# find the branches starting from this revision
branchpoints = set()
- for branch, revision in pycompat.iteritems(branchmap):
+ for branch, revision in branchmap.items():
revparts = tuple([int(i) for i in revision.split(b'.')])
if len(revparts) < 2: # bad tags
continue
@@ -579,7 +577,7 @@
return log
-class changeset(object):
+class changeset:
"""Class changeset has the following attributes:
.id - integer identifying this changeset (list index)
.author - author name as CVS knows it
--- a/hgext/convert/darcs.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/darcs.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
@@ -114,7 +113,7 @@
shutil.rmtree(self.tmppath, ignore_errors=True)
def recode(self, s, encoding=None):
- if isinstance(s, pycompat.unicode):
+ if isinstance(s, str):
# XMLParser returns unicode objects for anything it can't
# encode into ASCII. We convert them back to str to get
# recode's normal conversion behavior.
--- a/hgext/convert/filemap.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/filemap.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import posixpath
@@ -42,7 +41,7 @@
return posixpath.normpath(path)
-class filemapper(object):
+class filemapper:
"""Map and filter filenames when importing.
A name can be mapped to itself, a new name, or None (omit from new
repository)."""
@@ -126,7 +125,7 @@
repo belong to the source repo and what parts don't."""
if self.targetprefixes is None:
self.targetprefixes = set()
- for before, after in pycompat.iteritems(self.rename):
+ for before, after in self.rename.items():
self.targetprefixes.add(after)
# If "." is a target, then all target files are considered from the
--- a/hgext/convert/git.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/git.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
@@ -20,7 +19,7 @@
from . import common
-class submodule(object):
+class submodule:
def __init__(self, path, node, url):
self.path = path
self.node = node
--- a/hgext/convert/gnuarch.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/gnuarch.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
import shutil
@@ -28,7 +27,7 @@
class gnuarch_source(common.converter_source, common.commandline):
- class gnuarch_rev(object):
+ class gnuarch_rev:
def __init__(self, rev):
self.rev = rev
self.summary = b''
--- a/hgext/convert/hg.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/hg.py Fri Mar 25 11:33:12 2022 -0400
@@ -16,7 +16,6 @@
# identifier to be stored in the converted revision. This will cause
# the converted revision to have a different identity than the
# source.
-from __future__ import absolute_import
import os
import re
@@ -40,7 +39,6 @@
merge as mergemod,
mergestate,
phases,
- pycompat,
util,
)
from mercurial.utils import dateutil
@@ -139,7 +137,7 @@
if missings:
self.after()
- for pbranch, heads in sorted(pycompat.iteritems(missings)):
+ for pbranch, heads in sorted(missings.items()):
pbranchpath = os.path.join(self.path, pbranch)
prepo = hg.peer(self.ui, {}, pbranchpath)
self.ui.note(
@@ -424,7 +422,7 @@
tagparent = tagparent or self.repo.nullid
oldlines = set()
- for branch, heads in pycompat.iteritems(self.repo.branchmap()):
+ for branch, heads in self.repo.branchmap().items():
for h in heads:
if b'.hgtags' in self.repo[h]:
oldlines.update(
@@ -596,7 +594,7 @@
maappend = ma.append
rappend = r.append
d = ctx1.manifest().diff(ctx2.manifest())
- for f, ((node1, flag1), (node2, flag2)) in pycompat.iteritems(d):
+ for f, ((node1, flag1), (node2, flag2)) in d.items():
if node2 is None:
rappend(f)
else:
@@ -622,7 +620,7 @@
cleanp2 = set()
if len(parents) == 2:
d = parents[1].manifest().diff(ctx.manifest(), clean=True)
- for f, value in pycompat.iteritems(d):
+ for f, value in d.items():
if value is None:
cleanp2.add(f)
changes = [(f, rev) for f in files if f not in self.ignored]
--- a/hgext/convert/monotone.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/monotone.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
import re
@@ -103,7 +102,7 @@
# Prepare the command in automate stdio format
kwargs = pycompat.byteskwargs(kwargs)
command = []
- for k, v in pycompat.iteritems(kwargs):
+ for k, v in kwargs.items():
command.append(b"%d:%s" % (len(k), k))
if v:
command.append(b"%d:%s" % (len(v), v))
@@ -151,7 +150,7 @@
raise error.Abort(_(b'bad mtn packet - no end of packet size'))
lengthstr += read
try:
- length = pycompat.long(lengthstr[:-1])
+ length = int(lengthstr[:-1])
except TypeError:
raise error.Abort(
_(b'bad mtn packet - bad packet size %s') % lengthstr
--- a/hgext/convert/p4.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/p4.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import marshal
import re
--- a/hgext/convert/subversion.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/subversion.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,11 +1,11 @@
# Subversion 1.4/1.5 Python API backend
#
# Copyright(C) 2007 Daniel Holth et al
-from __future__ import absolute_import
import codecs
import locale
import os
+import pickle
import re
import xml.dom.minidom
@@ -26,7 +26,6 @@
from . import common
-pickle = util.pickle
stringio = util.stringio
propertycache = util.propertycache
urlerr = util.urlerr
@@ -181,7 +180,7 @@
return optrev
-class changedpath(object):
+class changedpath:
def __init__(self, p):
self.copyfrom_path = p.copyfrom_path
self.copyfrom_rev = p.copyfrom_rev
@@ -203,7 +202,7 @@
def receiver(orig_paths, revnum, author, date, message, pool):
paths = {}
if orig_paths is not None:
- for k, v in pycompat.iteritems(orig_paths):
+ for k, v in orig_paths.items():
paths[k] = changedpath(v)
pickle.dump((paths, revnum, author, date, message), fp, protocol)
@@ -249,7 +248,7 @@
get_log_child(ui.fout, *args)
-class logstream(object):
+class logstream:
"""Interruptible revision log iterator."""
def __init__(self, stdout):
@@ -298,7 +297,7 @@
def receiver(orig_paths, revnum, author, date, message, pool):
paths = {}
if orig_paths is not None:
- for k, v in pycompat.iteritems(orig_paths):
+ for k, v in orig_paths.items():
paths[k] = changedpath(v)
self.append((paths, revnum, author, date, message))
@@ -730,7 +729,7 @@
)
files = [
n
- for n, e in pycompat.iteritems(entries)
+ for n, e in entries.items()
if e.kind == svn.core.svn_node_file
]
self.removed = set()
@@ -820,7 +819,7 @@
origpaths = []
copies = [
(e.copyfrom_path, e.copyfrom_rev, p)
- for p, e in pycompat.iteritems(origpaths)
+ for p, e in origpaths.items()
if e.copyfrom_path
]
# Apply moves/copies from more specific to general
@@ -851,7 +850,7 @@
# be represented in mercurial.
addeds = {
p: e.copyfrom_path
- for p, e in pycompat.iteritems(origpaths)
+ for p, e in origpaths.items()
if e.action == b'A' and e.copyfrom_path
}
badroots = set()
@@ -1140,7 +1139,7 @@
parents = []
# check whether this revision is the start of a branch or part
# of a branch renaming
- orig_paths = sorted(pycompat.iteritems(orig_paths))
+ orig_paths = sorted(orig_paths.items())
root_paths = [
(p, e) for p, e in orig_paths if self.module.startswith(p)
]
@@ -1302,7 +1301,7 @@
path += b'/'
return (
(path + p)
- for p, e in pycompat.iteritems(entries)
+ for p, e in entries.items()
if e.kind == svn.core.svn_node_file
)
--- a/hgext/convert/transport.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/convert/transport.py Fri Mar 25 11:33:12 2022 -0400
@@ -16,7 +16,6 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
-from __future__ import absolute_import
import svn.client
import svn.core
@@ -71,7 +70,7 @@
pass
-class SvnRaTransport(object):
+class SvnRaTransport:
"""
Open an ra connection to a Subversion repository.
"""
@@ -108,7 +107,7 @@
self.ra = ra
svn.ra.reparent(self.ra, self.svn_url.encode('utf8'))
- class Reporter(object):
+ class Reporter:
def __init__(self, reporter_data):
self._reporter, self._baton = reporter_data
--- a/hgext/eol.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/eol.py Fri Mar 25 11:33:12 2022 -0400
@@ -91,7 +91,6 @@
used.
"""
-from __future__ import absolute_import
import os
import re
@@ -186,7 +185,7 @@
}
-class eolfile(object):
+class eolfile:
def __init__(self, ui, root, data):
self._decode = {
b'LF': b'to-lf',
@@ -379,7 +378,7 @@
if not repo.local():
return
- for name, fn in pycompat.iteritems(filters):
+ for name, fn in filters.items():
repo.adddatafilter(name, fn)
ui.setconfig(b'patch', b'eol', b'auto', b'eol')
--- a/hgext/extdiff.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/extdiff.py Fri Mar 25 11:33:12 2022 -0400
@@ -81,7 +81,6 @@
pretty fast (at least faster than having to compare the entire tree).
'''
-from __future__ import absolute_import
import os
import re
@@ -696,7 +695,7 @@
return dodiff(ui, repo, cmdline, pats, opts)
-class savedcmd(object):
+class savedcmd:
"""use external program to diff repository (or selected files)
Show differences between revisions for the specified files, using
--- a/hgext/factotum.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/factotum.py Fri Mar 25 11:33:12 2022 -0400
@@ -45,7 +45,6 @@
'''
-from __future__ import absolute_import
import os
from mercurial.i18n import _
--- a/hgext/fastannotate/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastannotate/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -101,7 +101,6 @@
#
# * format changes to the revmap file (maybe use length-encoding
# instead of null-terminated file paths at least?)
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/fastannotate/commands.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastannotate/commands.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
--- a/hgext/fastannotate/context.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastannotate/context.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import contextlib
@@ -160,7 +159,7 @@
_defaultdiffopthash = hashdiffopts(mdiff.defaultopts)
-class annotateopts(object):
+class annotateopts:
"""like mercurial.mdiff.diffopts, but is for annotate
followrename: follow renames, like "hg annotate -f"
@@ -175,7 +174,7 @@
def __init__(self, **opts):
opts = pycompat.byteskwargs(opts)
- for k, v in pycompat.iteritems(self.defaults):
+ for k, v in self.defaults.items():
setattr(self, k, opts.get(k, v))
@util.propertycache
@@ -197,7 +196,7 @@
defaultopts = annotateopts()
-class _annotatecontext(object):
+class _annotatecontext:
"""do not use this class directly as it does not use lock to protect
writes. use "with annotatecontext(...)" instead.
"""
@@ -584,7 +583,7 @@
# find an unresolved line and its linelog rev to annotate
hsh = None
try:
- for (rev, _linenum), idxs in pycompat.iteritems(key2idxs):
+ for (rev, _linenum), idxs in key2idxs.items():
if revmap.rev2flag(rev) & revmapmod.sidebranchflag:
continue
hsh = annotateresult[idxs[0]][0]
@@ -595,7 +594,7 @@
# the remaining key2idxs are not in main branch, resolving them
# using the hard way...
revlines = {}
- for (rev, linenum), idxs in pycompat.iteritems(key2idxs):
+ for (rev, linenum), idxs in key2idxs.items():
if rev not in revlines:
hsh = annotateresult[idxs[0]][0]
if self.ui.debugflag:
@@ -784,7 +783,7 @@
pass
-class pathhelper(object):
+class pathhelper:
"""helper for getting paths for lockfile, linelog and revmap"""
def __init__(self, repo, path, opts=defaultopts):
--- a/hgext/fastannotate/error.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastannotate/error.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
class CorruptedFileError(Exception):
--- a/hgext/fastannotate/formatter.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastannotate/formatter.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial.node import (
hex,
@@ -20,7 +19,7 @@
# imitating mercurial.commands.annotate, not using the vanilla formatter since
# the data structures are a bit different, and we have some fast paths.
-class defaultformatter(object):
+class defaultformatter:
"""the default formatter that does leftpad and support some common flags"""
def __init__(self, ui, repo, opts):
--- a/hgext/fastannotate/protocol.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastannotate/protocol.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import os
@@ -15,7 +14,6 @@
error,
extensions,
hg,
- pycompat,
util,
wireprotov1peer,
wireprotov1server,
@@ -190,7 +188,7 @@
for result in results:
r = result.result()
# TODO: pconvert these paths on the server?
- r = {util.pconvert(p): v for p, v in pycompat.iteritems(r)}
+ r = {util.pconvert(p): v for p, v in r.items()}
for path in sorted(r):
# ignore malicious paths
if not path.startswith(b'fastannotate/') or b'/../' in (
--- a/hgext/fastannotate/revmap.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastannotate/revmap.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import bisect
import io
@@ -49,7 +48,7 @@
_hshlen = 20
-class revmap(object):
+class revmap:
"""trivial hg bin hash - linelog rev bidirectional map
also stores a flag (uint8) for each revision, and track renames.
--- a/hgext/fastannotate/support.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastannotate/support.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial.pycompat import getattr
from mercurial import (
@@ -23,7 +22,7 @@
)
-class _lazyfctx(object):
+class _lazyfctx:
"""delegates to fctx but do not construct fctx when unnecessary"""
def __init__(self, repo, node, path):
--- a/hgext/fastexport.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fastexport.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# The format specification for fast-import streams can be found at
# https://git-scm.com/docs/git-fast-import#_input_format
-from __future__ import absolute_import
import re
from mercurial.i18n import _
--- a/hgext/fetch.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fetch.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
'''pull, update and merge in one command (DEPRECATED)'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial.node import short
--- a/hgext/fix.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fix.py Fri Mar 25 11:33:12 2022 -0400
@@ -122,7 +122,6 @@
file content back to stdout as documented above.
"""
-from __future__ import absolute_import
import collections
import itertools
@@ -378,9 +377,7 @@
Useful as a hook point for extending "hg fix" with output summarizing the
effects of the command, though we choose not to output anything here.
"""
- replacements = {
- prec: [succ] for prec, succ in pycompat.iteritems(replacements)
- }
+ replacements = {prec: [succ] for prec, succ in replacements.items()}
scmutil.cleanupnodes(repo, replacements, b'fix', fixphase=True)
@@ -693,7 +690,7 @@
"""
metadata = {}
newdata = fixctx[path].data()
- for fixername, fixer in pycompat.iteritems(fixers):
+ for fixername, fixer in fixers.items():
if fixer.affects(opts, fixctx, path):
ranges = lineranges(
opts, path, basepaths, basectxs, fixctx, newdata
@@ -771,7 +768,7 @@
Directly updates the dirstate for the affected files.
"""
- for path, data in pycompat.iteritems(filedata):
+ for path, data in filedata.items():
fctx = ctx[path]
fctx.write(data, fctx.flags())
@@ -906,7 +903,7 @@
return names
-class Fixer(object):
+class Fixer:
"""Wraps the raw config values for a fixer with methods"""
def __init__(
--- a/hgext/fsmonitor/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -107,7 +107,6 @@
# The issues related to nested repos and subrepos are probably not fundamental
# ones. Patches to fix them are welcome.
-from __future__ import absolute_import
import codecs
import os
@@ -502,15 +501,11 @@
visit.update(f for f in copymap if f not in results and matchfn(f))
else:
if matchalways:
- visit.update(
- f for f, st in pycompat.iteritems(dmap) if f not in results
- )
+ visit.update(f for f, st in dmap.items() if f not in results)
visit.update(f for f in copymap if f not in results)
else:
visit.update(
- f
- for f, st in pycompat.iteritems(dmap)
- if f not in results and matchfn(f)
+ f for f, st in dmap.items() if f not in results and matchfn(f)
)
visit.update(f for f in copymap if f not in results and matchfn(f))
@@ -686,7 +681,7 @@
)
-class poststatus(object):
+class poststatus:
def __init__(self, startclock):
self._startclock = pycompat.sysbytes(startclock)
@@ -761,7 +756,7 @@
pass
-class state_update(object):
+class state_update:
"""This context manager is responsible for dispatching the state-enter
and state-leave signals to the watchman service. The enter and leave
methods can be invoked manually (for scenarios where context manager
--- a/hgext/fsmonitor/pywatchman/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/pywatchman/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# no unicode literals
-from __future__ import absolute_import, division, print_function
import inspect
import math
@@ -302,7 +301,7 @@
)
-class Transport(object):
+class Transport:
"""communication transport to the watchman server"""
buf = None
@@ -347,7 +346,7 @@
self.buf.append(b)
-class Codec(object):
+class Codec:
"""communication encoding for the watchman server"""
transport = None
@@ -860,7 +859,7 @@
self.transport.write(cmd + b"\n")
-class client(object):
+class client:
"""Handles the communication with the watchman service"""
sockpath = None
--- a/hgext/fsmonitor/pywatchman/capabilities.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/pywatchman/capabilities.py Fri Mar 25 11:33:12 2022 -0400
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# no unicode literals
-from __future__ import absolute_import, division, print_function
def parse_version(vstr):
--- a/hgext/fsmonitor/pywatchman/compat.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/pywatchman/compat.py Fri Mar 25 11:33:12 2022 -0400
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# no unicode literals
-from __future__ import absolute_import, division, print_function
import sys
--- a/hgext/fsmonitor/pywatchman/encoding.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/pywatchman/encoding.py Fri Mar 25 11:33:12 2022 -0400
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# no unicode literals
-from __future__ import absolute_import, division, print_function
import sys
--- a/hgext/fsmonitor/pywatchman/load.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/pywatchman/load.py Fri Mar 25 11:33:12 2022 -0400
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# no unicode literals
-from __future__ import absolute_import, division, print_function
import ctypes
--- a/hgext/fsmonitor/pywatchman/pybser.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/pywatchman/pybser.py Fri Mar 25 11:33:12 2022 -0400
@@ -27,7 +27,6 @@
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# no unicode literals
-from __future__ import absolute_import, division, print_function
import binascii
import collections
@@ -94,7 +93,7 @@
return ret
-class _bser_buffer(object):
+class _bser_buffer:
def __init__(self, version):
self.bser_version = version
self.buf = ctypes.create_string_buffer(8192)
@@ -325,7 +324,7 @@
# This is a quack-alike with the bserObjectType in bser.c
# It provides by getattr accessors and getitem for both index
# and name.
-class _BunserDict(object):
+class _BunserDict:
__slots__ = ("_keys", "_values")
def __init__(self, keys, values):
@@ -351,7 +350,7 @@
return len(self._keys)
-class Bunser(object):
+class Bunser:
def __init__(self, mutable=True, value_encoding=None, value_errors=None):
self.mutable = mutable
self.value_encoding = value_encoding
--- a/hgext/fsmonitor/state.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/state.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
@@ -23,7 +22,7 @@
_versionformat = b">I"
-class state(object):
+class state:
def __init__(self, repo):
self._vfs = repo.vfs
self._ui = repo.ui
--- a/hgext/fsmonitor/watchmanclient.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/fsmonitor/watchmanclient.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import getpass
@@ -44,7 +43,7 @@
super(WatchmanNoRoot, self).__init__(msg)
-class client(object):
+class client:
def __init__(self, ui, root, timeout=1.0):
err = None
if not self._user:
--- a/hgext/git/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/git/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
firstborn a la Rumpelstiltskin, etc.
"""
-from __future__ import absolute_import
import os
@@ -48,7 +47,7 @@
# TODO: extract an interface for this in core
-class gitstore(object): # store.basicstore):
+class gitstore: # store.basicstore):
def __init__(self, path, vfstype):
self.vfs = vfstype(path)
self.opener = self.vfs
@@ -130,7 +129,7 @@
return orig(requirements, storebasepath, vfstype)
-class gitfilestorage(object):
+class gitfilestorage:
def file(self, path):
if path[0:1] == b'/':
path = path[1:]
@@ -162,7 +161,7 @@
_BMS_PREFIX = 'refs/heads/'
-class gitbmstore(object):
+class gitbmstore:
def __init__(self, gitrepo):
self.gitrepo = gitrepo
self._aclean = True
--- a/hgext/git/dirstate.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/git/dirstate.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import contextlib
import errno
import os
@@ -68,7 +66,7 @@
@interfaceutil.implementer(intdirstate.idirstate)
-class gitdirstate(object):
+class gitdirstate:
def __init__(self, ui, root, gitrepo):
self._ui = ui
self._root = os.path.dirname(root)
--- a/hgext/git/gitlog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/git/gitlog.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from mercurial.i18n import _
from mercurial.node import (
@@ -31,7 +29,7 @@
pygit2 = gitutil.get_pygit2()
-class baselog(object): # revlog.revlog):
+class baselog: # revlog.revlog):
"""Common implementations between changelog and manifestlog."""
def __init__(self, gr, db):
@@ -71,7 +69,7 @@
return t is not None
-class baselogindex(object):
+class baselogindex:
def __init__(self, log):
self._log = log
--- a/hgext/git/gitutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/git/gitutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
"""utilities to assist in working with pygit2"""
-from __future__ import absolute_import
from mercurial.node import bin, hex, sha1nodeconstants
--- a/hgext/git/index.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/git/index.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import collections
import os
import sqlite3
--- a/hgext/git/manifest.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/git/manifest.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from mercurial import (
match as matchmod,
pathutil,
@@ -17,7 +15,7 @@
@interfaceutil.implementer(repository.imanifestdict)
-class gittreemanifest(object):
+class gittreemanifest:
"""Expose git trees (and optionally a builder's overlay) as a manifestdict.
Very similar to mercurial.manifest.treemanifest.
@@ -260,7 +258,7 @@
@interfaceutil.implementer(repository.imanifestrevisionstored)
-class gittreemanifestctx(object):
+class gittreemanifestctx:
def __init__(self, repo, gittree):
self._repo = repo
self._tree = gittree
@@ -281,7 +279,7 @@
@interfaceutil.implementer(repository.imanifestrevisionwritable)
-class memgittreemanifestctx(object):
+class memgittreemanifestctx:
def __init__(self, repo, tree):
self._repo = repo
self._tree = tree
--- a/hgext/githelp.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/githelp.py Fri Mar 25 11:33:12 2022 -0400
@@ -15,7 +15,6 @@
produced.
"""
-from __future__ import absolute_import
import getopt
import re
@@ -116,14 +115,14 @@
opts = dict(
[
(k, convert(v)) if isinstance(v, bytes) else (k, v)
- for k, v in pycompat.iteritems(opts)
+ for k, v in opts.items()
]
)
return args, opts
-class Command(object):
+class Command:
def __init__(self, name):
self.name = name
self.args = []
@@ -132,7 +131,7 @@
def __bytes__(self):
cmd = b"hg " + self.name
if self.opts:
- for k, values in sorted(pycompat.iteritems(self.opts)):
+ for k, values in sorted(self.opts.items()):
for v in values:
if v:
if isinstance(v, int):
@@ -164,7 +163,7 @@
return AndCommand(self, other)
-class AndCommand(object):
+class AndCommand:
def __init__(self, left, right):
self.left = left
self.right = right
--- a/hgext/gpg.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/gpg.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
'''commands to sign and verify changesets'''
-from __future__ import absolute_import
import binascii
import os
@@ -65,7 +64,7 @@
help.CATEGORY_NAMES[_HELP_CATEGORY] = b'Signing changes (GPG)'
-class gpg(object):
+class gpg:
def __init__(self, path, key=None):
self.path = path
self.key = (key and b" --local-user \"%s\"" % key) or b""
--- a/hgext/graphlog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/graphlog.py Fri Mar 25 11:33:12 2022 -0400
@@ -15,7 +15,6 @@
revision graph is also shown.
'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/hgk.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/hgk.py Fri Mar 25 11:33:12 2022 -0400
@@ -34,7 +34,6 @@
vdiff on hovered and selected revisions.
'''
-from __future__ import absolute_import
import os
@@ -377,9 +376,7 @@
"""start interactive history viewer"""
opts = pycompat.byteskwargs(opts)
os.chdir(repo.root)
- optstr = b' '.join(
- [b'--%s %s' % (k, v) for k, v in pycompat.iteritems(opts) if v]
- )
+ optstr = b' '.join([b'--%s %s' % (k, v) for k, v in opts.items() if v])
if repo.filtername is None:
optstr += b'--hidden'
--- a/hgext/highlight/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/highlight/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -26,7 +26,6 @@
match (even matches with a low confidence score) will be used.
"""
-from __future__ import absolute_import
from . import highlight
from mercurial.hgweb import (
--- a/hgext/highlight/highlight.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/highlight/highlight.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
# The original module was split in an interface and an implementation
# file to defer pygments loading and speedup extension setup.
-from __future__ import absolute_import
from mercurial import demandimport
--- a/hgext/histedit.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/histedit.py Fri Mar 25 11:33:12 2022 -0400
@@ -190,7 +190,6 @@
"""
-from __future__ import absolute_import
# chistedit dependencies that are not available everywhere
try:
@@ -202,6 +201,7 @@
import functools
import os
+import pickle
import struct
from mercurial.i18n import _
@@ -245,7 +245,6 @@
urlutil,
)
-pickle = util.pickle
cmdtable = {}
command = registrar.command(cmdtable)
@@ -352,7 +351,7 @@
return b''.join([b'# %s\n' % l if l else b'#\n' for l in lines])
-class histeditstate(object):
+class histeditstate:
def __init__(self, repo):
self.repo = repo
self.actions = None
@@ -491,7 +490,7 @@
return self.repo.vfs.exists(b'histedit-state')
-class histeditaction(object):
+class histeditaction:
def __init__(self, state, node):
self.state = state
self.repo = state.repo
@@ -1143,7 +1142,7 @@
return struct.unpack(b'hh', fcntl.ioctl(1, termios.TIOCGWINSZ, b' '))
-class histeditrule(object):
+class histeditrule:
def __init__(self, ui, ctx, pos, action=b'pick'):
self.ui = ui
self.ctx = ctx
@@ -1243,7 +1242,7 @@
return line[: n - 2] + b' >'
-class _chistedit_state(object):
+class _chistedit_state:
def __init__(
self,
repo,
@@ -2102,7 +2101,7 @@
mapping, tmpnodes, created, ntm = processreplacement(state)
if mapping:
- for prec, succs in pycompat.iteritems(mapping):
+ for prec, succs in mapping.items():
if not succs:
ui.debug(b'histedit: %s is dropped\n' % short(prec))
else:
@@ -2140,7 +2139,7 @@
nodechanges = fd(
{
hf(oldn): fl([hf(n) for n in newn], name=b'node')
- for oldn, newn in pycompat.iteritems(mapping)
+ for oldn, newn in mapping.items()
},
key=b"oldnode",
value=b"newnodes",
@@ -2388,7 +2387,7 @@
tsum = summary[len(fword) + 1 :].lstrip()
# safe but slow: reverse iterate over the actions so we
# don't clash on two commits having the same summary
- for na, l in reversed(list(pycompat.iteritems(newact))):
+ for na, l in reversed(list(newact.items())):
actx = repo[na.node]
asum = _getsummary(actx)
if asum == tsum:
@@ -2401,7 +2400,7 @@
# copy over and flatten the new list
actions = []
- for na, l in pycompat.iteritems(newact):
+ for na, l in newact.items():
actions.append(na)
actions += l
--- a/hgext/hooklib/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/hooklib/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -13,7 +13,6 @@
extension as option. The functionality itself is planned to be supported
long-term.
"""
-from __future__ import absolute_import
from . import (
changeset_obsoleted,
changeset_published,
--- a/hgext/hooklib/changeset_obsoleted.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/hooklib/changeset_obsoleted.py Fri Mar 25 11:33:12 2022 -0400
@@ -17,7 +17,6 @@
python:hgext.hooklib.changeset_obsoleted.hook
"""
-from __future__ import absolute_import
import email.errors as emailerrors
import email.utils as emailutils
--- a/hgext/hooklib/changeset_published.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/hooklib/changeset_published.py Fri Mar 25 11:33:12 2022 -0400
@@ -17,7 +17,6 @@
python:hgext.hooklib.changeset_published.hook
"""
-from __future__ import absolute_import
import email.errors as emailerrors
import email.utils as emailutils
--- a/hgext/hooklib/enforce_draft_commits.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/hooklib/enforce_draft_commits.py Fri Mar 25 11:33:12 2022 -0400
@@ -14,7 +14,6 @@
python:hgext.hooklib.enforce_draft_commits.hook
"""
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/hooklib/reject_merge_commits.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/hooklib/reject_merge_commits.py Fri Mar 25 11:33:12 2022 -0400
@@ -14,7 +14,6 @@
python:hgext.hooklib.reject_merge_commits.hook
"""
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/hooklib/reject_new_heads.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/hooklib/reject_new_heads.py Fri Mar 25 11:33:12 2022 -0400
@@ -14,7 +14,6 @@
python:hgext.hooklib.reject_new_heads.hook
"""
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/infinitepush/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/infinitepush/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -87,7 +87,6 @@
bookmarks = True
"""
-from __future__ import absolute_import
import collections
import contextlib
@@ -287,7 +286,7 @@
return remotebookmark
-class bundlestore(object):
+class bundlestore:
def __init__(self, repo):
self._repo = repo
storetype = self._repo.ui.config(b'infinitepush', b'storetype')
@@ -406,7 +405,7 @@
def wireprotolistkeyspatterns(repo, proto, namespace, patterns):
patterns = wireprototypes.decodelist(patterns)
- d = pycompat.iteritems(repo.listkeys(encoding.tolocal(namespace), patterns))
+ d = repo.listkeys(encoding.tolocal(namespace), patterns).items()
return pushkey.encodekeys(d)
@@ -420,7 +419,7 @@
if pattern.endswith(b'*'):
pattern = b're:^' + pattern[:-1] + b'.*'
kind, pat, matcher = stringutil.stringmatcher(pattern)
- for bookmark, node in pycompat.iteritems(bookmarks):
+ for bookmark, node in bookmarks.items():
if matcher(bookmark):
results[bookmark] = node
return results
@@ -543,7 +542,7 @@
if part.type == b'changegroup':
haschangegroup = True
newpart = bundle2.bundlepart(part.type, data=part.read())
- for key, value in pycompat.iteritems(part.params):
+ for key, value in part.params.items():
newpart.addparam(key, value)
parts.append(newpart)
@@ -795,7 +794,7 @@
# saveremotenames expects 20 byte binary nodes for branches
branches[rname].append(bin(hexnode))
- for bookmark, hexnode in pycompat.iteritems(newbookmarks):
+ for bookmark, hexnode in newbookmarks.items():
bookmarks[bookmark] = hexnode
remotenamesext.saveremotenames(repo, remotepath, branches, bookmarks)
@@ -805,7 +804,7 @@
return
with repo.wlock(), repo.lock(), repo.transaction(b'bookmark') as tr:
changes = []
- for scratchbook, node in pycompat.iteritems(bookmarks):
+ for scratchbook, node in bookmarks.items():
changectx = repo[node]
changes.append((scratchbook, changectx.node()))
repo._bookmarks.applychanges(repo, tr, changes)
@@ -1046,7 +1045,7 @@
bundle2._processpart(op, part)
else:
bundlepart = bundle2.bundlepart(part.type, data=part.read())
- for key, value in pycompat.iteritems(part.params):
+ for key, value in part.params.items():
bundlepart.addparam(key, value)
# Certain parts require a response
@@ -1138,7 +1137,7 @@
# differs from previous behavior, we need to put it behind a
# config flag for incremental rollout.
bundlepart = bundle2.bundlepart(part.type, data=part.read())
- for key, value in pycompat.iteritems(part.params):
+ for key, value in part.params.items():
bundlepart.addparam(key, value)
# Certain parts require a response
@@ -1324,9 +1323,7 @@
b'new': newnode,
b'old': oldnode,
}
- op.reply.newpart(
- b'pushkey', mandatoryparams=pycompat.iteritems(params)
- )
+ op.reply.newpart(b'pushkey', mandatoryparams=params.items())
def bundle2pushkey(orig, op, part):
--- a/hgext/infinitepush/bundleparts.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/infinitepush/bundleparts.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial.node import hex
@@ -13,7 +12,6 @@
changegroup,
error,
extensions,
- pycompat,
revsetlang,
util,
)
@@ -68,7 +66,7 @@
parts.append(
bundle2.bundlepart(
scratchbranchparttype.upper(),
- advisoryparams=pycompat.iteritems(params),
+ advisoryparams=params.items(),
data=cg,
)
)
@@ -103,7 +101,7 @@
return
-class copiedpart(object):
+class copiedpart:
"""a copy of unbundlepart content that can be consumed later"""
def __init__(self, part):
--- a/hgext/infinitepush/common.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/infinitepush/common.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
--- a/hgext/infinitepush/fileindexapi.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/infinitepush/fileindexapi.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,7 +11,6 @@
indexpath = PATH
"""
-from __future__ import absolute_import
import os
--- a/hgext/infinitepush/indexapi.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/infinitepush/indexapi.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,10 +5,8 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
-
-class indexapi(object):
+class indexapi:
"""Class that manages access to infinitepush index.
This class is a context manager and all write operations (like
--- a/hgext/infinitepush/sqlindexapi.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/infinitepush/sqlindexapi.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import logging
import os
@@ -14,8 +13,6 @@
import warnings
import mysql.connector
-from mercurial import pycompat
-
from . import indexapi
@@ -180,7 +177,7 @@
self.sqlconnect()
args = []
values = []
- for bookmark, node in pycompat.iteritems(bookmarks):
+ for bookmark, node in bookmarks.items():
args.append(b'(%s, %s, %s)')
values.extend((bookmark, node, self.reponame))
args = b','.join(args)
--- a/hgext/infinitepush/store.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/infinitepush/store.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# based on bundleheads extension by Gregory Szorc <gps@mozilla.com>
-from __future__ import absolute_import
import abc
import os
@@ -26,7 +25,7 @@
pass
-class abstractbundlestore(object): # pytype: disable=ignored-metaclass
+class abstractbundlestore: # pytype: disable=ignored-metaclass
"""Defines the interface for bundle stores.
A bundle store is an entity that stores raw bundle data. It is a simple
@@ -57,7 +56,7 @@
"""
-class filebundlestore(object):
+class filebundlestore:
"""bundle store in filesystem
meant for storing bundles somewhere on disk and on network filesystems
--- a/hgext/journal.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/journal.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,7 +11,6 @@
"""
-from __future__ import absolute_import
import collections
import errno
@@ -129,7 +128,7 @@
repo = store._repo
if util.safehasattr(repo, 'journal'):
oldmarks = bookmarks.bmstore(repo)
- for mark, value in pycompat.iteritems(store):
+ for mark, value in store.items():
oldvalue = oldmarks.get(mark, repo.nullid)
if value != oldvalue:
repo.journal.record(bookmarktype, mark, oldvalue, value)
@@ -167,7 +166,7 @@
pass
while iterable_map:
- value, key, it = order(pycompat.itervalues(iterable_map))
+ value, key, it = order(iterable_map.values())
yield value
try:
iterable_map[key][0] = next(it)
@@ -283,7 +282,7 @@
__str__ = encoding.strmethod(__bytes__)
-class journalstorage(object):
+class journalstorage:
"""Storage for journal entries
Entries are divided over two files; one with entries that pertain to the
--- a/hgext/keyword.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/keyword.py Fri Mar 25 11:33:12 2022 -0400
@@ -83,8 +83,6 @@
'''
-from __future__ import absolute_import
-
import os
import re
import weakref
@@ -237,7 +235,7 @@
return modified, added
-class kwtemplater(object):
+class kwtemplater:
"""
Sets up keyword templates, corresponding keyword regex, and
provides keyword substitution functions.
@@ -515,7 +513,7 @@
kwmaps = _defaultkwmaps(ui)
if uikwmaps:
ui.status(_(b'\tdisabling current template maps\n'))
- for k, v in pycompat.iteritems(kwmaps):
+ for k, v in kwmaps.items():
ui.setconfig(b'keywordmaps', k, v, b'keyword')
else:
ui.status(_(b'\n\tconfiguration using current keyword template maps\n'))
@@ -529,7 +527,7 @@
ui.writenoi18n(b'[extensions]\nkeyword =\n')
demoitems(b'keyword', ui.configitems(b'keyword'))
demoitems(b'keywordset', ui.configitems(b'keywordset'))
- demoitems(b'keywordmaps', pycompat.iteritems(kwmaps))
+ demoitems(b'keywordmaps', kwmaps.items())
keywords = b'$' + b'$\n$'.join(sorted(kwmaps.keys())) + b'$\n'
repo.wvfs.write(fn, keywords)
repo[None].add([fn])
--- a/hgext/largefiles/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -104,7 +104,6 @@
explicitly do so with the --large flag passed to the :hg:`add`
command.
'''
-from __future__ import absolute_import
from mercurial import (
cmdutil,
--- a/hgext/largefiles/basestore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/basestore.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
'''base class for store implementations and store-related utility code'''
-from __future__ import absolute_import
from mercurial.i18n import _
@@ -42,7 +41,7 @@
return b"%s: %s" % (urlutil.hidepassword(self.url), self.detail)
-class basestore(object):
+class basestore:
def __init__(self, ui, repo, url):
self.ui = ui
self.repo = repo
--- a/hgext/largefiles/lfcommands.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/lfcommands.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
'''High-level command function for lfconvert, plus the cmdtable.'''
-from __future__ import absolute_import
import errno
import os
--- a/hgext/largefiles/lfutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/lfutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
'''largefiles utility code: must not import other modules in this package.'''
-from __future__ import absolute_import
import contextlib
import copy
@@ -757,7 +756,7 @@
return match
-class automatedcommithook(object):
+class automatedcommithook:
"""Stateful hook to update standins at the 1st commit of resuming
For efficiency, updating standins in the working directory should
--- a/hgext/largefiles/localstore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/localstore.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
'''store class for local filesystem'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial.pycompat import open
--- a/hgext/largefiles/overrides.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/overrides.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
'''Overridden Mercurial commands and functions for the largefiles extension'''
-from __future__ import absolute_import
import copy
import os
@@ -493,7 +492,7 @@
large = opts.pop('large', False)
if large:
- class fakerepo(object):
+ class fakerepo:
dirstate = lfutil.openlfdirstate(ui, repo)
orig(ui, fakerepo, *pats, **opts)
@@ -714,7 +713,7 @@
copies = orig(ctx1, ctx2, match=match)
updated = {}
- for k, v in pycompat.iteritems(copies):
+ for k, v in copies.items():
updated[lfutil.splitstandin(k) or k] = lfutil.splitstandin(v) or v
return updated
--- a/hgext/largefiles/proto.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/proto.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
--- a/hgext/largefiles/remotestore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/remotestore.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,13 +5,11 @@
# GNU General Public License version 2 or any later version.
'''remote largefile store; the base class for wirestore'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
error,
- pycompat,
util,
)
@@ -53,9 +51,8 @@
def exists(self, hashes):
return {
h: s == 0
- for (h, s) in pycompat.iteritems(
- self._stat(hashes)
- ) # dict-from-generator
+ for (h, s) in self._stat(hashes).items()
+ # dict-from-generator
}
def sendfile(self, filename, hash):
--- a/hgext/largefiles/reposetup.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/reposetup.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
'''setup for largefiles repositories: reposetup'''
-from __future__ import absolute_import
import copy
--- a/hgext/largefiles/storefactory.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/storefactory.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
--- a/hgext/largefiles/wirestore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/largefiles/wirestore.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
# GNU General Public License version 2 or any later version.
'''largefile store working over Mercurial's wire protocol'''
-from __future__ import absolute_import
from . import (
lfutil,
--- a/hgext/lfs/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/lfs/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -120,7 +120,6 @@
usercache = /path/to/global/cache
"""
-from __future__ import absolute_import
import sys
@@ -400,7 +399,7 @@
def pointer(v):
# In the file spec, version is first and the other keys are sorted.
sortkeyfunc = lambda x: (x[0] != b'version', x)
- items = sorted(pycompat.iteritems(pointers[v]), key=sortkeyfunc)
+ items = sorted(pointers[v].items(), key=sortkeyfunc)
return util.sortdict(items)
makemap = lambda v: {
--- a/hgext/lfs/blobstore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/lfs/blobstore.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import errno
@@ -109,7 +108,7 @@
return None # progress is handled by the worker client
-class local(object):
+class local:
"""Local blobstore for large file contents.
This blobstore is used both as a cache and as a staging area for large blobs
@@ -274,7 +273,7 @@
except (AttributeError, IndexError):
# it might be anything, for example a string
reason = inst.reason
- if isinstance(reason, pycompat.unicode):
+ if isinstance(reason, str):
# SSLError of Python 2.7.9 contains a unicode
reason = encoding.unitolocal(reason)
return reason
@@ -307,7 +306,7 @@
return None
-class _gitlfsremote(object):
+class _gitlfsremote:
def __init__(self, repo, url):
ui = repo.ui
self.ui = ui
@@ -407,7 +406,7 @@
)
def encodestr(x):
- if isinstance(x, pycompat.unicode):
+ if isinstance(x, str):
return x.encode('utf-8')
return x
@@ -643,7 +642,7 @@
getattr(h, "close_all", lambda: None)()
-class _dummyremote(object):
+class _dummyremote:
"""Dummy store storing blobs to temp directory."""
def __init__(self, repo, url):
@@ -662,7 +661,7 @@
tostore.download(p.oid(), fp, None)
-class _nullremote(object):
+class _nullremote:
"""Null store storing blobs to /dev/null."""
def __init__(self, repo, url):
@@ -675,7 +674,7 @@
pass
-class _promptremote(object):
+class _promptremote:
"""Prompt user to set lfs.url when accessed."""
def __init__(self, repo, url):
--- a/hgext/lfs/pointer.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/lfs/pointer.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
@@ -41,7 +40,7 @@
def serialize(self):
sortkeyfunc = lambda x: (x[0] != b'version', x)
- items = sorted(pycompat.iteritems(self.validate()), key=sortkeyfunc)
+ items = sorted(self.validate().items(), key=sortkeyfunc)
return b''.join(b'%s %s\n' % (k, v) for k, v in items)
def oid(self):
@@ -63,7 +62,7 @@
def validate(self):
"""raise InvalidPointer on error. return self if there is no error"""
requiredcount = 0
- for k, v in pycompat.iteritems(self):
+ for k, v in self.items():
if k in self._requiredre:
if not self._requiredre[k].match(v):
raise InvalidPointer(
--- a/hgext/lfs/wireprotolfsserver.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/lfs/wireprotolfsserver.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import datetime
import errno
--- a/hgext/lfs/wrapper.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/lfs/wrapper.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import hashlib
@@ -25,7 +24,6 @@
exchange,
exthelper,
localrepo,
- pycompat,
revlog,
scmutil,
util,
@@ -143,7 +141,7 @@
# translate hg filelog metadata to lfs metadata with "x-hg-" prefix
if hgmeta is not None:
- for k, v in pycompat.iteritems(hgmeta):
+ for k, v in hgmeta.items():
metadata[b'x-hg-%s' % k] = v
rawtext = metadata.serialize()
--- a/hgext/logtoprocess.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/logtoprocess.py Fri Mar 25 11:33:12 2022 -0400
@@ -32,7 +32,6 @@
"""
-from __future__ import absolute_import
import os
@@ -45,7 +44,7 @@
testedwith = b'ships-with-hg-core'
-class processlogger(object):
+class processlogger:
"""Map log events to external commands
Arguments are passed on as environment variables.
--- a/hgext/mq.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/mq.py Fri Mar 25 11:33:12 2022 -0400
@@ -62,7 +62,6 @@
in the strip extension.
'''
-from __future__ import absolute_import, print_function
import errno
import os
@@ -151,7 +150,7 @@
except KeyError:
# note: load is lazy so we could avoid the try-except,
# but I (marmoute) prefer this explicit code.
- class dummyui(object):
+ class dummyui:
def debug(self, msg):
pass
@@ -184,7 +183,7 @@
normname = util.normpath
-class statusentry(object):
+class statusentry:
def __init__(self, node, name):
self.node, self.name = node, name
@@ -294,7 +293,7 @@
return lines
-class patchheader(object):
+class patchheader:
def __init__(self, pf, plainmode=False):
def eatdiff(lines):
while lines:
@@ -496,7 +495,7 @@
pass
-class queue(object):
+class queue:
def __init__(self, ui, baseui, path, patchdir=None):
self.basepath = path
try:
@@ -2025,7 +2024,7 @@
# we can't copy a file created by the patch itself
if dst in copies:
del copies[dst]
- for src, dsts in pycompat.iteritems(copies):
+ for src, dsts in copies.items():
for dst in dsts:
repo.dirstate.copy(src, dst)
else:
@@ -4288,7 +4287,7 @@
entry[1].extend(mqopt)
def dotable(cmdtable):
- for cmd, entry in pycompat.iteritems(cmdtable):
+ for cmd, entry in cmdtable.items():
cmd = cmdutil.parsealiases(cmd)[0]
func = entry[0]
if func.norepo:
--- a/hgext/narrow/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/narrow/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# GNU General Public License version 2 or any later version.
'''create clones which fetch history data for subset of files (EXPERIMENTAL)'''
-from __future__ import absolute_import
from mercurial import (
localrepo,
--- a/hgext/narrow/narrowbundle2.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/narrow/narrowbundle2.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import struct
--- a/hgext/narrow/narrowcommands.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/narrow/narrowcommands.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import itertools
import os
--- a/hgext/narrow/narrowdirstate.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/narrow/narrowdirstate.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import error
--- a/hgext/narrow/narrowrepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/narrow/narrowrepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial import wireprototypes
--- a/hgext/narrow/narrowtemplates.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/narrow/narrowtemplates.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial import (
registrar,
--- a/hgext/narrow/narrowwirepeer.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/narrow/narrowwirepeer.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial import (
bundle2,
--- a/hgext/notify.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/notify.py Fri Mar 25 11:33:12 2022 -0400
@@ -154,7 +154,6 @@
references. See also ``notify.strip``.
'''
-from __future__ import absolute_import
import email.errors as emailerrors
import email.utils as emailutils
@@ -315,7 +314,7 @@
}
-class notifier(object):
+class notifier:
'''email notification class.'''
def __init__(self, ui, repo, hooktype):
--- a/hgext/pager.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/pager.py Fri Mar 25 11:33:12 2022 -0400
@@ -21,7 +21,6 @@
[pager]
attend-cat = false
'''
-from __future__ import absolute_import
from mercurial import (
cmdutil,
--- a/hgext/patchbomb.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/patchbomb.py Fri Mar 25 11:33:12 2022 -0400
@@ -71,7 +71,6 @@
You can set patchbomb to always ask for confirmation by setting
``patchbomb.confirm`` to true.
'''
-from __future__ import absolute_import
import email.encoders as emailencoders
import email.mime.base as emimebase
--- a/hgext/phabricator.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/phabricator.py Fri Mar 25 11:33:12 2022 -0400
@@ -57,11 +57,11 @@
example.phabtoken = cli-xxxxxxxxxxxxxxxxxxxxxxxxxxxx
"""
-from __future__ import absolute_import
import base64
import contextlib
import hashlib
+import io
import itertools
import json
import mimetypes
@@ -219,9 +219,7 @@
rawparams = encoding.unifromlocal(wdirvfs.read(b".arcconfig"))
# json.loads only returns unicode strings
arcconfig = pycompat.rapply(
- lambda x: encoding.unitolocal(x)
- if isinstance(x, pycompat.unicode)
- else x,
+ lambda x: encoding.unitolocal(x) if isinstance(x, str) else x,
pycompat.json_loads(rawparams),
)
@@ -447,9 +445,7 @@
time.sleep(retry_interval)
ui.debug(b'Conduit Response: %s\n' % body)
parsed = pycompat.rapply(
- lambda x: encoding.unitolocal(x)
- if isinstance(x, pycompat.unicode)
- else x,
+ lambda x: encoding.unitolocal(x) if isinstance(x, str) else x,
# json.loads only accepts bytes from py3.6+
pycompat.json_loads(encoding.unifromlocal(body)),
)
@@ -473,9 +469,7 @@
rawparams = encoding.unifromlocal(ui.fin.read())
# json.loads only returns unicode strings
params = pycompat.rapply(
- lambda x: encoding.unitolocal(x)
- if isinstance(x, pycompat.unicode)
- else x,
+ lambda x: encoding.unitolocal(x) if isinstance(x, str) else x,
pycompat.json_loads(rawparams),
)
# json.dumps only accepts unicode strings
@@ -674,7 +668,7 @@
return output.getvalue()
-class DiffChangeType(object):
+class DiffChangeType:
ADD = 1
CHANGE = 2
DELETE = 3
@@ -685,7 +679,7 @@
MULTICOPY = 8
-class DiffFileType(object):
+class DiffFileType:
TEXT = 1
IMAGE = 2
BINARY = 3
@@ -706,7 +700,7 @@
@attr.s
-class phabchange(object):
+class phabchange:
"""Represents a Differential change, owns Differential hunks and owned by a
Differential diff. Each one represents one file in a diff.
"""
@@ -747,7 +741,7 @@
@attr.s
-class phabdiff(object):
+class phabdiff:
"""Represents a Differential diff, owns Differential changes. Corresponds
to a commit.
"""
@@ -2200,7 +2194,7 @@
for drev, contents in patches:
ui.status(_(b'applying patch from D%s\n') % drev)
- with patch.extract(ui, pycompat.bytesio(contents)) as patchdata:
+ with patch.extract(ui, io.BytesIO(contents)) as patchdata:
msg, node, rej = cmdutil.tryimportone(
ui,
repo,
@@ -2279,7 +2273,7 @@
drevmap = getdrevmap(repo, logcmdutil.revrange(repo, [revs]))
specs = []
unknown = []
- for r, d in pycompat.iteritems(drevmap):
+ for r, d in drevmap.items():
if d is None:
unknown.append(repo[r])
else:
@@ -2364,7 +2358,7 @@
revs = repo.revs('sort(_underway(), topo)')
drevmap = getdrevmap(repo, revs)
unknownrevs, drevids, revsbydrevid = [], set(), {}
- for rev, drevid in pycompat.iteritems(drevmap):
+ for rev, drevid in drevmap.items():
if drevid is not None:
drevids.add(drevid)
revsbydrevid.setdefault(drevid, set()).add(rev)
--- a/hgext/rebase.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/rebase.py Fri Mar 25 11:33:12 2022 -0400
@@ -14,7 +14,6 @@
https://mercurial-scm.org/wiki/RebaseExtension
'''
-from __future__ import absolute_import
import errno
import os
@@ -160,7 +159,7 @@
)
-class rebaseruntime(object):
+class rebaseruntime:
"""This class is a container for rebase runtime state"""
def __init__(self, repo, ui, inmemory=False, dryrun=False, opts=None):
@@ -244,7 +243,7 @@
f.write(b'%d\n' % int(self.keepbranchesf))
f.write(b'%s\n' % (self.activebookmark or b''))
destmap = self.destmap
- for d, v in pycompat.iteritems(self.state):
+ for d, v in self.state.items():
oldrev = repo[d].hex()
if v >= 0:
newrev = repo[v].hex()
@@ -506,7 +505,7 @@
# commits.
self.storestatus(tr)
- cands = [k for k, v in pycompat.iteritems(self.state) if v == revtodo]
+ cands = [k for k, v in self.state.items() if v == revtodo]
p = repo.ui.makeprogress(
_(b"rebasing"), unit=_(b'changesets'), total=len(cands)
)
@@ -1337,7 +1336,7 @@
# emulate the old behavior, showing "nothing to rebase" (a better
# behavior may be abort with "cannot find branching point" error)
bpbase.clear()
- for bp, bs in pycompat.iteritems(bpbase): # calculate roots
+ for bp, bs in bpbase.items(): # calculate roots
roots += list(repo.revs(b'children(%d) & ancestors(%ld)', bp, bs))
rebaseset = repo.revs(b'%ld::', roots)
@@ -2104,7 +2103,7 @@
fl = fm.formatlist
fd = fm.formatdict
changes = {}
- for oldns, newn in pycompat.iteritems(replacements):
+ for oldns, newn in replacements.items():
for oldn in oldns:
changes[hf(oldn)] = fl([hf(n) for n in newn], name=b'node')
nodechanges = fd(changes, key=b"oldnode", value=b"newnodes")
@@ -2258,7 +2257,7 @@
msg = _(b'rebase: (use "hg rebase --abort" to clear broken state)\n')
ui.write(msg)
return
- numrebased = len([i for i in pycompat.itervalues(state) if i >= 0])
+ numrebased = len([i for i in state.values() if i >= 0])
# i18n: column positioning for "hg summary"
ui.write(
_(b'rebase: %s, %s (rebase --continue)\n')
--- a/hgext/record.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/record.py Fri Mar 25 11:33:12 2022 -0400
@@ -10,7 +10,6 @@
The feature provided by this extension has been moved into core Mercurial as
:hg:`commit --interactive`.'''
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/hgext/releasenotes.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/releasenotes.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,7 +11,6 @@
process simpler by automating it.
"""
-from __future__ import absolute_import
import difflib
import errno
@@ -78,7 +77,7 @@
BULLET_SECTION = _(b'Other Changes')
-class parsedreleasenotes(object):
+class parsedreleasenotes:
def __init__(self):
self.sections = {}
@@ -171,14 +170,14 @@
self.addnontitleditem(section, paragraphs)
-class releasenotessections(object):
+class releasenotessections:
def __init__(self, ui, repo=None):
if repo:
sections = util.sortdict(DEFAULT_SECTIONS)
custom_sections = getcustomadmonitions(repo)
if custom_sections:
sections.update(custom_sections)
- self._sections = list(pycompat.iteritems(sections))
+ self._sections = list(sections.items())
else:
self._sections = list(DEFAULT_SECTIONS)
--- a/hgext/relink.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/relink.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# GNU General Public License version 2 or any later version.
"""recreates hardlinks between repository clones"""
-from __future__ import absolute_import
import os
import stat
--- a/hgext/remotefilelog/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -124,7 +124,6 @@
corruption before returning metadata
"""
-from __future__ import absolute_import
import os
import time
--- a/hgext/remotefilelog/basepack.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/basepack.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import collections
import errno
import mmap
@@ -65,7 +63,7 @@
PACKOPENMODE = b'rb'
-class _cachebackedpacks(object):
+class _cachebackedpacks:
def __init__(self, packs, cachesize):
self._packs = set(packs)
self._lrucache = util.lrucachedict(cachesize)
@@ -111,7 +109,7 @@
self._lastpack = None
-class basepackstore(object):
+class basepackstore:
# Default cache size limit for the pack files.
DEFAULTCACHESIZE = 100
@@ -269,7 +267,7 @@
return newpacks
-class versionmixin(object):
+class versionmixin:
# Mix-in for classes with multiple supported versions
VERSION = None
SUPPORTED_VERSIONS = [2]
@@ -528,7 +526,7 @@
self.idxfp.write(struct.pack(b'!BB', self.VERSION, config))
-class indexparams(object):
+class indexparams:
__slots__ = (
'fanoutprefix',
'fanoutstruct',
--- a/hgext/remotefilelog/basestore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/basestore.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import errno
import os
import shutil
@@ -21,7 +19,7 @@
)
-class basestore(object):
+class basestore:
def __init__(self, repo, path, reponame, shared=False):
"""Creates a remotefilelog store object for the given repo name.
@@ -148,7 +146,7 @@
filenamemap = self._resolvefilenames(existing.keys())
- for filename, sha in pycompat.iteritems(filenamemap):
+ for filename, sha in filenamemap.items():
yield (filename, existing[sha])
def _resolvefilenames(self, hashes):
@@ -414,7 +412,7 @@
)
-class baseunionstore(object):
+class baseunionstore:
def __init__(self, *args, **kwargs):
# If one of the functions that iterates all of the stores is about to
# throw a KeyError, try this many times with a full refresh between
--- a/hgext/remotefilelog/connectionpool.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/connectionpool.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,11 +5,9 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial import (
hg,
- pycompat,
sshpeer,
util,
)
@@ -17,7 +15,7 @@
_sshv1peer = sshpeer.sshv1peer
-class connectionpool(object):
+class connectionpool:
def __init__(self, repo):
self._repo = repo
self._pool = dict()
@@ -61,13 +59,13 @@
return conn
def close(self):
- for pathpool in pycompat.itervalues(self._pool):
+ for pathpool in self._pool.values():
for conn in pathpool:
conn.close()
del pathpool[:]
-class connection(object):
+class connection:
def __init__(self, pool, peer):
self._pool = pool
self.peer = peer
--- a/hgext/remotefilelog/constants.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/constants.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import struct
from mercurial.i18n import _
--- a/hgext/remotefilelog/contentstore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/contentstore.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import threading
from mercurial.node import (
@@ -19,7 +17,7 @@
)
-class ChainIndicies(object):
+class ChainIndicies:
"""A static class for easy reference to the delta chain indicies."""
# The filename of this revision delta
@@ -231,7 +229,7 @@
self._threaddata.metacache = (node, meta)
-class remotecontentstore(object):
+class remotecontentstore:
def __init__(self, ui, fileservice, shared):
self._fileservice = fileservice
# type(shared) is usually remotefilelogcontentstore
@@ -276,7 +274,7 @@
pass
-class manifestrevlogstore(object):
+class manifestrevlogstore:
def __init__(self, repo):
self._store = repo.store
self._svfs = repo.svfs
--- a/hgext/remotefilelog/datapack.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/datapack.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import struct
import zlib
@@ -455,7 +453,7 @@
def createindex(self, nodelocations, indexoffset):
entries = sorted(
- (n, db, o, s) for n, (db, o, s) in pycompat.iteritems(self.entries)
+ (n, db, o, s) for n, (db, o, s) in self.entries.items()
)
rawindex = b''
--- a/hgext/remotefilelog/debugcommands.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/debugcommands.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
import zlib
@@ -82,7 +81,7 @@
os.remove(temppath)
r = filelog.filelog(repo.svfs, b'temprevlog')
- class faket(object):
+ class faket:
def add(self, a, b, c):
pass
@@ -211,7 +210,7 @@
continue
filepath = os.path.join(root, file)
size, firstnode, mapping = parsefileblob(filepath, decompress)
- for p1, p2, linknode, copyfrom in pycompat.itervalues(mapping):
+ for p1, p2, linknode, copyfrom in mapping.values():
if linknode == sha1nodeconstants.nullid:
actualpath = os.path.relpath(root, path)
key = fileserverclient.getcachekey(
--- a/hgext/remotefilelog/fileserverclient.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/fileserverclient.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import io
import os
@@ -140,7 +139,7 @@
peer.__class__ = remotefilepeer
-class cacheconnection(object):
+class cacheconnection:
"""The connection for communicating with the remote cache. Performs
gets and sets by communicating with an external process that has the
cache-specific implementation.
@@ -303,7 +302,7 @@
pipeo.flush()
-class fileserverclient(object):
+class fileserverclient:
"""A client for requesting files from the remote file server."""
def __init__(self, repo):
@@ -518,7 +517,7 @@
# returns cache misses. This enables tests to run easily
# and may eventually allow us to be a drop in replacement
# for the largefiles extension.
- class simplecache(object):
+ class simplecache:
def __init__(self):
self.missingids = []
self.connected = True
--- a/hgext/remotefilelog/historypack.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/historypack.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import struct
from mercurial.node import (
@@ -521,7 +519,7 @@
files = (
(hashutil.sha1(filename).digest(), filename, offset, size)
- for filename, (offset, size) in pycompat.iteritems(self.files)
+ for filename, (offset, size) in self.files.items()
)
files = sorted(files)
@@ -557,7 +555,7 @@
)
nodeindexoffset += constants.FILENAMESIZE + len(filename)
- for node, location in sorted(pycompat.iteritems(nodelocations)):
+ for node, location in sorted(nodelocations.items()):
nodeindexentries.append(
struct.pack(nodeindexformat, node, location)
)
--- a/hgext/remotefilelog/metadatastore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/metadatastore.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from mercurial.node import (
hex,
sha1nodeconstants,
@@ -143,7 +141,7 @@
)
-class remotemetadatastore(object):
+class remotemetadatastore:
def __init__(self, ui, fileservice, shared):
self._fileservice = fileservice
self._shared = shared
--- a/hgext/remotefilelog/remotefilectx.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/remotefilectx.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import time
--- a/hgext/remotefilelog/remotefilelog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/remotefilelog.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import os
@@ -16,7 +15,6 @@
ancestor,
error,
mdiff,
- pycompat,
revlog,
)
from mercurial.utils import storageutil
@@ -29,7 +27,7 @@
)
-class remotefilelognodemap(object):
+class remotefilelognodemap:
def __init__(self, filename, store):
self._filename = filename
self._store = store
@@ -44,7 +42,7 @@
return node
-class remotefilelog(object):
+class remotefilelog:
_generaldelta = True
_flagserrorclass = error.RevlogError
@@ -424,7 +422,7 @@
return self.repo.nullid
revmap, parentfunc = self._buildrevgraph(a, b)
- nodemap = {v: k for (k, v) in pycompat.iteritems(revmap)}
+ nodemap = {v: k for (k, v) in revmap.items()}
ancs = ancestor.ancestors(parentfunc, revmap[a], revmap[b])
if ancs:
@@ -439,7 +437,7 @@
return self.repo.nullid
revmap, parentfunc = self._buildrevgraph(a, b)
- nodemap = {v: k for (k, v) in pycompat.iteritems(revmap)}
+ nodemap = {v: k for (k, v) in revmap.items()}
ancs = ancestor.commonancestorsheads(parentfunc, revmap[a], revmap[b])
return map(nodemap.__getitem__, ancs)
@@ -455,7 +453,7 @@
parentsmap = collections.defaultdict(list)
allparents = set()
for mapping in (amap, bmap):
- for node, pdata in pycompat.iteritems(mapping):
+ for node, pdata in mapping.items():
parents = parentsmap[node]
p1, p2, linknode, copyfrom = pdata
# Don't follow renames (copyfrom).
--- a/hgext/remotefilelog/remotefilelogserver.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/remotefilelogserver.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
@@ -22,7 +21,6 @@
error,
extensions,
match,
- pycompat,
scmutil,
store,
streamclone,
@@ -95,7 +93,7 @@
b'x_rfl_getfile', b'file node', permission=b'pull'
)(getfile)
- class streamstate(object):
+ class streamstate:
match = None
shallowremote = False
noflatmf = False
@@ -417,7 +415,7 @@
cachepath = repo.vfs.join(b"remotefilelogcache")
for head in heads:
mf = repo[head].manifest()
- for filename, filenode in pycompat.iteritems(mf):
+ for filename, filenode in mf.items():
filecachepath = os.path.join(cachepath, filename, hex(filenode))
neededfiles.add(filecachepath)
--- a/hgext/remotefilelog/repack.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/repack.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import os
import time
@@ -489,18 +487,18 @@
if type(m) is dict:
# m is a result of diff of two manifests and is a dictionary that
# maps filename to ((newnode, newflag), (oldnode, oldflag)) tuple
- for filename, diff in pycompat.iteritems(m):
+ for filename, diff in m.items():
if diff[0][0] is not None:
keepkeys.add(keyfn(filename, diff[0][0]))
else:
# m is a manifest object
- for filename, filenode in pycompat.iteritems(m):
+ for filename, filenode in m.items():
keepkeys.add(keyfn(filename, filenode))
return keepkeys
-class repacker(object):
+class repacker:
"""Class for orchestrating the repack of data and history information into a
new format.
"""
@@ -596,7 +594,7 @@
maxchainlen = ui.configint(b'packs', b'maxchainlen', 1000)
byfile = {}
- for entry in pycompat.itervalues(ledger.entries):
+ for entry in ledger.entries.values():
if entry.datasource:
byfile.setdefault(entry.filename, {})[entry.node] = entry
@@ -604,7 +602,7 @@
repackprogress = ui.makeprogress(
_(b"repacking data"), unit=self.unit, total=len(byfile)
)
- for filename, entries in sorted(pycompat.iteritems(byfile)):
+ for filename, entries in sorted(byfile.items()):
repackprogress.update(count)
ancestors = {}
@@ -751,14 +749,14 @@
ui = self.repo.ui
byfile = {}
- for entry in pycompat.itervalues(ledger.entries):
+ for entry in ledger.entries.values():
if entry.historysource:
byfile.setdefault(entry.filename, {})[entry.node] = entry
progress = ui.makeprogress(
_(b"repacking history"), unit=self.unit, total=len(byfile)
)
- for filename, entries in sorted(pycompat.iteritems(byfile)):
+ for filename, entries in sorted(byfile.items()):
ancestors = {}
nodes = list(node for node in entries)
@@ -821,7 +819,7 @@
return sortednodes
-class repackledger(object):
+class repackledger:
"""Storage for all the bookkeeping that happens during a repack. It contains
the list of revisions being repacked, what happened to each revision, and
which source store contained which revision originally (for later cleanup).
@@ -869,7 +867,7 @@
self.created.add(value)
-class repackentry(object):
+class repackentry:
"""Simple class representing a single revision entry in the repackledger."""
__slots__ = (
--- a/hgext/remotefilelog/shallowbundle.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/shallowbundle.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial.node import bin, hex
--- a/hgext/remotefilelog/shallowrepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/shallowrepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
@@ -15,7 +14,6 @@
error,
localrepo,
match,
- pycompat,
scmutil,
sparse,
util,
@@ -269,7 +267,7 @@
mfrevlog = mfl.getstorage(b'')
if base is not None:
mfdict = mfl[repo[base].manifestnode()].read()
- skip = set(pycompat.iteritems(mfdict))
+ skip = set(mfdict.items())
else:
skip = set()
@@ -299,7 +297,7 @@
else:
mfdict = mfl[mfnode].read()
- diff = pycompat.iteritems(mfdict)
+ diff = mfdict.items()
if pats:
diff = (pf for pf in diff if m(pf[0]))
if sparsematch:
--- a/hgext/remotefilelog/shallowstore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/shallowstore.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
def wrapstore(store):
--- a/hgext/remotefilelog/shallowutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/shallowutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import errno
@@ -103,7 +102,7 @@
"""
result = collections.defaultdict(lambda: 0)
for dict in dicts:
- for k, v in pycompat.iteritems(dict):
+ for k, v in dict.items():
result[k] += v
return result
@@ -111,7 +110,7 @@
def prefixkeys(dict, prefix):
"""Returns ``dict`` with ``prefix`` prepended to all its keys."""
result = {}
- for k, v in pycompat.iteritems(dict):
+ for k, v in dict.items():
result[prefix + k] = v
return result
@@ -160,7 +159,7 @@
length limit is exceeded
"""
metabuf = b''
- for k, v in sorted(pycompat.iteritems((metadict or {}))):
+ for k, v in sorted((metadict or {}).items()):
if len(k) != 1:
raise error.ProgrammingError(b'packmeta: illegal key: %s' % k)
if len(v) > 0xFFFE:
@@ -176,8 +175,8 @@
_metaitemtypes = {
- constants.METAKEYFLAG: (int, pycompat.long),
- constants.METAKEYSIZE: (int, pycompat.long),
+ constants.METAKEYFLAG: (int, int),
+ constants.METAKEYSIZE: (int, int),
}
@@ -188,7 +187,7 @@
and METAKEYFLAG will be dropped if its value is 0.
"""
newmeta = {}
- for k, v in pycompat.iteritems(metadict or {}):
+ for k, v in (metadict or {}).items():
expectedtype = _metaitemtypes.get(k, (bytes,))
if not isinstance(v, expectedtype):
raise error.ProgrammingError(b'packmeta: wrong type of key %s' % k)
@@ -209,7 +208,7 @@
integers.
"""
metadict = _parsepackmeta(metabuf)
- for k, v in pycompat.iteritems(metadict):
+ for k, v in metadict.items():
if k in _metaitemtypes and int in _metaitemtypes[k]:
metadict[k] = bin2int(v)
return metadict
--- a/hgext/remotefilelog/shallowverifier.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotefilelog/shallowverifier.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import verify
--- a/hgext/remotenames.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/remotenames.py Fri Mar 25 11:33:12 2022 -0400
@@ -24,7 +24,6 @@
namespace (default: 'default')
"""
-from __future__ import absolute_import
from mercurial.i18n import _
@@ -171,13 +170,13 @@
if not self.loaded:
self._load()
- for k, vtup in pycompat.iteritems(self.potentialentries):
+ for k, vtup in self.potentialentries.items():
yield (k, [bin(vtup[0])])
items = iteritems
-class remotenames(object):
+class remotenames:
"""
This class encapsulates all the remotenames state. It also contains
methods to access that state in convenient ways. Remotenames are lazy
@@ -208,7 +207,7 @@
if not self._nodetobmarks:
bmarktonodes = self.bmarktonodes()
self._nodetobmarks = {}
- for name, node in pycompat.iteritems(bmarktonodes):
+ for name, node in bmarktonodes.items():
self._nodetobmarks.setdefault(node[0], []).append(name)
return self._nodetobmarks
@@ -219,7 +218,7 @@
if not self._nodetobranch:
branchtonodes = self.branchtonodes()
self._nodetobranch = {}
- for name, nodes in pycompat.iteritems(branchtonodes):
+ for name, nodes in branchtonodes.items():
for node in nodes:
self._nodetobranch.setdefault(node, []).append(name)
return self._nodetobranch
@@ -229,7 +228,7 @@
marktonodes = self.bmarktonodes()
self._hoisttonodes = {}
hoist += b'/'
- for name, node in pycompat.iteritems(marktonodes):
+ for name, node in marktonodes.items():
if name.startswith(hoist):
name = name[len(hoist) :]
self._hoisttonodes[name] = node
@@ -240,7 +239,7 @@
marktonodes = self.bmarktonodes()
self._nodetohoists = {}
hoist += b'/'
- for name, node in pycompat.iteritems(marktonodes):
+ for name, node in marktonodes.items():
if name.startswith(hoist):
name = name[len(hoist) :]
self._nodetohoists.setdefault(node[0], []).append(name)
--- a/hgext/schemes.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/schemes.py Fri Mar 25 11:33:12 2022 -0400
@@ -39,7 +39,6 @@
You can override a predefined scheme by defining a new scheme with the
same name.
"""
-from __future__ import absolute_import
import os
import re
@@ -68,7 +67,7 @@
_partre = re.compile(br'{(\d+)\}')
-class ShortRepository(object):
+class ShortRepository:
def __init__(self, url, scheme, templater):
self.scheme = scheme
self.templater = templater
--- a/hgext/share.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/share.py Fri Mar 25 11:33:12 2022 -0400
@@ -65,7 +65,6 @@
and there are no untracked files, delete that share and create a new share.
'''
-from __future__ import absolute_import
import errno
from mercurial.i18n import _
--- a/hgext/show.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/show.py Fri Mar 25 11:33:12 2022 -0400
@@ -25,7 +25,6 @@
performed.
"""
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial.node import nullrev
--- a/hgext/sparse.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/sparse.py Fri Mar 25 11:33:12 2022 -0400
@@ -71,7 +71,6 @@
tools/tests/**
"""
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial.pycompat import setattr
--- a/hgext/split.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/split.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
"""command to split a changeset into smaller ones (EXPERIMENTAL)"""
-from __future__ import absolute_import
from mercurial.i18n import _
--- a/hgext/sqlitestore.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/sqlitestore.py Fri Mar 25 11:33:12 2022 -0400
@@ -43,7 +43,6 @@
# --extra-config-opt extensions.sqlitestore= \
# --extra-config-opt storage.new-repo-backend=sqlite
-from __future__ import absolute_import
import sqlite3
import struct
@@ -265,7 +264,7 @@
@attr.s
-class revisionentry(object):
+class revisionentry:
rid = attr.ib()
rev = attr.ib()
node = attr.ib()
@@ -279,7 +278,7 @@
@interfaceutil.implementer(repository.irevisiondelta)
@attr.s(slots=True)
-class sqliterevisiondelta(object):
+class sqliterevisiondelta:
node = attr.ib()
p1node = attr.ib()
p2node = attr.ib()
@@ -295,14 +294,14 @@
@interfaceutil.implementer(repository.iverifyproblem)
@attr.s(frozen=True)
-class sqliteproblem(object):
+class sqliteproblem:
warning = attr.ib(default=None)
error = attr.ib(default=None)
node = attr.ib(default=None)
@interfaceutil.implementer(repository.ifilestorage)
-class sqlitefilestore(object):
+class sqlitefilestore:
"""Implements storage for an individual tracked path."""
def __init__(self, db, path, compression):
@@ -1250,7 +1249,7 @@
@interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
-class sqlitefilestorage(object):
+class sqlitefilestorage:
"""Repository file storage backed by SQLite."""
def file(self, path):
--- a/hgext/strip.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/strip.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
This extension allows you to strip changesets and all their descendants from the
repository. See the command help for details.
"""
-from __future__ import absolute_import
from mercurial import commands
--- a/hgext/transplant.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/transplant.py Fri Mar 25 11:33:12 2022 -0400
@@ -13,7 +13,6 @@
Transplanted patches are recorded in .hg/transplant/transplants, as a
map from a changeset hash to its hash in the source repository.
'''
-from __future__ import absolute_import
import os
@@ -76,13 +75,13 @@
)
-class transplantentry(object):
+class transplantentry:
def __init__(self, lnode, rnode):
self.lnode = lnode
self.rnode = rnode
-class transplants(object):
+class transplants:
def __init__(self, path=None, transplantfile=None, opener=None):
self.path = path
self.transplantfile = transplantfile
@@ -107,7 +106,7 @@
if not os.path.isdir(self.path):
os.mkdir(self.path)
fp = self.opener(self.transplantfile, b'w')
- for list in pycompat.itervalues(self.transplants):
+ for list in self.transplants.values():
for t in list:
l, r = map(hex, (t.lnode, t.rnode))
fp.write(l + b':' + r + b'\n')
@@ -129,7 +128,7 @@
self.dirty = True
-class transplanter(object):
+class transplanter:
def __init__(self, ui, repo, opts):
self.ui = ui
self.repo = repo
--- a/hgext/uncommit.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/uncommit.py Fri Mar 25 11:33:12 2022 -0400
@@ -17,7 +17,6 @@
added and removed in the working directory.
"""
-from __future__ import absolute_import
from mercurial.i18n import _
@@ -81,9 +80,7 @@
files = initialfiles - exclude
# Filter copies
copied = copiesmod.pathcopies(base, ctx)
- copied = {
- dst: src for dst, src in pycompat.iteritems(copied) if dst in files
- }
+ copied = {dst: src for dst, src in copied.items() if dst in files}
def filectxfn(repo, memctx, path, contentctx=ctx, redirect=()):
if path not in contentctx:
--- a/hgext/win32mbcs.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/win32mbcs.py Fri Mar 25 11:33:12 2022 -0400
@@ -44,7 +44,6 @@
It is useful for the users who want to commit with UTF-8 log message.
'''
-from __future__ import absolute_import
import os
import sys
@@ -95,7 +94,7 @@
def encode(arg):
- if isinstance(arg, pycompat.unicode):
+ if isinstance(arg, str):
return arg.encode(_encoding)
elif isinstance(arg, tuple):
return tuple(map(encode, arg))
@@ -136,7 +135,7 @@
def wrapper(func, args, kwds):
- return basewrapper(func, pycompat.unicode, encode, decode, args, kwds)
+ return basewrapper(func, str, encode, decode, args, kwds)
def reversewrapper(func, args, kwds):
--- a/hgext/win32text.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/win32text.py Fri Mar 25 11:33:12 2022 -0400
@@ -41,7 +41,6 @@
# or pretxnchangegroup.cr = python:hgext.win32text.forbidcr
'''
-from __future__ import absolute_import
import re
from mercurial.i18n import _
@@ -213,7 +212,7 @@
def reposetup(ui, repo):
if not repo.local():
return
- for name, fn in pycompat.iteritems(_filters):
+ for name, fn in _filters.items():
repo.adddatafilter(name, fn)
--- a/hgext/zeroconf/Zeroconf.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/zeroconf/Zeroconf.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
""" Multicast DNS Service Discovery for Python, v0.12
Copyright (C) 2003, Paul Scott-Murphy
@@ -233,7 +231,7 @@
# implementation classes
-class DNSEntry(object):
+class DNSEntry:
"""A DNS entry"""
def __init__(self, name, type, clazz):
@@ -508,7 +506,7 @@
return self.toString(b"%s:%s" % (self.server, self.port))
-class DNSIncoming(object):
+class DNSIncoming:
"""Object representation of an incoming DNS packet"""
def __init__(self, data):
@@ -704,7 +702,7 @@
return result
-class DNSOutgoing(object):
+class DNSOutgoing:
"""Object representation of an outgoing packet"""
def __init__(self, flags, multicast=1):
@@ -866,7 +864,7 @@
return b''.join(self.data)
-class DNSCache(object):
+class DNSCache:
"""A cache of DNS entries"""
def __init__(self):
@@ -984,7 +982,7 @@
self.condition.release()
-class Listener(object):
+class Listener:
"""A Listener is used by this module to listen on the multicast
group to which DNS messages are sent, allowing the implementation
to cache information as it arrives.
@@ -1129,7 +1127,7 @@
event(self.zeroconf)
-class ServiceInfo(object):
+class ServiceInfo:
"""Service information"""
def __init__(
@@ -1388,7 +1386,7 @@
return result
-class Zeroconf(object):
+class Zeroconf:
"""Implementation of Zeroconf Multicast DNS Service Discovery
Supports registration, unregistration, queries and browsing.
--- a/hgext/zeroconf/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext/zeroconf/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -22,7 +22,6 @@
$ hg paths
zc-test = http://example.com:8000/test
'''
-from __future__ import absolute_import
import os
import socket
@@ -159,7 +158,7 @@
# listen
-class listener(object):
+class listener:
def __init__(self):
self.found = {}
--- a/hgext3rd/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/hgext3rd/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
# name space package to host third party extensions
-from __future__ import absolute_import
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
--- a/i18n/check-translation.py Tue Mar 22 03:19:01 2022 +0100
+++ b/i18n/check-translation.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
#!/usr/bin/env python3
#
# check-translation.py - check Mercurial specific translation problems
-from __future__ import absolute_import
import re
--- a/i18n/hggettext Tue Mar 22 03:19:01 2022 +0100
+++ b/i18n/hggettext Fri Mar 25 11:33:12 2022 -0400
@@ -20,7 +20,6 @@
join the message cataloges to get the final catalog.
"""
-from __future__ import absolute_import, print_function
import inspect
import os
--- a/i18n/polib.py Tue Mar 22 03:19:01 2022 +0100
+++ b/i18n/polib.py Fri Mar 25 11:33:12 2022 -0400
@@ -13,7 +13,6 @@
:func:`~polib.mofile` convenience functions.
"""
-from __future__ import absolute_import
__author__ = 'David Jean Louis <izimobil@gmail.com>'
__version__ = '1.0.7'
@@ -43,7 +42,7 @@
except ImportError:
# replacement of io.open() for python < 2.6
# we use codecs instead
- class io(object):
+ class io:
@staticmethod
def open(fpath, mode='r', encoding=None):
return codecs.open(fpath, mode, encoding)
@@ -817,7 +816,7 @@
# class _BaseEntry {{{
-class _BaseEntry(object):
+class _BaseEntry:
"""
Base class for :class:`~polib.POEntry` and :class:`~polib.MOEntry` classes.
This class should **not** be instanciated directly.
@@ -1228,7 +1227,7 @@
# class _POFileParser {{{
-class _POFileParser(object):
+class _POFileParser:
"""
A finite state machine to parse efficiently and correctly po
file format.
@@ -1707,7 +1706,7 @@
# class _MOFileParser {{{
-class _MOFileParser(object):
+class _MOFileParser:
"""
A class to parse binary mo files.
"""
--- a/i18n/posplit Tue Mar 22 03:19:01 2022 +0100
+++ b/i18n/posplit Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# license: MIT/X11/Expat
#
-from __future__ import absolute_import, print_function
import polib
import re
--- a/mercurial/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
# Allow 'from mercurial import demandimport' to keep working.
import hgdemandimport
--- a/mercurial/ancestor.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/ancestor.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import heapq
@@ -147,7 +146,7 @@
return deepest(gca)
-class incrementalmissingancestors(object):
+class incrementalmissingancestors:
"""persistent state used to calculate missing ancestors incrementally
Although similar in spirit to lazyancestors below, this is a separate class
@@ -317,7 +316,7 @@
see(p2)
-class lazyancestors(object):
+class lazyancestors:
def __init__(self, pfunc, revs, stoprev=0, inclusive=False):
"""Create a new object generating ancestors for the given revs. Does
not generate revs lower than stoprev.
--- a/mercurial/archival.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/archival.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import gzip
import os
@@ -76,7 +75,7 @@
def guesskind(dest):
- for kind, extensions in pycompat.iteritems(exts):
+ for kind, extensions in exts.items():
if any(dest.endswith(ext) for ext in extensions):
return kind
return None
@@ -133,43 +132,10 @@
return out.getvalue()
-class tarit(object):
+class tarit:
"""write archive to tar file or stream. can write uncompressed,
or compress with gzip or bzip2."""
- if pycompat.ispy3:
- GzipFileWithTime = gzip.GzipFile # camelcase-required
- else:
-
- class GzipFileWithTime(gzip.GzipFile):
- def __init__(self, *args, **kw):
- timestamp = None
- if 'mtime' in kw:
- timestamp = kw.pop('mtime')
- if timestamp is None:
- self.timestamp = time.time()
- else:
- self.timestamp = timestamp
- gzip.GzipFile.__init__(self, *args, **kw)
-
- def _write_gzip_header(self):
- self.fileobj.write(b'\037\213') # magic header
- self.fileobj.write(b'\010') # compression method
- fname = self.name
- if fname and fname.endswith(b'.gz'):
- fname = fname[:-3]
- flags = 0
- if fname:
- flags = gzip.FNAME # pytype: disable=module-attr
- self.fileobj.write(pycompat.bytechr(flags))
- gzip.write32u( # pytype: disable=module-attr
- self.fileobj, int(self.timestamp)
- )
- self.fileobj.write(b'\002')
- self.fileobj.write(b'\377')
- if fname:
- self.fileobj.write(fname + b'\000')
-
def __init__(self, dest, mtime, kind=b''):
self.mtime = mtime
self.fileobj = None
@@ -179,7 +145,7 @@
mode = mode[0:1]
if not fileobj:
fileobj = open(name, mode + b'b')
- gzfileobj = self.GzipFileWithTime(
+ gzfileobj = gzip.GzipFile(
name,
pycompat.sysstr(mode + b'b'),
zlib.Z_BEST_COMPRESSION,
@@ -227,7 +193,7 @@
self.fileobj.close()
-class zipit(object):
+class zipit:
"""write archive to zip file or stream. can write uncompressed,
or compressed with deflate."""
@@ -274,7 +240,7 @@
self.z.close()
-class fileit(object):
+class fileit:
'''write archive as files in directory.'''
def __init__(self, name, mtime):
@@ -339,9 +305,6 @@
subrepos tells whether to include subrepos.
"""
- if kind == b'txz' and not pycompat.ispy3:
- raise error.Abort(_(b'xz compression is only available in Python 3'))
-
if kind == b'files':
if prefix:
raise error.Abort(_(b'cannot give prefix when archiving to files'))
--- a/mercurial/bookmarks.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/bookmarks.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import struct
@@ -59,7 +58,7 @@
return fp
-class bmstore(object):
+class bmstore:
r"""Storage for bookmarks.
This object should do all bookmark-related reads and writes, so
@@ -138,7 +137,7 @@
return iter(self._refmap)
def iteritems(self):
- return pycompat.iteritems(self._refmap)
+ return self._refmap.items()
def items(self):
return self._refmap.items()
@@ -251,7 +250,7 @@
self._aclean = True
def _write(self, fp):
- for name, node in sorted(pycompat.iteritems(self._refmap)):
+ for name, node in sorted(self._refmap.items()):
fp.write(b"%s %s\n" % (hex(node), encoding.fromlocal(name)))
self._clean = True
self._repo.invalidatevolatilesets()
@@ -419,7 +418,7 @@
)
name = repo._activebookmark.split(b'@', 1)[0]
heads = []
- for mark, n in pycompat.iteritems(repo._bookmarks):
+ for mark, n in repo._bookmarks.items():
if mark.split(b'@', 1)[0] == name:
heads.append(n)
return heads
@@ -477,7 +476,7 @@
marks = getattr(repo, '_bookmarks', {})
hasnode = repo.changelog.hasnode
- for k, v in pycompat.iteritems(marks):
+ for k, v in marks.items():
# don't expose local divergent bookmarks
if hasnode(v) and not isdivergent(k):
yield k, v
@@ -688,7 +687,7 @@
remotemarks"""
changed = []
localmarks = repo._bookmarks
- for (b, id) in pycompat.iteritems(remotemarks):
+ for (b, id) in remotemarks.items():
if id != localmarks.get(b, None) and id in repo:
changed.append((b, id, ui.debug, _(b"updating bookmark %s\n") % b))
for b in localmarks:
@@ -1075,7 +1074,7 @@
hexfn = fm.hexfunc
if len(bmarks) == 0 and fm.isplain():
ui.status(_(b"no bookmarks set\n"))
- for bmark, (n, prefix, label) in sorted(pycompat.iteritems(bmarks)):
+ for bmark, (n, prefix, label) in sorted(bmarks.items()):
fm.startitem()
fm.context(repo=repo)
if not ui.quiet:
--- a/mercurial/branchmap.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/branchmap.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import struct
@@ -63,7 +62,7 @@
unpack_from = struct.unpack_from
-class BranchMapCache(object):
+class BranchMapCache:
"""mapping of filtered views of repo with their branchcache"""
def __init__(self):
@@ -120,7 +119,7 @@
clbranchinfo = cl.branchinfo
rbheads = []
closed = set()
- for bheads in pycompat.itervalues(remotebranchmap):
+ for bheads in remotebranchmap.values():
rbheads += bheads
for h in bheads:
r = clrev(h)
@@ -170,7 +169,7 @@
return b'branch cache'
-class branchcache(object):
+class branchcache:
"""A dict like object that hold branches heads cache.
This cache is used to avoid costly computations to determine all the
@@ -271,7 +270,7 @@
return key in self._entries
def iteritems(self):
- for k, v in pycompat.iteritems(self._entries):
+ for k, v in self._entries.items():
self._verifybranch(k)
yield k, v
@@ -401,13 +400,13 @@
return heads
def iterbranches(self):
- for bn, heads in pycompat.iteritems(self):
+ for bn, heads in self.items():
yield (bn, heads) + self._branchtip(heads)
def iterheads(self):
"""returns all the heads"""
self._verifyall()
- return pycompat.itervalues(self._entries)
+ return self._entries.values()
def copy(self):
"""return an deep copy of the branchcache object"""
@@ -435,7 +434,7 @@
cachekey.append(hex(self.filteredhash))
f.write(b" ".join(cachekey) + b'\n')
nodecount = 0
- for label, nodes in sorted(pycompat.iteritems(self._entries)):
+ for label, nodes in sorted(self._entries.items()):
label = encoding.fromlocal(label)
for node in nodes:
nodecount += 1
@@ -491,7 +490,7 @@
# Faster than using ctx.obsolete()
obsrevs = obsolete.getrevs(repo, b'obsolete')
- for branch, newheadrevs in pycompat.iteritems(newbranches):
+ for branch, newheadrevs in newbranches.items():
# For every branch, compute the new branchheads.
# A branchhead is a revision such that no descendant is on
# the same branch.
@@ -632,7 +631,7 @@
_rbccloseflag = 0x80000000
-class revbranchcache(object):
+class revbranchcache:
"""Persistent cache, mapping from revision number to branch name and close.
This is a low level cache, independent of filtering.
--- a/mercurial/bundle2.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/bundle2.py Fri Mar 25 11:33:12 2022 -0400
@@ -145,7 +145,6 @@
preserve.
"""
-from __future__ import absolute_import, division
import collections
import errno
@@ -252,7 +251,7 @@
return _decorator
-class unbundlerecords(object):
+class unbundlerecords:
"""keep record of what happens during and unbundle
New records are added using `records.add('cat', obj)`. Where 'cat' is a
@@ -300,7 +299,7 @@
__bool__ = __nonzero__
-class bundleoperation(object):
+class bundleoperation:
"""an object that represents a single bundling process
Its purpose is to carry unbundle-related objects and states.
@@ -380,7 +379,7 @@
return op
-class partiterator(object):
+class partiterator:
def __init__(self, repo, op, unbundler):
self.repo = repo
self.op = op
@@ -627,7 +626,7 @@
bundlepriority = [b'HG10GZ', b'HG10BZ', b'HG10UN']
-class bundle20(object):
+class bundle20:
"""represent an outgoing bundle2 container
Use the `addparam` method to add stream level parameter. and `newpart` to
@@ -751,7 +750,7 @@
return salvaged
-class unpackermixin(object):
+class unpackermixin:
"""A mixin to extract bytes and struct data from a stream"""
def __init__(self, fp):
@@ -984,7 +983,7 @@
unbundler._compressed = True
-class bundlepart(object):
+class bundlepart:
"""A bundle2 part contains application level payload
The part `type` is used to route the part to the application level
@@ -1274,7 +1273,7 @@
)
-class interruptoperation(object):
+class interruptoperation:
"""A limited operation to be use by part handler during interruption
It only have access to an ui object.
@@ -2240,7 +2239,7 @@
b'remote repository changed while pushing - please try again '
b'(%s is %s expected %s)'
)
- for expectedphase, nodes in pycompat.iteritems(phasetonodes):
+ for expectedphase, nodes in phasetonodes.items():
for n in nodes:
actualphase = phasecache.phase(unfi, cl.rev(n))
if actualphase != expectedphase:
--- a/mercurial/bundlecaches.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/bundlecaches.py Fri Mar 25 11:33:12 2022 -0400
@@ -21,7 +21,7 @@
@attr.s
-class bundlespec(object):
+class bundlespec:
compression = attr.ib()
wirecompression = attr.ib()
version = attr.ib()
@@ -343,7 +343,7 @@
return newentries
-class clonebundleentry(object):
+class clonebundleentry:
"""Represents an item in a clone bundles manifest.
This rich class is needed to support sorting since sorted() in Python 3
--- a/mercurial/bundlerepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/bundlerepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,7 +11,6 @@
were part of the actual repository.
"""
-from __future__ import absolute_import
import os
import shutil
@@ -271,7 +270,7 @@
return filespos
-class bundlerepository(object):
+class bundlerepository:
"""A repository instance that is a union of a local repo and a bundle.
Instances represent a read-only repository composed of a local repository
@@ -551,7 +550,7 @@
return repo
-class bundletransactionmanager(object):
+class bundletransactionmanager:
def transaction(self):
return None
--- a/mercurial/cacheutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cacheutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from . import repoview
--- a/mercurial/cext/base85.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/base85.c Fri Mar 25 11:33:12 2022 -0400
@@ -38,7 +38,7 @@
unsigned int acc, val, ch;
int pad = 0;
- if (!PyArg_ParseTuple(args, PY23("s#|i", "y#|i"), &text, &len, &pad)) {
+ if (!PyArg_ParseTuple(args, "y#|i", &text, &len, &pad)) {
return NULL;
}
@@ -90,7 +90,7 @@
int c;
unsigned int acc;
- if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &len)) {
+ if (!PyArg_ParseTuple(args, "y#", &text, &len)) {
return NULL;
}
@@ -177,7 +177,6 @@
static const int version = 1;
-#ifdef IS_PY3K
static struct PyModuleDef base85_module = {
PyModuleDef_HEAD_INIT, "base85", base85_doc, -1, methods,
};
@@ -191,13 +190,3 @@
PyModule_AddIntConstant(m, "version", version);
return m;
}
-#else
-PyMODINIT_FUNC initbase85(void)
-{
- PyObject *m;
- m = Py_InitModule3("base85", methods, base85_doc);
-
- b85prep();
- PyModule_AddIntConstant(m, "version", version);
-}
-#endif
--- a/mercurial/cext/bdiff.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/bdiff.c Fri Mar 25 11:33:12 2022 -0400
@@ -76,8 +76,7 @@
l.next = NULL;
- if (!PyArg_ParseTuple(args, PY23("s*s*:bdiff", "y*y*:bdiff"), &ba,
- &bb)) {
+ if (!PyArg_ParseTuple(args, "y*y*:bdiff", &ba, &bb)) {
return NULL;
}
@@ -233,7 +232,7 @@
Py_ssize_t nelts = 0, size, i, start = 0;
PyObject *result = NULL;
- if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &text, &size)) {
+ if (!PyArg_ParseTuple(args, "y#", &text, &size)) {
goto abort;
}
if (!size) {
@@ -299,8 +298,7 @@
NULL, /* priv */
};
- if (!PyArg_ParseTuple(args, PY23("s#s#", "y#y#"), &a.ptr, &la, &b.ptr,
- &lb)) {
+ if (!PyArg_ParseTuple(args, "y#y#", &a.ptr, &la, &b.ptr, &lb)) {
return NULL;
}
@@ -337,7 +335,6 @@
static const int version = 3;
-#ifdef IS_PY3K
static struct PyModuleDef bdiff_module = {
PyModuleDef_HEAD_INIT, "bdiff", mdiff_doc, -1, methods,
};
@@ -349,11 +346,3 @@
PyModule_AddIntConstant(m, "version", version);
return m;
}
-#else
-PyMODINIT_FUNC initbdiff(void)
-{
- PyObject *m;
- m = Py_InitModule3("bdiff", methods, mdiff_doc);
- PyModule_AddIntConstant(m, "version", version);
-}
-#endif
--- a/mercurial/cext/charencode.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/charencode.c Fri Mar 25 11:33:12 2022 -0400
@@ -15,14 +15,6 @@
#include "compat.h"
#include "util.h"
-#ifdef IS_PY3K
-/* The mapping of Python types is meant to be temporary to get Python
- * 3 to compile. We should remove this once Python 3 support is fully
- * supported and proper types are used in the extensions themselves. */
-#define PyInt_Type PyLong_Type
-#define PyInt_AS_LONG PyLong_AS_LONG
-#endif
-
/* clang-format off */
static const char lowertable[128] = {
'\x00', '\x01', '\x02', '\x03', '\x04', '\x05', '\x06', '\x07',
@@ -133,8 +125,7 @@
{
const char *buf;
Py_ssize_t i, len;
- if (!PyArg_ParseTuple(args, PY23("s#:isasciistr", "y#:isasciistr"),
- &buf, &len)) {
+ if (!PyArg_ParseTuple(args, "y#:isasciistr", &buf, &len)) {
return NULL;
}
i = 0;
@@ -228,12 +219,12 @@
const char *table;
if (!PyArg_ParseTuple(args, "O!O!O!:make_file_foldmap", &PyDict_Type,
- &dmap, &PyInt_Type, &spec_obj, &PyFunction_Type,
+ &dmap, &PyLong_Type, &spec_obj, &PyFunction_Type,
&normcase_fallback)) {
goto quit;
}
- spec = (int)PyInt_AS_LONG(spec_obj);
+ spec = (int)PyLong_AS_LONG(spec_obj);
switch (spec) {
case NORMCASE_LOWER:
table = lowertable;
--- a/mercurial/cext/dirs.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/dirs.c Fri Mar 25 11:33:12 2022 -0400
@@ -13,11 +13,7 @@
#include "util.h"
-#ifdef IS_PY3K
#define PYLONG_VALUE(o) ((PyLongObject *)o)->ob_digit[0]
-#else
-#define PYLONG_VALUE(o) PyInt_AS_LONG(o)
-#endif
/*
* This is a multiset of directory names, built from the files that
@@ -100,11 +96,7 @@
}
/* Force Python to not reuse a small shared int. */
-#ifdef IS_PY3K
val = PyLong_FromLong(0x1eadbeef);
-#else
- val = PyInt_FromLong(0x1eadbeef);
-#endif
if (val == NULL)
goto bail;
--- a/mercurial/cext/manifest.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/manifest.c Fri Mar 25 11:33:12 2022 -0400
@@ -317,12 +317,7 @@
return ret;
}
-#ifdef IS_PY3K
#define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT
-#else
-#define LAZYMANIFESTENTRIESITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \
- | Py_TPFLAGS_HAVE_ITER
-#endif
static PyTypeObject lazymanifestEntriesIterator = {
PyVarObject_HEAD_INIT(NULL, 0) /* header */
@@ -365,12 +360,7 @@
return PyBytes_FromStringAndSize(l->start, pl);
}
-#ifdef IS_PY3K
#define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT
-#else
-#define LAZYMANIFESTKEYSITERATOR_TPFLAGS Py_TPFLAGS_DEFAULT \
- | Py_TPFLAGS_HAVE_ITER
-#endif
static PyTypeObject lazymanifestKeysIterator = {
PyVarObject_HEAD_INIT(NULL, 0) /* header */
@@ -790,7 +780,7 @@
Py_INCREF(copy->pydata);
for (i = 0; i < self->numlines; i++) {
PyObject *arglist = NULL, *result = NULL;
- arglist = Py_BuildValue(PY23("(s)", "(y)"),
+ arglist = Py_BuildValue("(y)",
self->lines[i].start);
if (!arglist) {
goto bail;
@@ -955,11 +945,7 @@
{NULL},
};
-#ifdef IS_PY3K
#define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT
-#else
-#define LAZYMANIFEST_TPFLAGS Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_SEQUENCE_IN
-#endif
static PyTypeObject lazymanifestType = {
PyVarObject_HEAD_INIT(NULL, 0) /* header */
--- a/mercurial/cext/mpatch.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/mpatch.c Fri Mar 25 11:33:12 2022 -0400
@@ -144,8 +144,7 @@
Py_ssize_t patchlen;
char *bin;
- if (!PyArg_ParseTuple(args, PY23("ls#", "ly#"), &orig, &bin,
- &patchlen)) {
+ if (!PyArg_ParseTuple(args, "ly#", &orig, &bin, &patchlen)) {
return NULL;
}
@@ -182,7 +181,6 @@
static const int version = 1;
-#ifdef IS_PY3K
static struct PyModuleDef mpatch_module = {
PyModuleDef_HEAD_INIT, "mpatch", mpatch_doc, -1, methods,
};
@@ -203,13 +201,3 @@
return m;
}
-#else
-PyMODINIT_FUNC initmpatch(void)
-{
- PyObject *m;
- m = Py_InitModule3("mpatch", methods, mpatch_doc);
- mpatch_Error =
- PyErr_NewException("mercurial.cext.mpatch.mpatchError", NULL, NULL);
- PyModule_AddIntConstant(m, "version", version);
-}
-#endif
--- a/mercurial/cext/osutil.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/osutil.c Fri Mar 25 11:33:12 2022 -0400
@@ -73,19 +73,11 @@
};
#endif
-#ifdef IS_PY3K
#define listdir_slot(name) \
static PyObject *listdir_stat_##name(PyObject *self, void *x) \
{ \
return PyLong_FromLong(((struct listdir_stat *)self)->st.name); \
}
-#else
-#define listdir_slot(name) \
- static PyObject *listdir_stat_##name(PyObject *self, void *x) \
- { \
- return PyInt_FromLong(((struct listdir_stat *)self)->st.name); \
- }
-#endif
listdir_slot(st_dev)
listdir_slot(st_mode)
@@ -206,7 +198,7 @@
? _S_IFDIR : _S_IFREG;
if (!wantstat)
- return Py_BuildValue(PY23("si", "yi"), fd->cFileName, kind);
+ return Py_BuildValue("yi", fd->cFileName, kind);
py_st = PyObject_CallObject((PyObject *)&listdir_stat_type, NULL);
if (!py_st)
@@ -224,7 +216,7 @@
if (kind == _S_IFREG)
stp->st_size = ((__int64)fd->nFileSizeHigh << 32)
+ fd->nFileSizeLow;
- return Py_BuildValue(PY23("siN", "yiN"), fd->cFileName,
+ return Py_BuildValue("yiN", fd->cFileName,
kind, py_st);
}
@@ -412,10 +404,10 @@
PyObject *stat = makestat(&st);
if (!stat)
goto error;
- elem = Py_BuildValue(PY23("siN", "yiN"), ent->d_name,
+ elem = Py_BuildValue("yiN", ent->d_name,
kind, stat);
} else
- elem = Py_BuildValue(PY23("si", "yi"), ent->d_name,
+ elem = Py_BuildValue("yi", ent->d_name,
kind);
if (!elem)
goto error;
@@ -593,10 +585,10 @@
stat = makestat(&st);
if (!stat)
goto error;
- elem = Py_BuildValue(PY23("siN", "yiN"),
+ elem = Py_BuildValue("yiN",
filename, kind, stat);
} else
- elem = Py_BuildValue(PY23("si", "yi"),
+ elem = Py_BuildValue("yi",
filename, kind);
if (!elem)
goto error;
@@ -767,10 +759,6 @@
#if defined(HAVE_SETPROCTITLE)
/* setproctitle is the first choice - available in FreeBSD */
#define SETPROCNAME_USE_SETPROCTITLE
-#elif (defined(__linux__) || defined(__APPLE__)) && PY_MAJOR_VERSION == 2
-/* rewrite the argv buffer in place - works in Linux and OS X. Py_GetArgcArgv
- * in Python 3 returns the copied wchar_t **argv, thus unsupported. */
-#define SETPROCNAME_USE_ARGVREWRITE
#else
#define SETPROCNAME_USE_NONE
#endif
@@ -780,49 +768,11 @@
static PyObject *setprocname(PyObject *self, PyObject *args)
{
const char *name = NULL;
- if (!PyArg_ParseTuple(args, PY23("s", "y"), &name))
+ if (!PyArg_ParseTuple(args, "y", &name))
return NULL;
#if defined(SETPROCNAME_USE_SETPROCTITLE)
setproctitle("%s", name);
-#elif defined(SETPROCNAME_USE_ARGVREWRITE)
- {
- static char *argvstart = NULL;
- static size_t argvsize = 0;
- if (argvstart == NULL) {
- int argc = 0, i;
- char **argv = NULL;
- char *argvend;
- extern void Py_GetArgcArgv(int *argc, char ***argv);
- Py_GetArgcArgv(&argc, &argv);
- /* Py_GetArgcArgv may not do much if a custom python
- * launcher is used that doesn't record the information
- * it needs. Let's handle this gracefully instead of
- * segfaulting. */
- if (argv != NULL)
- argvend = argvstart = argv[0];
- else
- argvend = argvstart = NULL;
-
- /* Check the memory we can use. Typically, argv[i] and
- * argv[i + 1] are continuous. */
- for (i = 0; i < argc; ++i) {
- size_t len;
- if (argv[i] > argvend || argv[i] < argvstart)
- break; /* not continuous */
- len = strlen(argv[i]);
- argvend = argv[i] + len + 1 /* '\0' */;
- }
- if (argvend > argvstart) /* sanity check */
- argvsize = argvend - argvstart;
- }
-
- if (argvstart && argvsize > 1) {
- int n = snprintf(argvstart, argvsize, "%s", name);
- if (n >= 0 && (size_t)n < argvsize)
- memset(argvstart + n, 0, argvsize - n);
- }
- }
#endif
Py_RETURN_NONE;
@@ -1135,14 +1085,14 @@
const char *path = NULL;
struct statfs buf;
int r;
- if (!PyArg_ParseTuple(args, PY23("s", "y"), &path))
+ if (!PyArg_ParseTuple(args, "y", &path))
return NULL;
memset(&buf, 0, sizeof(buf));
r = statfs(path, &buf);
if (r != 0)
return PyErr_SetFromErrno(PyExc_OSError);
- return Py_BuildValue(PY23("s", "y"), describefstype(&buf));
+ return Py_BuildValue("y", describefstype(&buf));
}
#endif /* defined(HAVE_LINUX_STATFS) || defined(HAVE_BSD_STATFS) */
@@ -1153,14 +1103,14 @@
const char *path = NULL;
struct statfs buf;
int r;
- if (!PyArg_ParseTuple(args, PY23("s", "y"), &path))
+ if (!PyArg_ParseTuple(args, "y", &path))
return NULL;
memset(&buf, 0, sizeof(buf));
r = statfs(path, &buf);
if (r != 0)
return PyErr_SetFromErrno(PyExc_OSError);
- return Py_BuildValue(PY23("s", "y"), buf.f_mntonname);
+ return Py_BuildValue("y", buf.f_mntonname);
}
#endif /* defined(HAVE_BSD_STATFS) */
@@ -1195,8 +1145,7 @@
static char *kwlist[] = {"path", "stat", "skip", NULL};
- if (!PyArg_ParseTupleAndKeywords(args, kwargs, PY23("s#|OO:listdir",
- "y#|OO:listdir"),
+ if (!PyArg_ParseTupleAndKeywords(args, kwargs, "y#|OO:listdir",
kwlist, &path, &plen, &statobj, &skipobj))
return NULL;
@@ -1227,12 +1176,8 @@
char fpmode[4];
int fppos = 0;
int plus;
-#ifndef IS_PY3K
- FILE *fp;
-#endif
- if (!PyArg_ParseTupleAndKeywords(args, kwds, PY23("et|si:posixfile",
- "et|yi:posixfile"),
+ if (!PyArg_ParseTupleAndKeywords(args, kwds, "et|yi:posixfile",
kwlist,
Py_FileSystemDefaultEncoding,
&name, &mode, &bufsize))
@@ -1302,26 +1247,9 @@
PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
goto bail;
}
-#ifndef IS_PY3K
- fp = _fdopen(fd, fpmode);
- if (fp == NULL) {
- _close(fd);
- PyErr_SetFromErrnoWithFilename(PyExc_IOError, name);
- goto bail;
- }
-
- file_obj = PyFile_FromFile(fp, name, mode, fclose);
- if (file_obj == NULL) {
- fclose(fp);
- goto bail;
- }
-
- PyFile_SetBufSize(file_obj, bufsize);
-#else
file_obj = PyFile_FromFd(fd, name, mode, bufsize, NULL, NULL, NULL, 1);
if (file_obj == NULL)
goto bail;
-#endif
bail:
PyMem_Free(name);
return file_obj;
@@ -1387,7 +1315,6 @@
static const int version = 4;
-#ifdef IS_PY3K
static struct PyModuleDef osutil_module = {
PyModuleDef_HEAD_INIT,
"osutil",
@@ -1406,14 +1333,3 @@
PyModule_AddIntConstant(m, "version", version);
return m;
}
-#else
-PyMODINIT_FUNC initosutil(void)
-{
- PyObject *m;
- if (PyType_Ready(&listdir_stat_type) == -1)
- return;
-
- m = Py_InitModule3("osutil", methods, osutil_doc);
- PyModule_AddIntConstant(m, "version", version);
-}
-#endif
--- a/mercurial/cext/parsers.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/parsers.c Fri Mar 25 11:33:12 2022 -0400
@@ -17,22 +17,6 @@
#include "charencode.h"
#include "util.h"
-#ifdef IS_PY3K
-/* The mapping of Python types is meant to be temporary to get Python
- * 3 to compile. We should remove this once Python 3 support is fully
- * supported and proper types are used in the extensions themselves. */
-#define PyInt_Check PyLong_Check
-#define PyInt_FromLong PyLong_FromLong
-#define PyInt_FromSsize_t PyLong_FromSsize_t
-#define PyInt_AsLong PyLong_AsLong
-#else
-/* Windows on Python 2.7 doesn't define S_IFLNK. Python 3+ defines via
- * pyport.h. */
-#ifndef S_IFLNK
-#define S_IFLNK 0120000
-#endif
-#endif
-
static const char *const versionerrortext = "Python minor version mismatch";
static const int dirstate_v1_from_p2 = -2;
@@ -313,17 +297,17 @@
static PyObject *dirstate_item_v1_mode(dirstateItemObject *self)
{
- return PyInt_FromLong(dirstate_item_c_v1_mode(self));
+ return PyLong_FromLong(dirstate_item_c_v1_mode(self));
};
static PyObject *dirstate_item_v1_size(dirstateItemObject *self)
{
- return PyInt_FromLong(dirstate_item_c_v1_size(self));
+ return PyLong_FromLong(dirstate_item_c_v1_size(self));
};
static PyObject *dirstate_item_v1_mtime(dirstateItemObject *self)
{
- return PyInt_FromLong(dirstate_item_c_v1_mtime(self));
+ return PyLong_FromLong(dirstate_item_c_v1_mtime(self));
};
static PyObject *dirstate_item_mtime_likely_equal_to(dirstateItemObject *self,
@@ -569,17 +553,17 @@
static PyObject *dirstate_item_get_mode(dirstateItemObject *self)
{
- return PyInt_FromLong(dirstate_item_c_v1_mode(self));
+ return PyLong_FromLong(dirstate_item_c_v1_mode(self));
};
static PyObject *dirstate_item_get_size(dirstateItemObject *self)
{
- return PyInt_FromLong(dirstate_item_c_v1_size(self));
+ return PyLong_FromLong(dirstate_item_c_v1_size(self));
};
static PyObject *dirstate_item_get_mtime(dirstateItemObject *self)
{
- return PyInt_FromLong(dirstate_item_c_v1_mtime(self));
+ return PyLong_FromLong(dirstate_item_c_v1_mtime(self));
};
static PyObject *dirstate_item_get_state(dirstateItemObject *self)
@@ -829,9 +813,8 @@
Py_ssize_t len = 40;
Py_ssize_t readlen;
- if (!PyArg_ParseTuple(
- args, PY23("O!O!s#:parse_dirstate", "O!O!y#:parse_dirstate"),
- &PyDict_Type, &dmap, &PyDict_Type, &cmap, &str, &readlen)) {
+ if (!PyArg_ParseTuple(args, "O!O!y#:parse_dirstate", &PyDict_Type,
+ &dmap, &PyDict_Type, &cmap, &str, &readlen)) {
goto quit;
}
@@ -844,8 +827,8 @@
goto quit;
}
- parents = Py_BuildValue(PY23("s#s#", "y#y#"), str, (Py_ssize_t)20,
- str + 20, (Py_ssize_t)20);
+ parents = Py_BuildValue("y#y#", str, (Py_ssize_t)20, str + 20,
+ (Py_ssize_t)20);
if (!parents) {
goto quit;
}
@@ -1174,8 +1157,7 @@
Py_ssize_t datalen, offset, stop;
PyObject *markers = NULL;
- if (!PyArg_ParseTuple(args, PY23("s#nn", "y#nn"), &data, &datalen,
- &offset, &stop)) {
+ if (!PyArg_ParseTuple(args, "y#nn", &data, &datalen, &offset, &stop)) {
return NULL;
}
if (offset < 0) {
@@ -1287,7 +1269,7 @@
if (!ver) {
return -1;
}
- hexversion = PyInt_AsLong(ver);
+ hexversion = PyLong_AsLong(ver);
Py_DECREF(ver);
/* sys.hexversion is a 32-bit number by default, so the -1 case
* should only occur in unusual circumstances (e.g. if sys.hexversion
@@ -1307,7 +1289,6 @@
return 0;
}
-#ifdef IS_PY3K
static struct PyModuleDef parsers_module = {PyModuleDef_HEAD_INIT, "parsers",
parsers_doc, -1, methods};
@@ -1321,15 +1302,3 @@
module_init(mod);
return mod;
}
-#else
-PyMODINIT_FUNC initparsers(void)
-{
- PyObject *mod;
-
- if (check_python_version() == -1) {
- return;
- }
- mod = Py_InitModule3("parsers", methods, parsers_doc);
- module_init(mod);
-}
-#endif
--- a/mercurial/cext/pathencode.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/pathencode.c Fri Mar 25 11:33:12 2022 -0400
@@ -535,8 +535,7 @@
Py_ssize_t len, newlen;
PyObject *ret;
- if (!PyArg_ParseTuple(args, PY23("s#:lowerencode", "y#:lowerencode"),
- &path, &len)) {
+ if (!PyArg_ParseTuple(args, "y#:lowerencode", &path, &len)) {
return NULL;
}
@@ -711,7 +710,7 @@
}
}
- shaobj = PyObject_CallFunction(shafunc, PY23("s#", "y#"), str, len);
+ shaobj = PyObject_CallFunction(shafunc, "y#", str, len);
if (shaobj == NULL) {
return -1;
--- a/mercurial/cext/revlog.c Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/revlog.c Fri Mar 25 11:33:12 2022 -0400
@@ -23,16 +23,6 @@
#include "revlog.h"
#include "util.h"
-#ifdef IS_PY3K
-/* The mapping of Python types is meant to be temporary to get Python
- * 3 to compile. We should remove this once Python 3 support is fully
- * supported and proper types are used in the extensions themselves. */
-#define PyInt_Check PyLong_Check
-#define PyInt_FromLong PyLong_FromLong
-#define PyInt_FromSsize_t PyLong_FromSsize_t
-#define PyInt_AsLong PyLong_AsLong
-#endif
-
typedef struct indexObjectStruct indexObject;
typedef struct {
@@ -43,6 +33,7 @@
int abi_version;
Py_ssize_t (*index_length)(const indexObject *);
const char *(*index_node)(indexObject *, Py_ssize_t);
+ int (*fast_rank)(indexObject *, Py_ssize_t);
int (*index_parents)(PyObject *, int, int *);
} Revlog_CAPI;
@@ -119,11 +110,9 @@
static int index_find_node(indexObject *self, const char *node);
#if LONG_MAX == 0x7fffffffL
-static const char *const tuple_format =
- PY23("Kiiiiiis#KiBBi", "Kiiiiiiy#KiBBi");
+static const char *const tuple_format = "Kiiiiiiy#KiBBi";
#else
-static const char *const tuple_format =
- PY23("kiiiiiis#kiBBi", "kiiiiiiy#kiBBi");
+static const char *const tuple_format = "kiiiiiiy#kiBBi";
#endif
/* A RevlogNG v1 index entry is 64 bytes long. */
@@ -576,6 +565,33 @@
}
/*
+ * Return the stored rank of a given revision if known, or rank_unknown
+ * otherwise.
+ *
+ * The rank of a revision is the size of the sub-graph it defines as a head.
+ * Equivalently, the rank of a revision `r` is the size of the set
+ * `ancestors(r)`, `r` included.
+ *
+ * This method returns the rank retrieved from the revlog in constant time. It
+ * makes no attempt at computing unknown values for versions of the revlog
+ * which do not persist the rank.
+ */
+static int index_fast_rank(indexObject *self, Py_ssize_t pos)
+{
+ Py_ssize_t length = index_length(self);
+
+ if (self->format_version != format_cl2 || pos >= length) {
+ return rank_unknown;
+ }
+
+ if (pos == nullrev) {
+ return 0; /* convention */
+ }
+
+ return getbe32(index_deref(self, pos) + entry_cl2_offset_rank);
+}
+
+/*
* Return the hash of the node corresponding to the given rev. The
* rev is assumed to be existing. If not, an exception is set.
*/
@@ -730,9 +746,9 @@
char comp_mode;
char *data;
#if LONG_MAX == 0x7fffffffL
- const char *const sidedata_format = PY23("nKiKB", "nKiKB");
+ const char *const sidedata_format = "nKiKB";
#else
- const char *const sidedata_format = PY23("nkikB", "nkikB");
+ const char *const sidedata_format = "nkikB";
#endif
if (self->entry_size == v1_entry_size || self->inlined) {
@@ -802,7 +818,7 @@
#define istat(__n, __d) \
do { \
s = PyBytes_FromString(__d); \
- t = PyInt_FromSsize_t(self->__n); \
+ t = PyLong_FromSsize_t(self->__n); \
if (!s || !t) \
goto bail; \
if (PyDict_SetItem(obj, s, t) == -1) \
@@ -953,7 +969,7 @@
l = PyList_GET_SIZE(roots);
for (i = 0; i < l; i++) {
- revnum = PyInt_AsLong(PyList_GET_ITEM(roots, i));
+ revnum = PyLong_AsLong(PyList_GET_ITEM(roots, i));
if (revnum == -1 && PyErr_Occurred())
goto bail;
/* If root is out of range, e.g. wdir(), it must be unreachable
@@ -966,7 +982,7 @@
/* Populate tovisit with all the heads */
l = PyList_GET_SIZE(heads);
for (i = 0; i < l; i++) {
- revnum = PyInt_AsLong(PyList_GET_ITEM(heads, i));
+ revnum = PyLong_AsLong(PyList_GET_ITEM(heads, i));
if (revnum == -1 && PyErr_Occurred())
goto bail;
if (revnum + 1 < 0 || revnum + 1 >= len + 1) {
@@ -986,7 +1002,7 @@
revnum = tovisit[k++];
if (revstates[revnum + 1] & RS_ROOT) {
revstates[revnum + 1] |= RS_REACHABLE;
- val = PyInt_FromLong(revnum);
+ val = PyLong_FromLong(revnum);
if (val == NULL)
goto bail;
r = PyList_Append(reachable, val);
@@ -1031,7 +1047,7 @@
RS_REACHABLE) &&
!(revstates[i + 1] & RS_REACHABLE)) {
revstates[i + 1] |= RS_REACHABLE;
- val = PyInt_FromSsize_t(i);
+ val = PyLong_FromSsize_t(i);
if (val == NULL)
goto bail;
r = PyList_Append(reachable, val);
@@ -1116,7 +1132,7 @@
}
for (i = 0; i < numphases; ++i) {
- PyObject *pyphase = PyInt_FromLong(trackedphases[i]);
+ PyObject *pyphase = PyLong_FromLong(trackedphases[i]);
PyObject *phaseroots = NULL;
if (pyphase == NULL)
goto release;
@@ -1175,7 +1191,7 @@
"bad phase number in internal list");
goto release;
}
- pyrev = PyInt_FromLong(rev);
+ pyrev = PyLong_FromLong(rev);
if (pyrev == NULL)
goto release;
if (PySet_Add(pyphase, pyrev) == -1) {
@@ -1189,7 +1205,7 @@
if (phasesetsdict == NULL)
goto release;
for (i = 0; i < numphases; ++i) {
- PyObject *pyphase = PyInt_FromLong(trackedphases[i]);
+ PyObject *pyphase = PyLong_FromLong(trackedphases[i]);
if (pyphase == NULL)
goto release;
if (PyDict_SetItem(phasesetsdict, pyphase, phasesets[i]) ==
@@ -1247,7 +1263,7 @@
if (heads == NULL)
goto bail;
if (len == 0) {
- PyObject *nullid = PyInt_FromLong(-1);
+ PyObject *nullid = PyLong_FromLong(-1);
if (nullid == NULL || PyList_Append(heads, nullid) == -1) {
Py_XDECREF(nullid);
goto bail;
@@ -1296,7 +1312,7 @@
if (nothead[i])
continue;
- head = PyInt_FromSsize_t(i);
+ head = PyLong_FromSsize_t(i);
if (head == NULL || PyList_Append(heads, head) == -1) {
Py_XDECREF(head);
goto bail;
@@ -1442,7 +1458,7 @@
assert(PyErr_Occurred());
goto bail;
}
- key = PyInt_FromSsize_t(base);
+ key = PyLong_FromSsize_t(base);
allvalues = PyDict_GetItem(cache, key);
if (allvalues == NULL && PyErr_Occurred()) {
goto bail;
@@ -1459,7 +1475,7 @@
goto bail;
}
}
- value = PyInt_FromSsize_t(rev);
+ value = PyLong_FromSsize_t(rev);
if (PyList_Append(allvalues, value)) {
goto bail;
}
@@ -1486,8 +1502,8 @@
return NULL;
}
- if (PyInt_Check(stoparg)) {
- stoprev = (int)PyInt_AsLong(stoparg);
+ if (PyLong_Check(stoparg)) {
+ stoprev = (int)PyLong_AsLong(stoparg);
if (stoprev == -1 && PyErr_Occurred()) {
return NULL;
}
@@ -1521,7 +1537,7 @@
iterrev = rev;
while (iterrev != baserev && iterrev != stoprev) {
- PyObject *value = PyInt_FromLong(iterrev);
+ PyObject *value = PyLong_FromLong(iterrev);
if (value == NULL) {
goto bail;
}
@@ -1560,7 +1576,7 @@
if (iterrev == stoprev) {
stopped = 1;
} else {
- PyObject *value = PyInt_FromLong(iterrev);
+ PyObject *value = PyLong_FromLong(iterrev);
if (value == NULL) {
goto bail;
}
@@ -1712,7 +1728,8 @@
goto bail;
}
for (i = 0; i < num_revs; i++) {
- Py_ssize_t revnum = PyInt_AsLong(PyList_GET_ITEM(list_revs, i));
+ Py_ssize_t revnum =
+ PyLong_AsLong(PyList_GET_ITEM(list_revs, i));
if (revnum == -1 && PyErr_Occurred()) {
goto bail;
}
@@ -2118,7 +2135,7 @@
raise_revlog_error();
return NULL;
}
- return PyInt_FromLong(length);
+ return PyLong_FromLong(length);
}
static void nt_dealloc(nodetree *self)
@@ -2266,7 +2283,7 @@
char *node;
int rev;
- if (PyInt_Check(value)) {
+ if (PyLong_Check(value)) {
long idx;
if (!pylong_to_long(value, &idx)) {
return NULL;
@@ -2278,7 +2295,7 @@
return NULL;
rev = index_find_node(self, node);
if (rev >= -1)
- return PyInt_FromLong(rev);
+ return PyLong_FromLong(rev);
if (rev == -2)
raise_revlog_error();
return NULL;
@@ -2310,7 +2327,7 @@
char *node;
int rev, i;
- if (!PyArg_ParseTuple(args, PY23("s#", "y#"), &node, &nodelen))
+ if (!PyArg_ParseTuple(args, "y#", &node, &nodelen))
return NULL;
if (nodelen < 1) {
@@ -2377,7 +2394,7 @@
raise_revlog_error();
return NULL;
}
- return PyInt_FromLong(length);
+ return PyLong_FromLong(length);
}
static PyObject *index_m_get(indexObject *self, PyObject *args)
@@ -2395,14 +2412,14 @@
return NULL;
if (rev == -2)
Py_RETURN_NONE;
- return PyInt_FromLong(rev);
+ return PyLong_FromLong(rev);
}
static int index_contains(indexObject *self, PyObject *value)
{
char *node;
- if (PyInt_Check(value)) {
+ if (PyLong_Check(value)) {
long rev;
if (!pylong_to_long(value, &rev)) {
return -1;
@@ -2440,7 +2457,7 @@
return NULL;
rev = index_find_node(self, node);
if (rev >= -1)
- return PyInt_FromLong(rev);
+ return PyLong_FromLong(rev);
if (rev == -2)
raise_revlog_error();
return NULL;
@@ -2493,7 +2510,7 @@
if (sv < poison) {
interesting -= 1;
if (sv == allseen) {
- PyObject *obj = PyInt_FromLong(v);
+ PyObject *obj = PyLong_FromLong(v);
if (obj == NULL)
goto bail;
if (PyList_Append(gca, obj) == -1) {
@@ -2561,7 +2578,7 @@
}
for (i = 0; i < revcount; i++) {
- int n = (int)PyInt_AsLong(PyList_GET_ITEM(revs, i));
+ int n = (int)PyLong_AsLong(PyList_GET_ITEM(revs, i));
if (n > maxrev)
maxrev = n;
}
@@ -2586,7 +2603,7 @@
goto bail;
for (i = 0; i < revcount; i++) {
- int n = (int)PyInt_AsLong(PyList_GET_ITEM(revs, i));
+ int n = (int)PyLong_AsLong(PyList_GET_ITEM(revs, i));
long b = 1l << i;
depth[n] = 1;
seen[n] = b;
@@ -2716,13 +2733,13 @@
bitmask x;
long val;
- if (!PyInt_Check(obj)) {
+ if (!PyLong_Check(obj)) {
PyErr_SetString(PyExc_TypeError,
"arguments must all be ints");
Py_DECREF(obj);
goto bail;
}
- val = PyInt_AsLong(obj);
+ val = PyLong_AsLong(obj);
Py_DECREF(obj);
if (val == -1) {
ret = PyList_New(0);
@@ -2763,7 +2780,7 @@
ret = PyList_New(1);
if (ret == NULL)
goto bail;
- obj = PyInt_FromLong(revs[0]);
+ obj = PyLong_FromLong(revs[0]);
if (obj == NULL)
goto bail;
PyList_SET_ITEM(ret, 0, obj);
@@ -2834,14 +2851,8 @@
Py_ssize_t length = index_length(self) + 1;
int ret = 0;
-/* Argument changed from PySliceObject* to PyObject* in Python 3. */
-#ifdef IS_PY3K
if (PySlice_GetIndicesEx(item, length, &start, &stop, &step,
&slicelength) < 0)
-#else
- if (PySlice_GetIndicesEx((PySliceObject *)item, length, &start, &stop,
- &step, &slicelength) < 0)
-#endif
return -1;
if (slicelength <= 0)
@@ -2925,7 +2936,7 @@
if (value == NULL)
return self->ntinitialized ? nt_delete_node(&self->nt, node)
: 0;
- rev = PyInt_AsLong(value);
+ rev = PyLong_AsLong(value);
if (rev > INT_MAX || rev < 0) {
if (!PyErr_Occurred())
PyErr_SetString(PyExc_ValueError, "rev out of range");
@@ -3027,10 +3038,9 @@
self->entry_size = cl2_entry_size;
}
- self->nullentry =
- Py_BuildValue(PY23("iiiiiiis#iiBBi", "iiiiiiiy#iiBBi"), 0, 0, 0, -1,
- -1, -1, -1, nullid, self->nodelen, 0, 0,
- comp_mode_inline, comp_mode_inline, rank_unknown);
+ self->nullentry = Py_BuildValue(
+ "iiiiiiiy#iiBBi", 0, 0, 0, -1, -1, -1, -1, nullid, self->nodelen, 0,
+ 0, comp_mode_inline, comp_mode_inline, rank_unknown);
if (!self->nullentry)
return -1;
@@ -3266,10 +3276,7 @@
static Revlog_CAPI CAPI = {
/* increment the abi_version field upon each change in the Revlog_CAPI
struct or in the ABI of the listed functions */
- 2,
- index_length,
- index_node,
- HgRevlogIndex_GetParents,
+ 3, index_length, index_node, index_fast_rank, HgRevlogIndex_GetParents,
};
void revlog_module_init(PyObject *mod)
--- a/mercurial/cext/util.h Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cext/util.h Fri Mar 25 11:33:12 2022 -0400
@@ -10,17 +10,6 @@
#include "compat.h"
-#if PY_MAJOR_VERSION >= 3
-#define IS_PY3K
-#endif
-
-/* helper to switch things like string literal depending on Python version */
-#ifdef IS_PY3K
-#define PY23(py2, py3) py3
-#else
-#define PY23(py2, py3) py2
-#endif
-
/* clang-format off */
typedef struct {
PyObject_HEAD
--- a/mercurial/cffi/bdiff.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cffi/bdiff.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import struct
--- a/mercurial/cffi/bdiffbuild.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cffi/bdiffbuild.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import cffi
import os
--- a/mercurial/cffi/mpatch.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cffi/mpatch.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from ..pure.mpatch import *
from ..pure.mpatch import mpatchError # silence pyflakes
--- a/mercurial/cffi/mpatchbuild.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cffi/mpatchbuild.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import cffi
import os
--- a/mercurial/cffi/osutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cffi/osutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
import stat as statmod
@@ -34,7 +33,7 @@
attrkinds[lib.VFIFO] = statmod.S_IFIFO
attrkinds[lib.VSOCK] = statmod.S_IFSOCK
- class stat_res(object):
+ class stat_res:
def __init__(self, st_mode, st_mtime, st_size):
self.st_mode = st_mode
self.st_mtime = st_mtime
--- a/mercurial/cffi/osutilbuild.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cffi/osutilbuild.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import cffi
ffi = cffi.FFI()
--- a/mercurial/changegroup.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/changegroup.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
import struct
@@ -106,7 +105,7 @@
os.unlink(cleanup)
-class cg1unpacker(object):
+class cg1unpacker:
"""Unpacker for cg1 changegroup streams.
A changegroup unpacker handles the framing of the revision data in
@@ -425,7 +424,7 @@
mfnode = cl.changelogrevision(cset).manifest
mfest = ml[mfnode].readdelta()
# store file nodes we must see
- for f, n in pycompat.iteritems(mfest):
+ for f, n in mfest.items():
needfiles.setdefault(f, set()).add(n)
on_filelog_rev = None
@@ -692,7 +691,7 @@
)
-class headerlessfixup(object):
+class headerlessfixup:
def __init__(self, fh, h):
self._h = h
self._fh = fh
@@ -1004,7 +1003,7 @@
progress.complete()
-class cgpacker(object):
+class cgpacker:
def __init__(
self,
repo,
@@ -1967,7 +1966,7 @@
del needfiles[f]
progress.complete()
- for f, needs in pycompat.iteritems(needfiles):
+ for f, needs in needfiles.items():
fl = repo.file(f)
for n in needs:
try:
--- a/mercurial/changelog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/changelog.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from .node import (
@@ -92,7 +91,7 @@
return b'\n'.join([l.rstrip() for l in desc.splitlines()]).strip(b'\n')
-class appender(object):
+class appender:
"""the changelog index must be updated last on disk, so we use this class
to delay writes to it"""
@@ -162,7 +161,7 @@
return self.fp.__exit__(*args)
-class _divertopener(object):
+class _divertopener:
def __init__(self, opener, target):
self._opener = opener
self._target = target
@@ -189,7 +188,7 @@
@attr.s
-class _changelogrevision(object):
+class _changelogrevision:
# Extensions might modify _defaultextra, so let the constructor below pass
# it in
extra = attr.ib()
@@ -205,7 +204,7 @@
branchinfo = attr.ib(default=(_defaultextra[b'branch'], False))
-class changelogrevision(object):
+class changelogrevision:
"""Holds results of a parsed changelog revision.
Changelog revisions consist of multiple pieces of data, including
--- a/mercurial/chgserver.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/chgserver.py Fri Mar 25 11:33:12 2022 -0400
@@ -39,7 +39,6 @@
skiphash = False
"""
-from __future__ import absolute_import
import inspect
import os
@@ -135,7 +134,7 @@
ignored = set()
envitems = [
(k, v)
- for k, v in pycompat.iteritems(encoding.environ)
+ for k, v in encoding.environ.items()
if _envre.match(k) and k not in ignored
]
envhash = _hashlist(sorted(envitems))
@@ -197,7 +196,7 @@
return _hashlist(pycompat.maplist(trystat, paths))[:12]
-class hashstate(object):
+class hashstate:
"""a structure storing confighash, mtimehash, paths used for mtimehash"""
def __init__(self, confighash, mtimehash, mtimepaths):
@@ -293,7 +292,7 @@
return (newui, newlui)
-class channeledsystem(object):
+class channeledsystem:
"""Propagate ui.system() request in the following format:
payload length (unsigned int),
@@ -321,7 +320,7 @@
def __call__(self, cmd, environ, cwd=None, type=b'system', cmdtable=None):
args = [type, cmd, util.abspath(cwd or b'.')]
- args.extend(b'%s=%s' % (k, v) for k, v in pycompat.iteritems(environ))
+ args.extend(b'%s=%s' % (k, v) for k, v in environ.items())
data = b'\0'.join(args)
self.out.write(struct.pack(b'>cI', self.channel, len(data)))
self.out.write(data)
@@ -409,22 +408,13 @@
# be unbuffered no matter if it is a tty or not.
if fn == b'ferr':
newfp = fp
- elif pycompat.ispy3:
+ else:
# On Python 3, the standard library doesn't offer line-buffered
# binary streams, so wrap/unwrap it.
if fp.isatty():
newfp = procutil.make_line_buffered(fp)
else:
newfp = procutil.unwrap_line_buffered(fp)
- else:
- # Python 2 uses the I/O streams provided by the C library, so
- # make it line-buffered explicitly. Otherwise the default would
- # be decided on first write(), where fout could be a pager.
- if fp.isatty():
- bufsize = 1 # line buffered
- else:
- bufsize = -1 # system default
- newfp = os.fdopen(fp.fileno(), mode, bufsize)
if newfp is not fp:
setattr(ui, fn, newfp)
setattr(self, cn, newfp)
@@ -448,17 +438,8 @@
nullfd = os.open(os.devnull, os.O_WRONLY)
ui = self.ui
for (ch, fp, fd), (cn, fn, mode) in zip(self._oldios, _iochannels):
- newfp = getattr(ui, fn)
- # On Python 2, newfp and fp may be separate file objects associated
- # with the same fd, so we must close newfp while it's associated
- # with the client. Otherwise the new associated fd would be closed
- # when newfp gets deleted. On Python 3, newfp is just a wrapper
- # around fp even if newfp is not fp, so deleting newfp is safe.
- if not (pycompat.ispy3 or newfp is fp):
- newfp.close()
- # restore original fd: fp is open again
try:
- if (pycompat.ispy3 or newfp is fp) and 'w' in mode:
+ if 'w' in mode:
# Discard buffered data which couldn't be flushed because
# of EPIPE. The data should belong to the current session
# and should never persist.
@@ -636,7 +617,7 @@
return b'%s-%s' % (os.path.join(dirname, basename), hashstr)
-class chgunixservicehandler(object):
+class chgunixservicehandler:
"""Set of operations for chg services"""
pollinterval = 1 # [sec]
--- a/mercurial/cmdutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/cmdutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import copy as copymod
import errno
@@ -627,7 +626,7 @@
# 5. finally restore backed-up files
try:
dirstate = repo.dirstate
- for realname, tmpname in pycompat.iteritems(backups):
+ for realname, tmpname in backups.items():
ui.debug(b'restoring %r to %r\n' % (tmpname, realname))
if dirstate.get_entry(realname).maybe_clean:
@@ -667,7 +666,7 @@
return commit(ui, repo, recordinwlock, pats, opts)
-class dirnode(object):
+class dirnode:
"""
Represent a directory in user working copy with information required for
the purpose of tersing its status.
@@ -833,7 +832,7 @@
@attr.s(frozen=True)
-class morestatus(object):
+class morestatus:
reporoot = attr.ib()
unfinishedop = attr.ib()
unfinishedmsg = attr.ib()
@@ -1344,7 +1343,7 @@
return not pat or pat == b'-'
-class _unclosablefile(object):
+class _unclosablefile:
def __init__(self, fp):
self._fp = fp
--- a/mercurial/color.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/color.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
--- a/mercurial/commands.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/commands.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
@@ -2470,7 +2469,7 @@
)
def debugcommands(ui, cmd=b'', *args):
"""list all available commands and options"""
- for cmd, vals in sorted(pycompat.iteritems(table)):
+ for cmd, vals in sorted(table.items()):
cmd = cmd.split(b'|')[0]
opts = b', '.join([i[1] for i in vals[1]])
ui.write(b'%s: %s\n' % (cmd, opts))
@@ -3911,9 +3910,7 @@
hexremoterev = hex(remoterev)
bms = [
bm
- for bm, bmr in pycompat.iteritems(
- peer.listkeys(b'bookmarks')
- )
+ for bm, bmr in peer.listkeys(b'bookmarks').items()
if bmr == hexremoterev
]
@@ -7090,7 +7087,7 @@
c = repo.dirstate.copies()
copied, renamed = [], []
- for d, s in pycompat.iteritems(c):
+ for d, s in c.items():
if s in status.removed:
status.removed.remove(s)
renamed.append(d)
--- a/mercurial/commandserver.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/commandserver.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import gc
@@ -40,7 +39,7 @@
)
-class channeledoutput(object):
+class channeledoutput:
"""
Write data to out in the following format:
@@ -69,7 +68,7 @@
return getattr(self.out, attr)
-class channeledmessage(object):
+class channeledmessage:
"""
Write encoded message and metadata to out in the following format:
@@ -98,7 +97,7 @@
return getattr(self._cout, attr)
-class channeledinput(object):
+class channeledinput:
"""
Read data from in_.
@@ -201,7 +200,7 @@
)
-class server(object):
+class server:
"""
Listens for commands on fin, runs them and writes the output on a channel
based stream to fout.
@@ -451,7 +450,7 @@
u.setlogger(b'cmdserver', logger)
-class pipeservice(object):
+class pipeservice:
def __init__(self, ui, repo, opts):
self.ui = ui
self.repo = repo
@@ -526,7 +525,7 @@
raise
-class unixservicehandler(object):
+class unixservicehandler:
"""Set of pluggable operations for unix-mode services
Almost all methods except for createcmdserver() are called in the main
@@ -560,7 +559,7 @@
return server(self.ui, repo, fin, fout, prereposetups)
-class unixforkingservice(object):
+class unixforkingservice:
"""
Listens on unix domain socket and forks server per connection
"""
--- a/mercurial/commit.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/commit.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
--- a/mercurial/config.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/config.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
@@ -15,12 +14,11 @@
from . import (
encoding,
error,
- pycompat,
util,
)
-class config(object):
+class config:
def __init__(self, data=None):
self._current_source_level = 0
self._data = {}
@@ -111,20 +109,19 @@
return sorted(self._data.keys())
def items(self, section):
- items = pycompat.iteritems(self._data.get(section, {}))
+ items = self._data.get(section, {}).items()
return [(k, v[0]) for (k, v) in items]
def set(self, section, item, value, source=b""):
- if pycompat.ispy3:
- assert not isinstance(
- section, str
- ), b'config section may not be unicode strings on Python 3'
- assert not isinstance(
- item, str
- ), b'config item may not be unicode strings on Python 3'
- assert not isinstance(
- value, str
- ), b'config values may not be unicode strings on Python 3'
+ assert not isinstance(
+ section, str
+ ), b'config section may not be unicode strings on Python 3'
+ assert not isinstance(
+ item, str
+ ), b'config item may not be unicode strings on Python 3'
+ assert not isinstance(
+ value, str
+ ), b'config values may not be unicode strings on Python 3'
if section not in self:
self._data[section] = util.cowsortdict()
else:
--- a/mercurial/configitems.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/configitems.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import functools
import re
@@ -30,7 +29,7 @@
knownitems.update(items)
-class configitem(object):
+class configitem:
"""represent a known config item
:section: the official config section where to find this item,
@@ -1571,6 +1570,45 @@
default=False,
)
coreconfigitem(
+ b'partial-merge-tools',
+ b'.*',
+ default=None,
+ generic=True,
+ experimental=True,
+)
+coreconfigitem(
+ b'partial-merge-tools',
+ br'.*\.patterns',
+ default=dynamicdefault,
+ generic=True,
+ priority=-1,
+ experimental=True,
+)
+coreconfigitem(
+ b'partial-merge-tools',
+ br'.*\.executable$',
+ default=dynamicdefault,
+ generic=True,
+ priority=-1,
+ experimental=True,
+)
+coreconfigitem(
+ b'partial-merge-tools',
+ br'.*\.order',
+ default=0,
+ generic=True,
+ priority=-1,
+ experimental=True,
+)
+coreconfigitem(
+ b'partial-merge-tools',
+ br'.*\.args',
+ default=b"$local $base $other",
+ generic=True,
+ priority=-1,
+ experimental=True,
+)
+coreconfigitem(
b'merge-tools',
b'.*',
default=None,
--- a/mercurial/context.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/context.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import filecmp
@@ -52,7 +51,7 @@
propertycache = util.propertycache
-class basectx(object):
+class basectx:
"""A basectx object represents the common logic for its children:
changectx: read-only context that is already present in the repo,
workingctx: a context that represents the working directory and can
@@ -124,7 +123,7 @@
deleted, unknown, ignored = s.deleted, s.unknown, s.ignored
deletedset = set(deleted)
d = mf1.diff(mf2, match=match, clean=listclean)
- for fn, value in pycompat.iteritems(d):
+ for fn, value in d.items():
if fn in deletedset:
continue
if value is None:
@@ -797,7 +796,7 @@
return self.walk(match)
-class basefilectx(object):
+class basefilectx:
"""A filecontext object represents the common logic for its children:
filectx: read-only access to a filerevision that is already present
in the repo,
@@ -3105,7 +3104,7 @@
return scmutil.status(modified, added, removed, [], [], [], [])
-class arbitraryfilectx(object):
+class arbitraryfilectx:
"""Allows you to use filectx-like functions on a file in an arbitrary
location on disk, possibly not in the working directory.
"""
--- a/mercurial/copies.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/copies.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import os
@@ -18,7 +17,6 @@
match as matchmod,
pathutil,
policy,
- pycompat,
util,
)
@@ -69,7 +67,7 @@
def _chain(prefix, suffix):
"""chain two sets of copies 'prefix' and 'suffix'"""
result = prefix.copy()
- for key, value in pycompat.iteritems(suffix):
+ for key, value in suffix.items():
result[key] = prefix.get(value, value)
return result
@@ -409,7 +407,7 @@
if childcopies:
newcopies = copies.copy()
- for dest, source in pycompat.iteritems(childcopies):
+ for dest, source in childcopies.items():
prev = copies.get(source)
if prev is not None and prev[1] is not None:
source = prev[1]
@@ -624,7 +622,7 @@
newcopies = copies
if childcopies:
newcopies = copies.copy()
- for dest, source in pycompat.iteritems(childcopies):
+ for dest, source in childcopies.items():
prev = copies.get(source)
if prev is not None and prev[1] is not None:
source = prev[1]
@@ -722,7 +720,7 @@
# can still exist (e.g. hg cp a b; hg mv a c). In those cases we
# arbitrarily pick one of the renames.
r = {}
- for k, v in sorted(pycompat.iteritems(copies)):
+ for k, v in sorted(copies.items()):
if match and not match(v):
continue
# remove copies
@@ -889,7 +887,7 @@
copy[dst] = src
-class branch_copies(object):
+class branch_copies:
"""Information about copies made on one side of a merge/graft.
"copy" is a mapping from destination name -> source name,
@@ -1081,7 +1079,7 @@
# examine each file copy for a potential directory move, which is
# when all the files in a directory are moved to a new directory
- for dst, src in pycompat.iteritems(fullcopy):
+ for dst, src in fullcopy.items():
dsrc, ddst = pathutil.dirname(src), pathutil.dirname(dst)
if dsrc in invalid:
# already seen to be uninteresting
@@ -1104,7 +1102,7 @@
if not dirmove:
return {}, {}
- dirmove = {k + b"/": v + b"/" for k, v in pycompat.iteritems(dirmove)}
+ dirmove = {k + b"/": v + b"/" for k, v in dirmove.items()}
for d in dirmove:
repo.ui.debug(
@@ -1187,7 +1185,7 @@
copies2 = {}
cp = _forwardcopies(base, c2)
- for dst, src in pycompat.iteritems(cp):
+ for dst, src in cp.items():
if src in m1:
copies2[dst] = src
@@ -1305,5 +1303,5 @@
for dest, __ in list(new_copies.items()):
if dest in parent:
del new_copies[dest]
- for dst, src in pycompat.iteritems(new_copies):
+ for dst, src in new_copies.items():
wctx[dst].markcopied(src)
--- a/mercurial/crecord.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/crecord.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
# This code is based on the Mark Edgington's crecord extension.
# (Itself based on Bryan O'Sullivan's record extension.)
-from __future__ import absolute_import
import os
import re
@@ -83,7 +82,7 @@
return curses and ui.interface(b"chunkselector") == b"curses"
-class patchnode(object):
+class patchnode:
"""abstract class for patch graph nodes
(i.e. patchroot, header, hunk, hunkline)
"""
@@ -602,7 +601,7 @@
"""
chunkselector = curseschunkselector(headerlist, ui, operation)
- class dummystdscr(object):
+ class dummystdscr:
def clear(self):
pass
@@ -629,7 +628,7 @@
}
-class curseschunkselector(object):
+class curseschunkselector:
def __init__(self, headerlist, ui, operation=None):
# put the headers into a patch object
self.headerlist = patch(headerlist)
--- a/mercurial/dagop.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dagop.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import heapq
@@ -272,7 +271,7 @@
break
-class subsetparentswalker(object):
+class subsetparentswalker:
r"""Scan adjacent ancestors in the graph given by the subset
This computes parent-child relations in the sub graph filtered by
@@ -648,7 +647,7 @@
@attr.s(slots=True, frozen=True)
-class annotateline(object):
+class annotateline:
fctx = attr.ib()
lineno = attr.ib()
# Whether this annotation was the result of a skip-annotate.
@@ -657,7 +656,7 @@
@attr.s(slots=True, frozen=True)
-class _annotatedfile(object):
+class _annotatedfile:
# list indexed by lineno - 1
fctxs = attr.ib()
linenos = attr.ib()
--- a/mercurial/dagparser.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dagparser.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
import string
--- a/mercurial/debugcommands.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/debugcommands.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import binascii
import codecs
@@ -493,7 +492,7 @@
b2caps = bundle2.bundle2caps(peer)
if b2caps:
ui.writenoi18n(b'Bundle2 capabilities:\n')
- for key, values in sorted(pycompat.iteritems(b2caps)):
+ for key, values in sorted(b2caps.items()):
ui.write(b' %s\n' % key)
for v in values:
ui.write(b' %s\n' % v)
@@ -1021,7 +1020,7 @@
b'',
b'remote-as-revs',
b"",
- b'use local as remote, with only these these revisions',
+ b'use local as remote, with only these revisions',
),
]
+ cmdutil.remoteopts
@@ -2385,11 +2384,11 @@
fm_files.end()
fm_extras = fm.nested(b'extras')
- for f, d in sorted(pycompat.iteritems(ms.allextras())):
+ for f, d in sorted(ms.allextras().items()):
if f in ms:
# If file is in mergestate, we have already processed it's extras
continue
- for k, v in pycompat.iteritems(d):
+ for k, v in d.items():
fm_extras.startitem()
fm_extras.data(file=f)
fm_extras.data(key=k)
@@ -2406,7 +2405,7 @@
names = set()
# since we previously only listed open branches, we will handle that
# specially (after this for loop)
- for name, ns in pycompat.iteritems(repo.names):
+ for name, ns in repo.names.items():
if name != b'branches':
names.update(ns.listnames(repo))
names.update(
@@ -2700,7 +2699,7 @@
fullpaths = opts['full']
files, dirs = set(), set()
adddir, addfile = dirs.add, files.add
- for f, st in pycompat.iteritems(dirstate):
+ for f, st in dirstate.items():
if f.startswith(spec) and st.state in acceptable:
if fixpaths:
f = f.replace(b'/', pycompat.ossep)
@@ -2889,7 +2888,7 @@
ui.status(pycompat.bytestr(r) + b'\n')
return not r
else:
- for k, v in sorted(pycompat.iteritems(target.listkeys(namespace))):
+ for k, v in sorted(target.listkeys(namespace).items()):
ui.write(
b"%s\t%s\n"
% (stringutil.escapestr(k), stringutil.escapestr(v))
@@ -4271,7 +4270,7 @@
for opt in cmdutil.remoteopts:
del opts[opt[1]]
args = {}
- for k, v in pycompat.iteritems(opts):
+ for k, v in opts.items():
if v:
args[k] = v
args = pycompat.strkwargs(args)
--- a/mercurial/destutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/destutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from . import bookmarks, error, obsutil, scmutil, stack
--- a/mercurial/diffhelper.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/diffhelper.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
--- a/mercurial/diffutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/diffutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
--- a/mercurial/dirstate.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dirstate.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import contextlib
@@ -91,7 +90,7 @@
@interfaceutil.implementer(intdirstate.idirstate)
-class dirstate(object):
+class dirstate:
def __init__(
self,
opener,
@@ -343,7 +342,7 @@
return iter(sorted(self._map))
def items(self):
- return pycompat.iteritems(self._map)
+ return self._map.items()
iteritems = items
@@ -771,9 +770,7 @@
def _writedirstate(self, tr, st):
# notify callbacks about parents change
if self._origpl is not None and self._origpl != self._pl:
- for c, callback in sorted(
- pycompat.iteritems(self._plchangecallbacks)
- ):
+ for c, callback in sorted(self._plchangecallbacks.items()):
callback(self, self._origpl, self._pl)
self._origpl = None
self._map.write(tr, st)
@@ -936,7 +933,7 @@
if match.isexact() and self._checkcase:
normed = {}
- for f, st in pycompat.iteritems(results):
+ for f, st in results.items():
if st is None:
continue
@@ -949,7 +946,7 @@
paths.add(f)
- for norm, paths in pycompat.iteritems(normed):
+ for norm, paths in normed.items():
if len(paths) > 1:
for path in paths:
folded = self._discoverpath(
@@ -1311,9 +1308,9 @@
# - match.traversedir does something, because match.traversedir should
# be called for every dir in the working dir
full = listclean or match.traversedir is not None
- for fn, st in pycompat.iteritems(
- self.walk(match, subrepos, listunknown, listignored, full=full)
- ):
+ for fn, st in self.walk(
+ match, subrepos, listunknown, listignored, full=full
+ ).items():
if not dcontains(fn):
if (listignored or mexact(fn)) and dirignore(fn):
if listignored:
--- a/mercurial/dirstateguard.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dirstateguard.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
from .i18n import _
--- a/mercurial/dirstatemap.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dirstatemap.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
@@ -13,7 +12,6 @@
error,
pathutil,
policy,
- pycompat,
txnutil,
util,
)
@@ -36,7 +34,7 @@
rangemask = 0x7FFFFFFF
-class _dirstatemapcommon(object):
+class _dirstatemapcommon:
"""
Methods that are identical for both implementations of the dirstatemap
class, with and without Rust extensions enabled.
@@ -355,7 +353,7 @@
util.clearcachedproperty(self, b"dirfoldmap")
def items(self):
- return pycompat.iteritems(self._map)
+ return self._map.items()
# forward for python2,3 compat
iteritems = items
@@ -379,7 +377,7 @@
self._dirtyparents = True
copies = {}
if fold_p2:
- for f, s in pycompat.iteritems(self._map):
+ for f, s in self._map.items():
# Discard "merged" markers when moving away from a merge state
if s.p2_info:
source = self.copymap.pop(f, None)
@@ -502,7 +500,7 @@
f = {}
normcase = util.normcase
- for name, s in pycompat.iteritems(self._map):
+ for name, s in self._map.items():
if not s.removed:
f[normcase(name)] = name
f[b'.'] = b'.' # prevents useless util.fspath() invocation
--- a/mercurial/dirstateutils/docket.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dirstateutils/docket.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import struct
@@ -29,7 +28,7 @@
)
-class DirstateDocket(object):
+class DirstateDocket:
data_filename_pattern = b'dirstate.%s'
def __init__(self, parents, data_size, tree_metadata, uuid):
--- a/mercurial/dirstateutils/timestamp.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dirstateutils/timestamp.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import functools
import os
--- a/mercurial/dirstateutils/v2.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dirstateutils/v2.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import struct
@@ -126,7 +125,7 @@
@attr.s
-class Node(object):
+class Node:
path = attr.ib()
entry = attr.ib()
parent = attr.ib(default=None)
--- a/mercurial/discovery.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/discovery.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import functools
@@ -74,7 +73,7 @@
return (list(common), anyinc, heads or list(srvheads))
-class outgoing(object):
+class outgoing:
"""Represents the result of a findcommonoutgoing() call.
Members:
@@ -238,7 +237,7 @@
knownnode = cl.hasnode # do not use nodemap until it is filtered
# A. register remote heads of branches which are in outgoing set
- for branch, heads in pycompat.iteritems(remotemap):
+ for branch, heads in remotemap.items():
# don't add head info about branches which we don't have locally
if branch not in branches:
continue
@@ -262,14 +261,14 @@
repo,
(
(branch, heads[1])
- for branch, heads in pycompat.iteritems(headssum)
+ for branch, heads in headssum.items()
if heads[0] is not None
),
)
newmap.update(repo, (ctx.rev() for ctx in missingctx))
- for branch, newheads in pycompat.iteritems(newmap):
+ for branch, newheads in newmap.items():
headssum[branch][1][:] = newheads
- for branch, items in pycompat.iteritems(headssum):
+ for branch, items in headssum.items():
for l in items:
if l is not None:
l.sort()
@@ -380,9 +379,7 @@
headssum = _oldheadssummary(repo, remoteheads, outgoing, inc)
pushop.pushbranchmap = headssum
newbranches = [
- branch
- for branch, heads in pycompat.iteritems(headssum)
- if heads[0] is None
+ branch for branch, heads in headssum.items() if heads[0] is None
]
# 1. Check for new branches on the remote.
if newbranches and not newbranch: # new branch requires --new-branch
--- a/mercurial/dispatch.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/dispatch.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import errno
import getopt
@@ -54,7 +53,7 @@
)
-class request(object):
+class request:
def __init__(
self,
args,
@@ -150,93 +149,76 @@
sys.exit(status & 255)
-if pycompat.ispy3:
-
- def initstdio():
- # stdio streams on Python 3 are io.TextIOWrapper instances proxying another
- # buffer. These streams will normalize \n to \r\n by default. Mercurial's
- # preferred mechanism for writing output (ui.write()) uses io.BufferedWriter
- # instances, which write to the underlying stdio file descriptor in binary
- # mode. ui.write() uses \n for line endings and no line ending normalization
- # is attempted through this interface. This "just works," even if the system
- # preferred line ending is not \n.
- #
- # But some parts of Mercurial (e.g. hooks) can still send data to sys.stdout
- # and sys.stderr. They will inherit the line ending normalization settings,
- # potentially causing e.g. \r\n to be emitted. Since emitting \n should
- # "just work," here we change the sys.* streams to disable line ending
- # normalization, ensuring compatibility with our ui type.
-
- if sys.stdout is not None:
- # write_through is new in Python 3.7.
- kwargs = {
- "newline": "\n",
- "line_buffering": sys.stdout.line_buffering,
- }
- if util.safehasattr(sys.stdout, "write_through"):
- # pytype: disable=attribute-error
- kwargs["write_through"] = sys.stdout.write_through
- # pytype: enable=attribute-error
- sys.stdout = io.TextIOWrapper(
- sys.stdout.buffer,
- sys.stdout.encoding,
- sys.stdout.errors,
- **kwargs
- )
+def initstdio():
+ # stdio streams on Python 3 are io.TextIOWrapper instances proxying another
+ # buffer. These streams will normalize \n to \r\n by default. Mercurial's
+ # preferred mechanism for writing output (ui.write()) uses io.BufferedWriter
+ # instances, which write to the underlying stdio file descriptor in binary
+ # mode. ui.write() uses \n for line endings and no line ending normalization
+ # is attempted through this interface. This "just works," even if the system
+ # preferred line ending is not \n.
+ #
+ # But some parts of Mercurial (e.g. hooks) can still send data to sys.stdout
+ # and sys.stderr. They will inherit the line ending normalization settings,
+ # potentially causing e.g. \r\n to be emitted. Since emitting \n should
+ # "just work," here we change the sys.* streams to disable line ending
+ # normalization, ensuring compatibility with our ui type.
- if sys.stderr is not None:
- kwargs = {
- "newline": "\n",
- "line_buffering": sys.stderr.line_buffering,
- }
- if util.safehasattr(sys.stderr, "write_through"):
- # pytype: disable=attribute-error
- kwargs["write_through"] = sys.stderr.write_through
- # pytype: enable=attribute-error
- sys.stderr = io.TextIOWrapper(
- sys.stderr.buffer,
- sys.stderr.encoding,
- sys.stderr.errors,
- **kwargs
- )
+ if sys.stdout is not None:
+ # write_through is new in Python 3.7.
+ kwargs = {
+ "newline": "\n",
+ "line_buffering": sys.stdout.line_buffering,
+ }
+ if util.safehasattr(sys.stdout, "write_through"):
+ # pytype: disable=attribute-error
+ kwargs["write_through"] = sys.stdout.write_through
+ # pytype: enable=attribute-error
+ sys.stdout = io.TextIOWrapper(
+ sys.stdout.buffer, sys.stdout.encoding, sys.stdout.errors, **kwargs
+ )
- if sys.stdin is not None:
- # No write_through on read-only stream.
- sys.stdin = io.TextIOWrapper(
- sys.stdin.buffer,
- sys.stdin.encoding,
- sys.stdin.errors,
- # None is universal newlines mode.
- newline=None,
- line_buffering=sys.stdin.line_buffering,
- )
+ if sys.stderr is not None:
+ kwargs = {
+ "newline": "\n",
+ "line_buffering": sys.stderr.line_buffering,
+ }
+ if util.safehasattr(sys.stderr, "write_through"):
+ # pytype: disable=attribute-error
+ kwargs["write_through"] = sys.stderr.write_through
+ # pytype: enable=attribute-error
+ sys.stderr = io.TextIOWrapper(
+ sys.stderr.buffer, sys.stderr.encoding, sys.stderr.errors, **kwargs
+ )
- def _silencestdio():
- for fp in (sys.stdout, sys.stderr):
- if fp is None:
- continue
- # Check if the file is okay
- try:
- fp.flush()
- continue
- except IOError:
- pass
- # Otherwise mark it as closed to silence "Exception ignored in"
- # message emitted by the interpreter finalizer.
- try:
- fp.close()
- except IOError:
- pass
+ if sys.stdin is not None:
+ # No write_through on read-only stream.
+ sys.stdin = io.TextIOWrapper(
+ sys.stdin.buffer,
+ sys.stdin.encoding,
+ sys.stdin.errors,
+ # None is universal newlines mode.
+ newline=None,
+ line_buffering=sys.stdin.line_buffering,
+ )
-else:
-
- def initstdio():
- for fp in (sys.stdin, sys.stdout, sys.stderr):
- procutil.setbinary(fp)
-
- def _silencestdio():
- pass
+def _silencestdio():
+ for fp in (sys.stdout, sys.stderr):
+ if fp is None:
+ continue
+ # Check if the file is okay
+ try:
+ fp.flush()
+ continue
+ except IOError:
+ pass
+ # Otherwise mark it as closed to silence "Exception ignored in"
+ # message emitted by the interpreter finalizer.
+ try:
+ fp.close()
+ except IOError:
+ pass
def _formatargs(args):
@@ -575,7 +557,7 @@
return r.sub(lambda x: replacemap[x.group()], cmd)
-class cmdalias(object):
+class cmdalias:
def __init__(self, ui, name, definition, cmdtable, source):
self.name = self.cmd = name
self.cmdname = b''
@@ -590,7 +572,7 @@
try:
aliases, entry = cmdutil.findcmd(self.name, cmdtable)
- for alias, e in pycompat.iteritems(cmdtable):
+ for alias, e in cmdtable.items():
if e is entry:
self.cmd = alias
break
@@ -758,7 +740,7 @@
raise
-class lazyaliasentry(object):
+class lazyaliasentry:
"""like a typical command entry (func, opts, help), but is lazy"""
def __init__(self, ui, name, definition, cmdtable, source):
--- a/mercurial/encoding.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/encoding.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import locale
import os
@@ -47,8 +46,7 @@
_sysstr = pycompat.sysstr
-if pycompat.ispy3:
- unichr = chr
+unichr = chr
# These unicode characters are ignored by HFS+ (Apple Technote 1150,
# "Unicode Subtleties"), so we need to ignore them in some places for
@@ -79,10 +77,8 @@
# encoding.environ is provided read-only, which may not be used to modify
# the process environment
-_nativeenviron = not pycompat.ispy3 or os.supports_bytes_environ
-if not pycompat.ispy3:
- environ = os.environ # re-exports
-elif _nativeenviron:
+_nativeenviron = os.supports_bytes_environ
+if _nativeenviron:
environ = os.environb # re-exports
else:
# preferred encoding isn't known yet; use utf-8 to avoid unicode error
@@ -99,7 +95,7 @@
# cp65001 is a Windows variant of utf-8, which isn't supported on Python 2.
# No idea if it should be rewritten to the canonical name 'utf-8' on Python 3.
# https://bugs.python.org/issue13216
-if pycompat.iswindows and not pycompat.ispy3:
+if pycompat.iswindows:
_encodingrewrites[b'cp65001'] = b'utf-8'
try:
@@ -271,21 +267,9 @@
# converter functions between native str and byte string. use these if the
# character encoding is not aware (e.g. exception message) or is known to
# be locale dependent (e.g. date formatting.)
-if pycompat.ispy3:
- strtolocal = unitolocal
- strfromlocal = unifromlocal
- strmethod = unimethod
-else:
-
- def strtolocal(s):
- # type: (str) -> bytes
- return s # pytype: disable=bad-return-type
-
- def strfromlocal(s):
- # type: (bytes) -> str
- return s # pytype: disable=bad-return-type
-
- strmethod = pycompat.identity
+strtolocal = unitolocal
+strfromlocal = unifromlocal
+strmethod = unimethod
def lower(s):
@@ -345,7 +329,7 @@
if not _nativeenviron:
# now encoding and helper functions are available, recreate the environ
# dict to be exported to other modules
- if pycompat.iswindows and pycompat.ispy3:
+ if pycompat.iswindows:
class WindowsEnviron(dict):
"""`os.environ` normalizes environment variables to uppercase on windows"""
@@ -361,36 +345,34 @@
DRIVE_RE = re.compile(b'^[a-z]:')
-if pycompat.ispy3:
- # os.getcwd() on Python 3 returns string, but it has os.getcwdb() which
- # returns bytes.
- if pycompat.iswindows:
- # Python 3 on Windows issues a DeprecationWarning about using the bytes
- # API when os.getcwdb() is called.
- #
- # Additionally, py3.8+ uppercases the drive letter when calling
- # os.path.realpath(), which is used on ``repo.root``. Since those
- # strings are compared in various places as simple strings, also call
- # realpath here. See https://bugs.python.org/issue40368
- #
- # However this is not reliable, so lets explicitly make this drive
- # letter upper case.
- #
- # note: we should consider dropping realpath here since it seems to
- # change the semantic of `getcwd`.
+# os.getcwd() on Python 3 returns string, but it has os.getcwdb() which
+# returns bytes.
+if pycompat.iswindows:
+ # Python 3 on Windows issues a DeprecationWarning about using the bytes
+ # API when os.getcwdb() is called.
+ #
+ # Additionally, py3.8+ uppercases the drive letter when calling
+ # os.path.realpath(), which is used on ``repo.root``. Since those
+ # strings are compared in various places as simple strings, also call
+ # realpath here. See https://bugs.python.org/issue40368
+ #
+ # However this is not reliable, so lets explicitly make this drive
+ # letter upper case.
+ #
+ # note: we should consider dropping realpath here since it seems to
+ # change the semantic of `getcwd`.
- def getcwd():
- cwd = os.getcwd() # re-exports
- cwd = os.path.realpath(cwd)
- cwd = strtolocal(cwd)
- if DRIVE_RE.match(cwd):
- cwd = cwd[0:1].upper() + cwd[1:]
- return cwd
+ def getcwd():
+ cwd = os.getcwd() # re-exports
+ cwd = os.path.realpath(cwd)
+ cwd = strtolocal(cwd)
+ if DRIVE_RE.match(cwd):
+ cwd = cwd[0:1].upper() + cwd[1:]
+ return cwd
- else:
- getcwd = os.getcwdb # re-exports
+
else:
- getcwd = os.getcwd # re-exports
+ getcwd = os.getcwdb # re-exports
# How to treat ambiguous-width characters. Set to 'wide' to treat as wide.
_wide = _sysstr(
@@ -528,7 +510,7 @@
return u + ellipsis
-class normcasespecs(object):
+class normcasespecs:
"""what a platform's normcase does to ASCII strings
This is specified per platform, and should be consistent with what normcase
@@ -601,10 +583,7 @@
# We need to decode/encode U+DCxx codes transparently since invalid UTF-8
# bytes are mapped to that range.
-if pycompat.ispy3:
- _utf8strict = r'surrogatepass'
-else:
- _utf8strict = r'strict'
+_utf8strict = r'surrogatepass'
_utf8len = [0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 3, 4]
--- a/mercurial/error.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/error.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,7 +11,6 @@
imports.
"""
-from __future__ import absolute_import
import difflib
@@ -40,7 +39,7 @@
return b'(%s)' % b', '.join(b"'%s'" % pycompat.bytestr(a) for a in exc.args)
-class Hint(object):
+class Hint:
"""Mix-in to provide a hint of an error
This should come first in the inheritance list to consume a hint and
@@ -69,14 +68,12 @@
def __bytes__(self):
return self.message
- if pycompat.ispy3:
-
- def __str__(self):
- # type: () -> str
- # the output would be unreadable if the message was translated,
- # but do not replace it with encoding.strfromlocal(), which
- # may raise another exception.
- return pycompat.sysstr(self.__bytes__())
+ def __str__(self):
+ # type: () -> str
+ # the output would be unreadable if the message was translated,
+ # but do not replace it with encoding.strfromlocal(), which
+ # may raise another exception.
+ return pycompat.sysstr(self.__bytes__())
def format(self):
# type: () -> bytes
--- a/mercurial/exchange.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/exchange.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import weakref
@@ -223,7 +222,7 @@
return forcebundle1 or not op.remote.capable(b'bundle2')
-class pushoperation(object):
+class pushoperation:
"""A object that represent a single push operation
Its purpose is to carry push related state and very common operations.
@@ -806,7 +805,7 @@
bundler.newpart(b'check:heads', data=iter(pushop.remoteheads))
else:
affected = set()
- for branch, heads in pycompat.iteritems(pushop.pushbranchmap):
+ for branch, heads in pushop.pushbranchmap.items():
remoteheads, newheads, unsyncedheads, discardedheads = heads
if remoteheads is not None:
remote = set(remoteheads)
@@ -855,7 +854,7 @@
checks = {p: [] for p in phases.allphases}
checks[phases.public].extend(pushop.remotephases.publicheads)
checks[phases.draft].extend(pushop.remotephases.draftroots)
- if any(pycompat.itervalues(checks)):
+ if any(checks.values()):
for phase in checks:
checks[phase].sort()
checkdata = phases.binaryencode(checks)
@@ -1117,7 +1116,7 @@
part = bundler.newpart(b'pushvars')
- for key, value in pycompat.iteritems(shellvars):
+ for key, value in shellvars.items():
part.addparam(key, value, mandatory=False)
@@ -1372,7 +1371,7 @@
pushop.bkresult = 1
-class pulloperation(object):
+class pulloperation:
"""A object that represent a single pull operation
It purpose is to carry pull related state and very common operation.
--- a/mercurial/extensions.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/extensions.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import ast
import collections
@@ -74,7 +73,7 @@
try:
mod = _extensions[name]
except KeyError:
- for k, v in pycompat.iteritems(_extensions):
+ for k, v in _extensions.items():
if k.endswith(b'.' + name) or k.endswith(b'/' + name):
mod = v
break
@@ -171,7 +170,7 @@
def _validatecmdtable(ui, cmdtable):
"""Check if extension commands have required attributes"""
- for c, e in pycompat.iteritems(cmdtable):
+ for c, e in cmdtable.items():
f = e[0]
missing = [a for a in _cmdfuncattrs if not util.safehasattr(f, a)]
if not missing:
@@ -579,7 +578,7 @@
'''
assert callable(wrapper)
aliases, entry = cmdutil.findcmd(command, table)
- for alias, e in pycompat.iteritems(table):
+ for alias, e in table.items():
if e is entry:
key = alias
break
@@ -622,7 +621,7 @@
raise AttributeError("type '%s' has no property '%s'" % (cls, propname))
-class wrappedfunction(object):
+class wrappedfunction:
'''context manager for temporarily wrapping a function'''
def __init__(self, container, funcname, wrapper):
@@ -756,7 +755,7 @@
if name in exts or name in _order or name == b'__init__':
continue
exts[name] = path
- for name, path in pycompat.iteritems(_disabledextensions):
+ for name, path in _disabledextensions.items():
# If no path was provided for a disabled extension (e.g. "color=!"),
# don't replace the path we already found by the scan above.
if path:
@@ -818,7 +817,7 @@
return {
name: gettext(desc)
- for name, desc in pycompat.iteritems(__index__.docs)
+ for name, desc in __index__.docs.items()
if name not in _order
}
except (ImportError, AttributeError):
@@ -829,7 +828,7 @@
return {}
exts = {}
- for name, path in pycompat.iteritems(paths):
+ for name, path in paths.items():
doc = _disabledhelp(path)
if doc and name != b'__index__':
exts[name] = doc.splitlines()[0]
@@ -876,7 +875,7 @@
a = node.args[0]
if isinstance(a, ast.Str):
name = pycompat.sysbytes(a.s)
- elif pycompat.ispy3 and isinstance(a, ast.Bytes):
+ elif isinstance(a, ast.Bytes):
name = a.s
else:
continue
@@ -918,7 +917,7 @@
ext = _finddisabledcmd(ui, cmd, cmd, path, strict=strict)
if not ext:
# otherwise, interrogate each extension until there's a match
- for name, path in pycompat.iteritems(paths):
+ for name, path in paths.items():
ext = _finddisabledcmd(ui, cmd, name, path, strict=strict)
if ext:
break
@@ -943,9 +942,7 @@
def notloaded():
'''return short names of extensions that failed to load'''
- return [
- name for name, mod in pycompat.iteritems(_extensions) if mod is None
- ]
+ return [name for name, mod in _extensions.items() if mod is None]
def moduleversion(module):
--- a/mercurial/exthelper.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/exthelper.py Fri Mar 25 11:33:12 2022 -0400
@@ -9,20 +9,18 @@
### Extension helper ###
#####################################################################
-from __future__ import absolute_import
from . import (
commands,
error,
extensions,
- pycompat,
registrar,
)
from hgdemandimport import tracing
-class exthelper(object):
+class exthelper:
"""Helper for modular extension setup
A single helper should be instantiated for each module of an
@@ -115,7 +113,7 @@
self._extcommandwrappers.extend(other._extcommandwrappers)
self._functionwrappers.extend(other._functionwrappers)
self.cmdtable.update(other.cmdtable)
- for section, items in pycompat.iteritems(other.configtable):
+ for section, items in other.configtable.items():
if section in self.configtable:
self.configtable[section].update(items)
else:
--- a/mercurial/fancyopts.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/fancyopts.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import abc
import functools
@@ -205,7 +204,7 @@
return parsedopts, parsedargs
-class customopt(object): # pytype: disable=ignored-metaclass
+class customopt: # pytype: disable=ignored-metaclass
"""Manage defaults and mutations for any type of opt."""
__metaclass__ = abc.ABCMeta
--- a/mercurial/filelog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/filelog.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from .node import nullrev
@@ -25,7 +24,7 @@
@interfaceutil.implementer(repository.ifilestorage)
-class filelog(object):
+class filelog:
def __init__(self, opener, path):
self._revlog = revlog.revlog(
opener,
--- a/mercurial/filemerge.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/filemerge.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import os
@@ -85,7 +84,7 @@
)
-class absentfilectx(object):
+class absentfilectx:
"""Represents a file that's ostensibly in a context but is actually not
present in it.
@@ -1052,6 +1051,7 @@
markerstyle = internalmarkerstyle
if mergetype == fullmerge:
+ _run_partial_resolution_tools(repo, local, other, base)
# conflict markers generated by premerge will use 'detailed'
# settings if either ui.mergemarkers or the tool's mergemarkers
# setting is 'detailed'. This way tools can have basic labels in
@@ -1116,6 +1116,73 @@
backup.remove()
+def _run_partial_resolution_tools(repo, local, other, base):
+ """Runs partial-resolution tools on the three inputs and updates them."""
+ ui = repo.ui
+ # Tuples of (order, name, executable path, args)
+ tools = []
+ seen = set()
+ section = b"partial-merge-tools"
+ for k, v in ui.configitems(section):
+ name = k.split(b'.')[0]
+ if name in seen:
+ continue
+ patterns = ui.configlist(section, b'%s.patterns' % name, [])
+ is_match = True
+ if patterns:
+ m = match.match(repo.root, b'', patterns)
+ is_match = m(local.fctx.path())
+ if is_match:
+ order = ui.configint(section, b'%s.order' % name, 0)
+ executable = ui.config(section, b'%s.executable' % name, name)
+ args = ui.config(section, b'%s.args' % name)
+ tools.append((order, name, executable, args))
+
+ if not tools:
+ return
+ # Sort in configured order (first in tuple)
+ tools.sort()
+
+ files = [
+ (b"local", local.fctx.path(), local.text()),
+ (b"base", base.fctx.path(), base.text()),
+ (b"other", other.fctx.path(), other.text()),
+ ]
+
+ with _maketempfiles(files) as temppaths:
+ localpath, basepath, otherpath = temppaths
+
+ for order, name, executable, args in tools:
+ cmd = procutil.shellquote(executable)
+ replace = {
+ b'local': localpath,
+ b'base': basepath,
+ b'other': otherpath,
+ }
+ args = util.interpolate(
+ br'\$',
+ replace,
+ args,
+ lambda s: procutil.shellquote(util.localpath(s)),
+ )
+
+ cmd = b'%s %s' % (cmd, args)
+ r = ui.system(cmd, cwd=repo.root, blockedtag=b'partial-mergetool')
+ if r:
+ raise error.StateError(
+ b'partial merge tool %s exited with code %d' % (name, r)
+ )
+ local_text = util.readfile(localpath)
+ other_text = util.readfile(otherpath)
+ if local_text == other_text:
+ # No need to run other tools if all conflicts have been resolved
+ break
+
+ local.set_text(local_text)
+ base.set_text(util.readfile(basepath))
+ other.set_text(other_text)
+
+
def _haltmerge():
msg = _(b'merge halted after failed merge (see hg resolve)')
raise error.InterventionRequired(msg)
@@ -1199,7 +1266,7 @@
def loadinternalmerge(ui, extname, registrarobj):
"""Load internal merge tool from specified registrarobj"""
- for name, func in pycompat.iteritems(registrarobj._table):
+ for name, func in registrarobj._table.items():
fullname = b':' + name
internals[fullname] = func
internals[b'internal:' + name] = func
--- a/mercurial/fileset.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/fileset.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import re
@@ -504,7 +503,7 @@
}
-class matchctx(object):
+class matchctx:
def __init__(self, basectx, ctx, cwd, badfn=None):
self._basectx = basectx
self.ctx = ctx
@@ -614,7 +613,7 @@
def loadpredicate(ui, extname, registrarobj):
"""Load fileset predicates from specified registrarobj"""
- for name, func in pycompat.iteritems(registrarobj._table):
+ for name, func in registrarobj._table.items():
symbols[name] = func
--- a/mercurial/filesetlang.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/filesetlang.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from .pycompat import getattr
--- a/mercurial/formatter.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/formatter.py Fri Mar 25 11:33:12 2022 -0400
@@ -105,11 +105,11 @@
baz: foo, bar
"""
-from __future__ import absolute_import, print_function
import contextlib
import itertools
import os
+import pickle
from .i18n import _
from .node import (
@@ -133,8 +133,6 @@
stringutil,
)
-pickle = util.pickle
-
def isprintable(obj):
"""Check if the given object can be directly passed in to formatter's
@@ -143,10 +141,10 @@
Returns False if the object is unsupported or must be pre-processed by
formatdate(), formatdict(), or formatlist().
"""
- return isinstance(obj, (type(None), bool, int, pycompat.long, float, bytes))
+ return isinstance(obj, (type(None), bool, int, int, float, bytes))
-class _nullconverter(object):
+class _nullconverter:
'''convert non-primitive data types to be processed by formatter'''
# set to True if context object should be stored as item
@@ -177,7 +175,7 @@
return list(data)
-class baseformatter(object):
+class baseformatter:
# set to True if the formater output a strict format that does not support
# arbitrary output in the stream.
@@ -295,11 +293,11 @@
def _iteritems(data):
'''iterate key-value pairs in stable order'''
if isinstance(data, dict):
- return sorted(pycompat.iteritems(data))
+ return sorted(data.items())
return data
-class _plainconverter(object):
+class _plainconverter:
'''convert non-primitive data types to text'''
storecontext = False
@@ -454,7 +452,7 @@
self._out.write(b"\n]\n")
-class _templateconverter(object):
+class _templateconverter:
'''convert non-primitive data types to be processed by templater'''
storecontext = True
@@ -543,7 +541,7 @@
@attr.s(frozen=True)
-class templatespec(object):
+class templatespec:
ref = attr.ib()
tmpl = attr.ib()
mapfile = attr.ib()
@@ -560,8 +558,7 @@
def literal_templatespec(tmpl):
- if pycompat.ispy3:
- assert not isinstance(tmpl, str), b'tmpl must not be a str'
+ assert not isinstance(tmpl, str), b'tmpl must not be a str'
return templatespec(b'', tmpl, None)
--- a/mercurial/graphmod.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/graphmod.py Fri Mar 25 11:33:12 2022 -0400
@@ -17,7 +17,6 @@
Data depends on type.
"""
-from __future__ import absolute_import
from .node import nullrev
from .thirdparty import attr
@@ -359,7 +358,7 @@
@attr.s
-class asciistate(object):
+class asciistate:
"""State of ascii() graph rendering"""
seen = attr.ib(init=False, default=attr.Factory(list))
--- a/mercurial/grep.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/grep.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import difflib
import errno
@@ -36,7 +35,7 @@
yield linenum, mstart - lstart, mend - lstart, body[lstart:lend]
-class linestate(object):
+class linestate:
def __init__(self, line, linenum, colstart, colend):
self.line = line
self.linenum = linenum
@@ -80,7 +79,7 @@
yield (b'+', b[i])
-class grepsearcher(object):
+class grepsearcher:
"""Search files and revisions for lines matching the given pattern
Options:
--- a/mercurial/hbisect.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hbisect.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import contextlib
--- a/mercurial/help.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/help.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import itertools
import re
@@ -126,7 +125,7 @@
'''return a text listing of the given extensions'''
rst = []
if exts:
- for name, desc in sorted(pycompat.iteritems(exts)):
+ for name, desc in sorted(exts.items()):
if not showdeprecated and any(w in desc for w in _exclkeywords):
continue
rst.append(b'%s:%s: %s\n' % (b' ' * indent, name, desc))
@@ -281,7 +280,7 @@
name = names[0]
if not filtertopic(ui, name):
results[b'topics'].append((names[0], header))
- for cmd, entry in pycompat.iteritems(commands.table):
+ for cmd, entry in commands.table.items():
if len(entry) == 3:
summary = entry[2]
else:
@@ -298,8 +297,8 @@
continue
results[b'commands'].append((cmdname, summary))
for name, docs in itertools.chain(
- pycompat.iteritems(extensions.enabled(False)),
- pycompat.iteritems(extensions.disabled()),
+ extensions.enabled(False).items(),
+ extensions.disabled().items(),
):
if not docs:
continue
@@ -312,7 +311,7 @@
except ImportError:
# debug message would be printed in extensions.load()
continue
- for cmd, entry in pycompat.iteritems(getattr(mod, 'cmdtable', {})):
+ for cmd, entry in getattr(mod, 'cmdtable', {}).items():
if kw in cmd or (len(entry) > 2 and lowercontains(entry[2])):
cmdname = cmdutil.parsealiases(cmd)[0]
func = entry[0]
@@ -665,7 +664,7 @@
h = {}
# Command -> string showing synonyms
syns = {}
- for c, e in pycompat.iteritems(cmdtable):
+ for c, e in cmdtable.items():
fs = cmdutil.parsealiases(c)
f = fs[0]
syns[f] = fs
--- a/mercurial/hg.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hg.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
@@ -1535,7 +1534,7 @@
]
-class cachedlocalrepo(object):
+class cachedlocalrepo:
"""Holds a localrepository that can be cached and reused."""
def __init__(self, repo):
--- a/mercurial/hgweb/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
@@ -37,7 +36,7 @@
- list of virtual:real tuples (multi-repo view)
"""
- if isinstance(config, pycompat.unicode):
+ if isinstance(config, str):
raise error.ProgrammingError(
b'Mercurial only supports encoded strings: %r' % config
)
@@ -55,7 +54,7 @@
return hgwebdir_mod.hgwebdir(config, baseui=baseui)
-class httpservice(object):
+class httpservice:
def __init__(self, ui, app, opts):
self.ui = ui
self.app = app
--- a/mercurial/hgweb/common.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/common.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import base64
import errno
@@ -116,7 +115,7 @@
self.message = message
-class continuereader(object):
+class continuereader:
"""File object wrapper to handle HTTP 100-continue.
This is used by servers so they automatically handle Expect: 100-continue
--- a/mercurial/hgweb/hgweb_mod.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/hgweb_mod.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import os
@@ -111,7 +110,7 @@
return templateutil.mappinglist(reversed(breadcrumb))
-class requestcontext(object):
+class requestcontext:
"""Holds state/context for an individual request.
Servers can be multi-threaded. Holding state on the WSGI application
@@ -236,7 +235,7 @@
return self.res.sendresponse()
-class hgweb(object):
+class hgweb:
"""HTTP server for individual repositories.
Instances of this class serve HTTP responses for a particular
@@ -413,7 +412,7 @@
if cmd == b'archive':
fn = req.qsparams[b'node']
- for type_, spec in pycompat.iteritems(webutil.archivespecs):
+ for type_, spec in webutil.archivespecs.items():
ext = spec[2]
if fn.endswith(ext):
req.qsparams[b'node'] = fn[: -len(ext)]
--- a/mercurial/hgweb/hgwebdir_mod.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/hgwebdir_mod.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import gc
import os
@@ -269,7 +268,7 @@
return templateutil.mappinggenerator(_indexentriesgen, args=args)
-class hgwebdir(object):
+class hgwebdir:
"""HTTP server for multiple repositories.
Given a configuration, different repositories will be served depending
@@ -461,12 +460,9 @@
if real:
# Re-parse the WSGI environment to take into account our
# repository path component.
- uenv = req.rawenv
- if pycompat.ispy3:
- uenv = {
- k.decode('latin1'): v
- for k, v in pycompat.iteritems(uenv)
- }
+ uenv = {
+ k.decode('latin1'): v for k, v in req.rawenv.items()
+ }
req = requestmod.parserequestfromenv(
uenv,
reponame=virtualrepo,
--- a/mercurial/hgweb/request.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/request.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
# import wsgiref.validate
@@ -22,7 +21,7 @@
)
-class multidict(object):
+class multidict:
"""A dict like object that can store multiple values for a key.
Used to store parsed request parameters.
@@ -78,11 +77,11 @@
return vals[0]
def asdictoflists(self):
- return {k: list(v) for k, v in pycompat.iteritems(self._items)}
+ return {k: list(v) for k, v in self._items.items()}
@attr.s(frozen=True)
-class parsedrequest(object):
+class parsedrequest:
"""Represents a parsed WSGI request.
Contains both parsed parameters as well as a handle on the input stream.
@@ -161,24 +160,22 @@
# TODO enable this once we fix internal violations.
# wsgiref.validate.check_environ(env)
- # PEP-0333 states that environment keys and values are native strings
- # (bytes on Python 2 and str on Python 3). The code points for the Unicode
- # strings on Python 3 must be between \00000-\000FF. We deal with bytes
- # in Mercurial, so mass convert string keys and values to bytes.
- if pycompat.ispy3:
+ # PEP-0333 states that environment keys and values are native strings.
+ # The code points for the Unicode strings on Python 3 must be between
+ # \00000-\000FF. We deal with bytes in Mercurial, so mass convert string
+ # keys and values to bytes.
+ def tobytes(s):
+ if not isinstance(s, str):
+ return s
+ if pycompat.iswindows:
+ # This is what mercurial.encoding does for os.environ on
+ # Windows.
+ return encoding.strtolocal(s)
+ else:
+ # This is what is documented to be used for os.environ on Unix.
+ return pycompat.fsencode(s)
- def tobytes(s):
- if not isinstance(s, str):
- return s
- if pycompat.iswindows:
- # This is what mercurial.encoding does for os.environ on
- # Windows.
- return encoding.strtolocal(s)
- else:
- # This is what is documented to be used for os.environ on Unix.
- return pycompat.fsencode(s)
-
- env = {tobytes(k): tobytes(v) for k, v in pycompat.iteritems(env)}
+ env = {tobytes(k): tobytes(v) for k, v in env.items()}
# Some hosting solutions are emulating hgwebdir, and dispatching directly
# to an hgweb instance using this environment variable. This was always
@@ -312,7 +309,7 @@
# perform case normalization for us. We just rewrite underscore to dash
# so keys match what likely went over the wire.
headers = []
- for k, v in pycompat.iteritems(env):
+ for k, v in env.items():
if k.startswith(b'HTTP_'):
headers.append((k[len(b'HTTP_') :].replace(b'_', b'-'), v))
@@ -358,7 +355,7 @@
)
-class offsettrackingwriter(object):
+class offsettrackingwriter:
"""A file object like object that is append only and tracks write count.
Instances are bound to a callable. This callable is called with data
@@ -391,7 +388,7 @@
return self._offset
-class wsgiresponse(object):
+class wsgiresponse:
"""Represents a response to a WSGI request.
A response consists of a status line, headers, and a body.
--- a/mercurial/hgweb/server.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/server.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import importlib
@@ -53,7 +52,7 @@
return urlreq.unquote(path), query
-class _error_logger(object):
+class _error_logger:
def __init__(self, handler):
self.handler = handler
@@ -186,18 +185,11 @@
env['REMOTE_ADDR'] = self.client_address[0]
env['QUERY_STRING'] = query or ''
- if pycompat.ispy3:
- if self.headers.get_content_type() is None:
- env['CONTENT_TYPE'] = self.headers.get_default_type()
- else:
- env['CONTENT_TYPE'] = self.headers.get_content_type()
- length = self.headers.get('content-length')
+ if self.headers.get_content_type() is None:
+ env['CONTENT_TYPE'] = self.headers.get_default_type()
else:
- if self.headers.typeheader is None:
- env['CONTENT_TYPE'] = self.headers.type
- else:
- env['CONTENT_TYPE'] = self.headers.typeheader
- length = self.headers.getheader('content-length')
+ env['CONTENT_TYPE'] = self.headers.get_content_type()
+ length = self.headers.get('content-length')
if length:
env['CONTENT_LENGTH'] = length
for header in [
@@ -351,7 +343,7 @@
_mixin = socketserver.ForkingMixIn
else:
- class _mixin(object):
+ class _mixin:
pass
--- a/mercurial/hgweb/webcommands.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/webcommands.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import copy
import mimetypes
@@ -47,7 +46,7 @@
commands = {}
-class webcommand(object):
+class webcommand:
"""Decorator used to register a web command handler.
The decorator takes as its positional arguments the name/path the
@@ -564,7 +563,7 @@
l = len(path)
abspath = b"/" + path
- for full, n in pycompat.iteritems(mf):
+ for full, n in mf.items():
# the virtual path (working copy path) used for the full
# (repository) path
f = decodepath(full)
@@ -1521,7 +1520,7 @@
early, other = [], []
primary = lambda s: s.partition(b'|')[0]
- for c, e in pycompat.iteritems(commands.table):
+ for c, e in commands.table.items():
doc = _getdoc(e)
if b'DEPRECATED' in doc or c.startswith(b'debug'):
continue
--- a/mercurial/hgweb/webutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/webutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import copy
import difflib
@@ -57,7 +56,7 @@
allowed = ui.configlist(b'web', b'allow-archive', untrusted=True)
archives = []
- for typ, spec in pycompat.iteritems(archivespecs):
+ for typ, spec in archivespecs.items():
if typ in allowed or ui.configbool(
b'web', b'allow' + typ, untrusted=True
):
@@ -100,7 +99,7 @@
step *= 10
-class revnav(object):
+class revnav:
def __init__(self, repo):
"""Navigation generation object
@@ -864,7 +863,7 @@
def itermaps(self, context):
separator = self._start
- for key, value in sorted(pycompat.iteritems(self._vars)):
+ for key, value in sorted(self._vars.items()):
yield {
b'name': key,
b'value': pycompat.bytestr(value),
--- a/mercurial/hgweb/wsgicgi.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/wsgicgi.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
# This was originally copied from the public domain code at
# http://www.python.org/dev/peps/pep-0333/#the-server-gateway-side
-from __future__ import absolute_import
import os
@@ -24,7 +23,7 @@
procutil.setbinary(procutil.stdin)
procutil.setbinary(procutil.stdout)
- environ = dict(pycompat.iteritems(os.environ)) # re-exports
+ environ = dict(os.environ.items()) # re-exports
environ.setdefault('PATH_INFO', '')
if environ.get('SERVER_SOFTWARE', '').startswith('Microsoft-IIS'):
# IIS includes script_name in PATH_INFO
--- a/mercurial/hgweb/wsgiheaders.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hgweb/wsgiheaders.py Fri Mar 25 11:33:12 2022 -0400
@@ -9,7 +9,6 @@
# Regular expression that matches `special' characters in parameters, the
# existence of which force quoting of the parameter value.
-from __future__ import absolute_import, print_function
import re
@@ -30,7 +29,7 @@
return param
-class Headers(object):
+class Headers:
"""Manage a collection of HTTP response headers"""
def __init__(self, headers=None):
--- a/mercurial/hook.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/hook.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import errno
@@ -167,7 +166,7 @@
else:
env[b'HGPLAIN'] = b''
- for k, v in pycompat.iteritems(args):
+ for k, v in args.items():
# transaction changes can accumulate MBs of data, so skip it
# for external hooks
if k == b'changes':
--- a/mercurial/httpconnection.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/httpconnection.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
@@ -27,7 +26,7 @@
urlreq = util.urlreq
# moved here from url.py to avoid a cycle
-class httpsendfile(object):
+class httpsendfile:
"""This is a wrapper around the objects returned by python's "open".
Its purpose is to send file-like objects via HTTP.
@@ -94,7 +93,7 @@
bestuser = None
bestlen = 0
bestauth = None
- for group, auth in pycompat.iteritems(groups):
+ for group, auth in groups.items():
if user and user != auth.get(b'username', user):
# If a username was set in the URI, the entry username
# must either match it or be unset
--- a/mercurial/httppeer.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/httppeer.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import io
@@ -14,6 +13,7 @@
import socket
import struct
+from concurrent import futures
from .i18n import _
from .pycompat import getattr
from . import (
@@ -62,7 +62,7 @@
return result
-class _multifile(object):
+class _multifile:
def __init__(self, *fileobjs):
for f in fileobjs:
if not util.safehasattr(f, b'length'):
@@ -231,15 +231,6 @@
return req, cu, qs
-def _reqdata(req):
- """Get request data, if any. If no data, returns None."""
- if pycompat.ispy3:
- return req.data
- if not req.has_data():
- return None
- return req.get_data()
-
-
def sendrequest(ui, opener, req):
"""Send a prepared HTTP request.
@@ -274,7 +265,7 @@
% b' %d bytes of commands arguments in headers'
% hgargssize
)
- data = _reqdata(req)
+ data = req.data
if data is not None:
length = getattr(data, 'length', None)
if length is None:
@@ -538,12 +529,12 @@
raise exception
-class queuedcommandfuture(pycompat.futures.Future):
+class queuedcommandfuture(futures.Future):
"""Wraps result() on command futures to trigger submission on call."""
def result(self, timeout=None):
if self.done():
- return pycompat.futures.Future.result(self, timeout)
+ return futures.Future.result(self, timeout)
self._peerexecutor.sendcommands()
--- a/mercurial/i18n.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/i18n.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import gettext as gettextmod
import locale
@@ -86,9 +85,9 @@
cache = _msgcache.setdefault(encoding.encoding, {})
if message not in cache:
- if type(message) is pycompat.unicode:
+ if type(message) is str:
# goofy unicode docstrings in test
- paragraphs = message.split(u'\n\n') # type: List[pycompat.unicode]
+ paragraphs = message.split(u'\n\n') # type: List[str]
else:
# should be ascii, but we have unicode docstrings in test, which
# are converted to utf-8 bytes on Python 3.
--- a/mercurial/interfaces/dirstate.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/interfaces/dirstate.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import contextlib
from . import util as interfaceutil
--- a/mercurial/interfaces/repository.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/interfaces/repository.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from ..i18n import _
from .. import error
@@ -389,7 +388,7 @@
@interfaceutil.implementer(ipeerbase)
-class peer(object):
+class peer:
"""Base class for peer repositories."""
limitedarguments = False
--- a/mercurial/interfaces/util.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/interfaces/util.py Fri Mar 25 11:33:12 2022 -0400
@@ -9,7 +9,6 @@
# bookkeeping for declaring interfaces. So, we use stubs for various
# zope.interface primitives unless instructed otherwise.
-from __future__ import absolute_import
from .. import encoding
@@ -21,11 +20,11 @@
implementer = zi.implementer
else:
- class Attribute(object):
+ class Attribute:
def __init__(self, __name__, __doc__=b''):
pass
- class Interface(object):
+ class Interface:
def __init__(
self, name, bases=(), attrs=None, __doc__=None, __module__=None
):
--- a/mercurial/keepalive.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/keepalive.py Fri Mar 25 11:33:12 2022 -0400
@@ -82,7 +82,6 @@
# $Id: keepalive.py,v 1.14 2006/04/04 21:00:32 mstenner Exp $
-from __future__ import absolute_import, print_function
import collections
import errno
@@ -108,7 +107,7 @@
DEBUG = None
-class ConnectionManager(object):
+class ConnectionManager:
"""
The connection manager must be able to:
* keep track of all existing
@@ -171,7 +170,7 @@
return dict(self._hostmap)
-class KeepAliveHandler(object):
+class KeepAliveHandler:
def __init__(self, timeout=None):
self._cm = ConnectionManager()
self._timeout = timeout
@@ -194,7 +193,7 @@
def close_all(self):
"""close all open connections"""
- for host, conns in pycompat.iteritems(self._cm.get_all()):
+ for host, conns in self._cm.get_all().items():
for h in conns:
self._cm.remove(h)
h.close()
@@ -399,12 +398,8 @@
# modification from socket.py
def __init__(self, sock, debuglevel=0, strict=0, method=None):
- extrakw = {}
- if not pycompat.ispy3:
- extrakw['strict'] = True
- extrakw['buffering'] = True
httplib.HTTPResponse.__init__(
- self, sock, debuglevel=debuglevel, method=method, **extrakw
+ self, sock, debuglevel=debuglevel, method=method
)
self.fileno = sock.fileno
self.code = None
@@ -794,7 +789,7 @@
global DEBUG
dbbackup = DEBUG
- class FakeLogger(object):
+ class FakeLogger:
def debug(self, msg, *args):
print(msg % args)
--- a/mercurial/linelog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/linelog.py Fri Mar 25 11:33:12 2022 -0400
@@ -18,7 +18,6 @@
deletion is performed on the file, a jump instruction is used to patch
in a new body of annotate information.
"""
-from __future__ import absolute_import, print_function
import abc
import struct
@@ -34,7 +33,7 @@
@attr.s
-class lineinfo(object):
+class lineinfo:
# Introducing revision of this line.
rev = attr.ib()
# Line number for this line in its introducing revision.
@@ -44,7 +43,7 @@
@attr.s
-class annotateresult(object):
+class annotateresult:
rev = attr.ib()
lines = attr.ib()
_eof = attr.ib()
@@ -53,7 +52,7 @@
return iter(self.lines)
-class _llinstruction(object): # pytype: disable=ignored-metaclass
+class _llinstruction: # pytype: disable=ignored-metaclass
__metaclass__ = abc.ABCMeta
@@ -234,7 +233,7 @@
raise NotImplementedError(b'Unimplemented opcode %r' % opcode)
-class linelog(object):
+class linelog:
"""Efficient cache for per-line history information."""
def __init__(self, program=None, maxrev=0):
--- a/mercurial/localrepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/localrepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import functools
@@ -16,6 +15,7 @@
import time
import weakref
+from concurrent import futures
from .i18n import _
from .node import (
bin,
@@ -251,7 +251,7 @@
@interfaceutil.implementer(repository.ipeercommandexecutor)
-class localcommandexecutor(object):
+class localcommandexecutor:
def __init__(self, peer):
self._peer = peer
self._sent = False
@@ -278,7 +278,7 @@
# method on the peer and return a resolved future.
fn = getattr(self._peer, pycompat.sysstr(command))
- f = pycompat.futures.Future()
+ f = futures.Future()
try:
result = fn(**pycompat.strkwargs(args))
@@ -1215,7 +1215,7 @@
@interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
-class revlogfilestorage(object):
+class revlogfilestorage:
"""File storage when using revlogs."""
def file(self, path):
@@ -1226,7 +1226,7 @@
@interfaceutil.implementer(repository.ilocalrepositoryfilestorage)
-class revlognarrowfilestorage(object):
+class revlognarrowfilestorage:
"""File storage when using revlogs and narrow files."""
def file(self, path):
@@ -1259,7 +1259,7 @@
@interfaceutil.implementer(repository.ilocalrepositorymain)
-class localrepository(object):
+class localrepository:
"""Main class for representing local repositories.
All local repositories are instances of this class.
@@ -2044,7 +2044,7 @@
# This simplifies its cache management by having one decorated
# function (this one) and the rest simply fetch things from it.
- class tagscache(object):
+ class tagscache:
def __init__(self):
# These two define the set of tags for this repository. tags
# maps tag name to node; tagtypes maps tag name to 'global' or
@@ -2068,7 +2068,7 @@
else:
tags = self._tagscache.tags
rev = self.changelog.rev
- for k, v in pycompat.iteritems(tags):
+ for k, v in tags.items():
try:
# ignore tags to unknown nodes
rev(v)
@@ -2103,13 +2103,12 @@
# writing to the cache), but the rest of Mercurial wants them in
# local encoding.
tags = {}
- for (name, (node, hist)) in pycompat.iteritems(alltags):
+ for (name, (node, hist)) in alltags.items():
if node != self.nullid:
tags[encoding.tolocal(name)] = node
tags[b'tip'] = self.changelog.tip()
tagtypes = {
- encoding.tolocal(name): value
- for (name, value) in pycompat.iteritems(tagtypes)
+ encoding.tolocal(name): value for (name, value) in tagtypes.items()
}
return (tags, tagtypes)
@@ -2128,7 +2127,7 @@
'''return a list of tags ordered by revision'''
if not self._tagscache.tagslist:
l = []
- for t, n in pycompat.iteritems(self.tags()):
+ for t, n in self.tags().items():
l.append((self.changelog.rev(n), t, n))
self._tagscache.tagslist = [(t, n) for r, t, n in sorted(l)]
@@ -2138,9 +2137,9 @@
'''return the tags associated with a node'''
if not self._tagscache.nodetagscache:
nodetagscache = {}
- for t, n in pycompat.iteritems(self._tagscache.tags):
+ for t, n in self._tagscache.tags.items():
nodetagscache.setdefault(n, []).append(t)
- for tags in pycompat.itervalues(nodetagscache):
+ for tags in nodetagscache.values():
tags.sort()
self._tagscache.nodetagscache = nodetagscache
return self._tagscache.nodetagscache.get(node, [])
@@ -2256,7 +2255,7 @@
mf = matchmod.match(self.root, b'', [pat])
fn = None
params = cmd
- for name, filterfn in pycompat.iteritems(self._datafilters):
+ for name, filterfn in self._datafilters.items():
if cmd.startswith(name):
fn = filterfn
params = cmd[len(name) :].lstrip()
@@ -3913,7 +3912,7 @@
#
# But we have to allow the close() method because some constructors
# of repos call close() on repo references.
- class poisonedrepository(object):
+ class poisonedrepository:
def __getattribute__(self, item):
if item == 'close':
return object.__getattribute__(self, item)
--- a/mercurial/lock.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/lock.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import errno
@@ -174,7 +173,7 @@
return l
-class lock(object):
+class lock:
"""An advisory lock held by one process to control access to a set
of files. Non-cooperating processes or incorrectly written scripts
can ignore Mercurial's locking scheme and stomp all over the
--- a/mercurial/logcmdutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/logcmdutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import itertools
import os
@@ -228,7 +227,7 @@
)
-class changesetdiffer(object):
+class changesetdiffer:
"""Generate diff of changeset with pre-configured filtering functions"""
def _makefilematcher(self, ctx):
@@ -262,7 +261,7 @@
return b' '.join(labels)
-class changesetprinter(object):
+class changesetprinter:
'''show changeset information when templating not requested.'''
def __init__(self, ui, repo, differ=None, diffopts=None, buffered=False):
@@ -328,7 +327,7 @@
if branch != b'default':
self.ui.write(columns[b'branch'] % branch, label=b'log.branch')
- for nsname, ns in pycompat.iteritems(self.repo.names):
+ for nsname, ns in self.repo.names.items():
# branches has special logic already handled above, so here we just
# skip it
if nsname == b'branches':
@@ -707,7 +706,7 @@
@attr.s
-class walkopts(object):
+class walkopts:
"""Options to configure a set of revisions and file matcher factory
to scan revision/file history
"""
@@ -992,7 +991,7 @@
opts[b'_patslog'] = list(wopts.pats)
expr = []
- for op, val in sorted(pycompat.iteritems(opts)):
+ for op, val in sorted(opts.items()):
if not val:
continue
revop, listop = _opt2logrevset[op]
--- a/mercurial/logexchange.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/logexchange.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,12 +6,10 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .node import hex
from . import (
- pycompat,
util,
vfs as vfsmod,
)
@@ -78,7 +76,7 @@
if oldpath != remotepath:
f.write(b'%s\0%s\0%s\n' % (node, oldpath, rname))
- for name, node in sorted(pycompat.iteritems(names)):
+ for name, node in sorted(names.items()):
if nametype == b"branches":
for n in node:
f.write(b'%s\0%s\0%s\n' % (n, remotepath, name))
@@ -160,7 +158,7 @@
with remoterepo.commandexecutor() as e:
branchmap = e.callcommand(b'branchmap', {}).result()
- for branch, nodes in pycompat.iteritems(branchmap):
+ for branch, nodes in branchmap.items():
bmap[branch] = []
for node in nodes:
if node in repo and not repo[node].obsolete():
--- a/mercurial/loggingutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/loggingutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
@@ -74,7 +73,7 @@
return b'*' in tracked or event in tracked
-class filelogger(object):
+class filelogger:
"""Basic logger backed by physical file with optional rotation"""
def __init__(self, vfs, name, tracked, maxfiles=0, maxsize=0):
@@ -105,7 +104,7 @@
)
-class fileobjectlogger(object):
+class fileobjectlogger:
"""Basic logger backed by file-like object"""
def __init__(self, fp, tracked):
@@ -130,7 +129,7 @@
)
-class proxylogger(object):
+class proxylogger:
"""Forward log events to another logger to be set later"""
def __init__(self):
--- a/mercurial/lsprof.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/lsprof.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,10 +1,7 @@
-from __future__ import absolute_import, print_function
-
import _lsprof
import sys
from .pycompat import getattr
-from . import pycompat
Profiler = _lsprof.Profiler
@@ -25,7 +22,7 @@
return Stats(p.getstats())
-class Stats(object):
+class Stats:
"""XXX docstring"""
def __init__(self, data):
@@ -120,13 +117,11 @@
def label(code):
if isinstance(code, str):
- if sys.version_info.major >= 3:
- code = code.encode('latin-1')
- return code
+ return code.encode('latin-1')
try:
mname = _fn2mod[code.co_filename]
except KeyError:
- for k, v in list(pycompat.iteritems(sys.modules)):
+ for k, v in list(sys.modules.items()):
if v is None:
continue
if not isinstance(getattr(v, '__file__', None), str):
@@ -139,7 +134,4 @@
res = '%s:%d(%s)' % (mname, code.co_firstlineno, code.co_name)
- if sys.version_info.major >= 3:
- res = res.encode('latin-1')
-
- return res
+ return res.encode('latin-1')
--- a/mercurial/lsprofcalltree.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/lsprofcalltree.py Fri Mar 25 11:33:12 2022 -0400
@@ -10,7 +10,6 @@
of the GNU General Public License, incorporated herein by reference.
"""
-from __future__ import absolute_import
from . import pycompat
@@ -27,7 +26,7 @@
)
-class KCacheGrind(object):
+class KCacheGrind:
def __init__(self, profiler):
self.data = profiler.getstats()
self.out_file = None
--- a/mercurial/mail.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/mail.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import email
import email.charset
@@ -468,43 +467,28 @@
return mimetextqp(s, 'plain', cs)
-if pycompat.ispy3:
-
- Generator = email.generator.BytesGenerator
-
- def parse(fp):
- # type: (Any) -> email.message.Message
- ep = email.parser.Parser()
- # disable the "universal newlines" mode, which isn't binary safe.
- # I have no idea if ascii/surrogateescape is correct, but that's
- # what the standard Python email parser does.
- fp = io.TextIOWrapper(
- fp, encoding='ascii', errors='surrogateescape', newline=chr(10)
- )
- try:
- return ep.parse(fp)
- finally:
- fp.detach()
-
- def parsebytes(data):
- # type: (bytes) -> email.message.Message
- ep = email.parser.BytesParser()
- return ep.parsebytes(data)
+Generator = email.generator.BytesGenerator
-else:
-
- Generator = email.generator.Generator
+def parse(fp):
+ # type: (Any) -> email.message.Message
+ ep = email.parser.Parser()
+ # disable the "universal newlines" mode, which isn't binary safe.
+ # I have no idea if ascii/surrogateescape is correct, but that's
+ # what the standard Python email parser does.
+ fp = io.TextIOWrapper(
+ fp, encoding='ascii', errors='surrogateescape', newline=chr(10)
+ )
+ try:
+ return ep.parse(fp)
+ finally:
+ fp.detach()
- def parse(fp):
- # type: (Any) -> email.message.Message
- ep = email.parser.Parser()
- return ep.parse(fp)
- def parsebytes(data):
- # type: (str) -> email.message.Message
- ep = email.parser.Parser()
- return ep.parsestr(data)
+def parsebytes(data):
+ # type: (bytes) -> email.message.Message
+ ep = email.parser.BytesParser()
+ return ep.parsebytes(data)
def headdecode(s):
--- a/mercurial/manifest.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/manifest.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import heapq
import itertools
@@ -85,7 +84,7 @@
return b''.join(lines)
-class lazymanifestiter(object):
+class lazymanifestiter:
def __init__(self, lm):
self.pos = 0
self.lm = lm
@@ -108,7 +107,7 @@
__next__ = next
-class lazymanifestiterentries(object):
+class lazymanifestiterentries:
def __init__(self, lm):
self.lm = lm
self.pos = 0
@@ -159,7 +158,7 @@
_manifestflags = {b'', b'l', b't', b'x'}
-class _lazymanifest(object):
+class _lazymanifest:
"""A pure python manifest backed by a byte string. It is supplimented with
internal lists as it is modified, until it is compacted back to a pure byte
string.
@@ -474,7 +473,7 @@
@interfaceutil.implementer(repository.imanifestdict)
-class manifestdict(object):
+class manifestdict:
def __init__(self, nodelen, data=b''):
self._nodelen = nodelen
self._lm = _lazymanifest(nodelen, data)
@@ -797,7 +796,7 @@
@interfaceutil.implementer(repository.imanifestdict)
-class treemanifest(object):
+class treemanifest:
def __init__(self, nodeconstants, dir=b'', text=b''):
self._dir = dir
self.nodeconstants = nodeconstants
@@ -827,9 +826,7 @@
def _loadalllazy(self):
selfdirs = self._dirs
subpath = self._subpath
- for d, (node, readsubtree, docopy) in pycompat.iteritems(
- self._lazydirs
- ):
+ for d, (node, readsubtree, docopy) in self._lazydirs.items():
if docopy:
selfdirs[d] = readsubtree(subpath(d), node).copy()
else:
@@ -868,11 +865,11 @@
differs, load it in both
"""
toloadlazy = []
- for d, v1 in pycompat.iteritems(t1._lazydirs):
+ for d, v1 in t1._lazydirs.items():
v2 = t2._lazydirs.get(d)
if not v2 or v2[0] != v1[0]:
toloadlazy.append(d)
- for d, v1 in pycompat.iteritems(t2._lazydirs):
+ for d, v1 in t2._lazydirs.items():
if d not in t1._lazydirs:
toloadlazy.append(d)
@@ -954,7 +951,7 @@
if p in self._files:
yield self._subpath(p), n
else:
- for f, sn in pycompat.iteritems(n):
+ for f, sn in n.items():
yield f, sn
iteritems = items
@@ -1105,11 +1102,10 @@
def _copyfunc(s):
self._load()
s._lazydirs = {
- d: (n, r, True)
- for d, (n, r, c) in pycompat.iteritems(self._lazydirs)
+ d: (n, r, True) for d, (n, r, c) in self._lazydirs.items()
}
sdirs = s._dirs
- for d, v in pycompat.iteritems(self._dirs):
+ for d, v in self._dirs.items():
sdirs[d] = v.copy()
s._files = dict.copy(self._files)
s._flags = dict.copy(self._flags)
@@ -1137,7 +1133,7 @@
t1._load()
t2._load()
self._loaddifflazy(t1, t2)
- for d, m1 in pycompat.iteritems(t1._dirs):
+ for d, m1 in t1._dirs.items():
if d in t2._dirs:
m2 = t2._dirs[d]
_filesnotin(m1, m2)
@@ -1250,7 +1246,7 @@
ret._flags[fn] = self._flags[fn]
visit = self._loadchildrensetlazy(visit)
- for dir, subm in pycompat.iteritems(self._dirs):
+ for dir, subm in self._dirs.items():
if visit and dir[:-1] not in visit:
continue
m = subm._matches_inner(match)
@@ -1295,15 +1291,15 @@
t2._load()
self._loaddifflazy(t1, t2)
- for d, m1 in pycompat.iteritems(t1._dirs):
+ for d, m1 in t1._dirs.items():
m2 = t2._dirs.get(d, emptytree)
stack.append((m1, m2))
- for d, m2 in pycompat.iteritems(t2._dirs):
+ for d, m2 in t2._dirs.items():
if d not in t1._dirs:
stack.append((emptytree, m2))
- for fn, n1 in pycompat.iteritems(t1._files):
+ for fn, n1 in t1._files.items():
fl1 = t1._flags.get(fn, b'')
n2 = t2._files.get(fn, None)
fl2 = t2._flags.get(fn, b'')
@@ -1312,7 +1308,7 @@
elif clean:
result[t1._subpath(fn)] = None
- for fn, n2 in pycompat.iteritems(t2._files):
+ for fn, n2 in t2._files.items():
if fn not in t1._files:
fl2 = t2._flags.get(fn, b'')
result[t2._subpath(fn)] = ((None, b''), (n2, fl2))
@@ -1362,9 +1358,7 @@
"""
self._load()
flags = self.flags
- lazydirs = [
- (d[:-1], v[0], b't') for d, v in pycompat.iteritems(self._lazydirs)
- ]
+ lazydirs = [(d[:-1], v[0], b't') for d, v in self._lazydirs.items()]
dirs = [(d[:-1], self._dirs[d]._node, b't') for d in self._dirs]
files = [(f, self._files[f], flags(f)) for f in self._files]
return _text(sorted(dirs + files + lazydirs))
@@ -1393,7 +1387,7 @@
visit = self._loadchildrensetlazy(visit)
if visit == b'this' or visit == b'all':
visit = None
- for d, subm in pycompat.iteritems(self._dirs):
+ for d, subm in self._dirs.items():
if visit and d[:-1] not in visit:
continue
subp1 = getnode(m1, d)
@@ -1416,7 +1410,7 @@
self._load()
# OPT: use visitchildrenset to avoid loading everything.
self._loadalllazy()
- for d, subm in pycompat.iteritems(self._dirs):
+ for d, subm in self._dirs.items():
for subtree in subm.walksubtrees(matcher=matcher):
yield subtree
@@ -1556,7 +1550,7 @@
@interfaceutil.implementer(repository.imanifeststorage)
-class manifestrevlog(object):
+class manifestrevlog:
"""A revlog that stores manifest texts. This is responsible for caching the
full-text manifest contents.
"""
@@ -1914,7 +1908,7 @@
@interfaceutil.implementer(repository.imanifestlog)
-class manifestlog(object):
+class manifestlog:
"""A collection class representing the collection of manifest snapshots
referenced by commits in the repository.
@@ -2013,7 +2007,7 @@
@interfaceutil.implementer(repository.imanifestrevisionwritable)
-class memmanifestctx(object):
+class memmanifestctx:
def __init__(self, manifestlog):
self._manifestlog = manifestlog
self._manifestdict = manifestdict(manifestlog.nodeconstants.nodelen)
@@ -2043,7 +2037,7 @@
@interfaceutil.implementer(repository.imanifestrevisionstored)
-class manifestctx(object):
+class manifestctx:
"""A class representing a single revision of a manifest, including its
contents, its parent revs, and its linkrev.
"""
@@ -2123,7 +2117,7 @@
@interfaceutil.implementer(repository.imanifestrevisionwritable)
-class memtreemanifestctx(object):
+class memtreemanifestctx:
def __init__(self, manifestlog, dir=b''):
self._manifestlog = manifestlog
self._dir = dir
@@ -2158,7 +2152,7 @@
@interfaceutil.implementer(repository.imanifestrevisionstored)
-class treemanifestctx(object):
+class treemanifestctx:
def __init__(self, manifestlog, dir, node):
self._manifestlog = manifestlog
self._dir = dir
@@ -2249,7 +2243,7 @@
m0 = self._manifestlog.get(self._dir, store.node(r0)).read()
m1 = self.read()
md = treemanifest(self._manifestlog.nodeconstants, dir=self._dir)
- for f, ((n0, fl0), (n1, fl1)) in pycompat.iteritems(m0.diff(m1)):
+ for f, ((n0, fl0), (n1, fl1)) in m0.diff(m1).items():
if n1:
md[f] = n1
if fl1:
--- a/mercurial/match.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/match.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import bisect
import copy
@@ -383,7 +382,7 @@
return kindpats
-class basematcher(object):
+class basematcher:
def __init__(self, badfn=None):
if badfn is not None:
self.bad = badfn
@@ -584,10 +583,7 @@
if b'' in prefix_set:
return True
- if pycompat.ispy3:
- sl = ord(b'/')
- else:
- sl = '/'
+ sl = ord(b'/')
# We already checked that path isn't in prefix_set exactly, so
# `path[len(pf)] should never raise IndexError.
@@ -663,7 +659,7 @@
# This is basically a reimplementation of pathutil.dirs that stores the
# children instead of just a count of them, plus a small optional optimization
# to avoid some directories we don't need.
-class _dirchildren(object):
+class _dirchildren:
def __init__(self, paths, onlyinclude=None):
self._dirs = {}
self._onlyinclude = onlyinclude or []
@@ -1615,7 +1611,7 @@
patterns = []
fp = open(filepath, b'rb')
- for lineno, line in enumerate(util.iterfile(fp), start=1):
+ for lineno, line in enumerate(fp, start=1):
if b"#" in line:
global _commentre
if not _commentre:
@@ -1642,7 +1638,7 @@
continue
linesyntax = syntax
- for s, rels in pycompat.iteritems(syntaxes):
+ for s, rels in syntaxes.items():
if line.startswith(rels):
linesyntax = rels
line = line[len(rels) :]
--- a/mercurial/mdiff.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/mdiff.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
import struct
@@ -38,7 +37,7 @@
# TODO: this looks like it could be an attrs, which might help pytype
-class diffopts(object):
+class diffopts:
"""context is the number of context lines
text treats all files as text
showfunc enables diff -p output
--- a/mercurial/merge.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/merge.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import errno
@@ -67,7 +66,7 @@
)
-class _unknowndirschecker(object):
+class _unknowndirschecker:
"""
Look for any unknown files or directories that may have a path conflict
with a file. If any path prefix of the file exists as a file or link,
@@ -538,7 +537,7 @@
raise error.StateError(msg % f)
-class mergeresult(object):
+class mergeresult:
"""An object representing result of merging manifests.
It has information about what actions need to be performed on dirstate
@@ -626,9 +625,7 @@
args, msg = self._actionmapping[a][f]
yield f, args, msg
else:
- for f, (args, msg) in pycompat.iteritems(
- self._actionmapping[a]
- ):
+ for f, (args, msg) in self._actionmapping[a].items():
yield f, args, msg
def len(self, actions=None):
@@ -644,10 +641,10 @@
def filemap(self, sort=False):
if sorted:
- for key, val in sorted(pycompat.iteritems(self._filemapping)):
+ for key, val in sorted(self._filemapping.items()):
yield key, val
else:
- for key, val in pycompat.iteritems(self._filemapping):
+ for key, val in self._filemapping.items():
yield key, val
def addcommitinfo(self, filename, key, value):
@@ -672,15 +669,15 @@
"""returns a dictionary of actions to be perfomed with action as key
and a list of files and related arguments as values"""
res = collections.defaultdict(list)
- for a, d in pycompat.iteritems(self._actionmapping):
- for f, (args, msg) in pycompat.iteritems(d):
+ for a, d in self._actionmapping.items():
+ for f, (args, msg) in d.items():
res[a].append((f, args, msg))
return res
def setactions(self, actions):
self._filemapping = actions
self._actionmapping = collections.defaultdict(dict)
- for f, (act, data, msg) in pycompat.iteritems(self._filemapping):
+ for f, (act, data, msg) in self._filemapping.items():
self._actionmapping[act][f] = data, msg
def hasconflicts(self):
@@ -787,7 +784,7 @@
relevantfiles = set(ma.diff(m2).keys())
# For copied and moved files, we need to add the source file too.
- for copykey, copyvalue in pycompat.iteritems(branch_copies1.copy):
+ for copykey, copyvalue in branch_copies1.copy.items():
if copyvalue in relevantfiles:
relevantfiles.add(copykey)
for movedirkey in branch_copies1.movewithdir:
@@ -797,7 +794,7 @@
diff = m1.diff(m2, match=matcher)
- for f, ((n1, fl1), (n2, fl2)) in pycompat.iteritems(diff):
+ for f, ((n1, fl1), (n2, fl2)) in diff.items():
if n1 and n2: # file exists on both local and remote side
if f not in ma:
# TODO: what if they're renamed from different sources?
@@ -1470,7 +1467,7 @@
@attr.s(frozen=True)
-class updateresult(object):
+class updateresult:
updatedcount = attr.ib()
mergedcount = attr.ib()
removedcount = attr.ib()
@@ -1512,7 +1509,7 @@
ms = wctx.mergestate(clean=True)
ms.start(wctx.p1().node(), mctx.node(), labels)
- for f, op in pycompat.iteritems(mresult.commitinfo):
+ for f, op in mresult.commitinfo.items():
# the other side of filenode was choosen while merging, store this in
# mergestate so that it can be reused on commit
ms.addcommitinfo(f, op)
@@ -2073,7 +2070,7 @@
_checkcollision(repo, wc.manifest(), mresult)
# divergent renames
- for f, fl in sorted(pycompat.iteritems(mresult.diverge)):
+ for f, fl in sorted(mresult.diverge.items()):
repo.ui.warn(
_(
b"note: possible conflict - %s was renamed "
@@ -2085,7 +2082,7 @@
repo.ui.warn(b" %s\n" % nf)
# rename and delete
- for f, fl in sorted(pycompat.iteritems(mresult.renamedelete)):
+ for f, fl in sorted(mresult.renamedelete.items()):
repo.ui.warn(
_(
b"note: possible conflict - %s was deleted "
@@ -2125,7 +2122,7 @@
if updatedirstate:
if extraactions:
- for k, acts in pycompat.iteritems(extraactions):
+ for k, acts in extraactions.items():
for a in acts:
mresult.addfile(a[0], k, *a[1:])
if k == mergestatemod.ACTION_GET and wantfiledata:
@@ -2196,10 +2193,10 @@
getfiledata = None
else:
now_sec = now[0]
- for f, m in pycompat.iteritems(getfiledata):
+ for f, m in getfiledata.items():
if m is not None and m[2][0] >= now_sec:
ambiguous_mtime[f] = (m[0], m[1], None)
- for f, m in pycompat.iteritems(ambiguous_mtime):
+ for f, m in ambiguous_mtime.items():
getfiledata[f] = m
repo.setparents(fp1, fp2)
--- a/mercurial/mergestate.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/mergestate.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import collections
import errno
import shutil
@@ -15,7 +13,6 @@
from . import (
error,
filemerge,
- pycompat,
util,
)
from .utils import hashutil
@@ -103,7 +100,7 @@
CHANGE_MODIFIED = b'modified'
-class MergeAction(object):
+class MergeAction:
"""represent an "action" merge need to take for a given file
Attributes:
@@ -197,7 +194,7 @@
)
-class _mergestate_base(object):
+class _mergestate_base:
"""track 3-way merge state of individual files
The merge state is stored on disk when needed. Two files are used: one with
@@ -365,7 +362,7 @@
def unresolved(self):
"""Obtain the paths of unresolved files."""
- for f, entry in pycompat.iteritems(self._state):
+ for f, entry in self._state.items():
if entry[0] in (
MERGE_RECORD_UNRESOLVED,
MERGE_RECORD_UNRESOLVED_PATH,
@@ -469,7 +466,7 @@
"""return counts for updated, merged and removed files in this
session"""
updated, merged, removed = 0, 0, 0
- for r, action in pycompat.itervalues(self._results):
+ for r, action in self._results.values():
if r is None:
updated += 1
elif r == 0:
@@ -492,7 +489,7 @@
ACTION_ADD_MODIFIED: [],
ACTION_GET: [],
}
- for f, (r, action) in pycompat.iteritems(self._results):
+ for f, (r, action) in self._results.items():
if action is not None:
actions[action].append((f, None, b"merge result"))
return actions
@@ -692,7 +689,7 @@
# the type of state that is stored, and capital-letter records are used
# to prevent older versions of Mercurial that do not support the feature
# from loading them.
- for filename, v in pycompat.iteritems(self._state):
+ for filename, v in self._state.items():
if v[0] in (
MERGE_RECORD_UNRESOLVED_PATH,
MERGE_RECORD_RESOLVED_PATH,
@@ -716,9 +713,9 @@
else:
# Normal files. These are stored in 'F' records.
records.append((RECORD_MERGED, b'\0'.join([filename] + v)))
- for filename, extras in sorted(pycompat.iteritems(self._stateextras)):
+ for filename, extras in sorted(self._stateextras.items()):
rawextras = b'\0'.join(
- b'%s\0%s' % (k, v) for k, v in pycompat.iteritems(extras)
+ b'%s\0%s' % (k, v) for k, v in extras.items()
)
records.append(
(RECORD_FILE_VALUES, b'%s\0%s' % (filename, rawextras))
--- a/mercurial/mergeutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/mergeutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
--- a/mercurial/metadata.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/metadata.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import multiprocessing
import struct
@@ -23,7 +22,7 @@
)
-class ChangingFiles(object):
+class ChangingFiles:
"""A class recording the changes made to files by a changeset
Actions performed on files are gathered into 3 sets:
--- a/mercurial/minifileset.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/minifileset.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from . import (
--- a/mercurial/minirst.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/minirst.py Fri Mar 25 11:33:12 2022 -0400
@@ -18,7 +18,6 @@
when adding support for new constructs.
"""
-from __future__ import absolute_import
import re
--- a/mercurial/namespaces.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/namespaces.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,8 +1,5 @@
-from __future__ import absolute_import
-
from .i18n import _
from . import (
- pycompat,
registrar,
templatekw,
util,
@@ -19,7 +16,7 @@
return [val]
-class namespaces(object):
+class namespaces:
"""provides an interface to register and operate on multiple namespaces. See
the namespace class below for details on the namespace object.
@@ -87,7 +84,7 @@
return self._names.get(namespace, default)
def items(self):
- return pycompat.iteritems(self._names)
+ return self._names.items()
iteritems = items
@@ -120,14 +117,14 @@
Raises a KeyError if there is no such node.
"""
- for ns, v in pycompat.iteritems(self._names):
+ for ns, v in self._names.items():
n = v.singlenode(repo, name)
if n:
return n
raise KeyError(_(b'no such name: %s') % name)
-class namespace(object):
+class namespace:
"""provides an interface to a namespace
Namespaces are basically generic many-to-many mapping between some
--- a/mercurial/narrowspec.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/narrowspec.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from .pycompat import getattr
--- a/mercurial/node.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/node.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import binascii
@@ -32,7 +31,7 @@
wdirrev = 0x7FFFFFFF
-class sha1nodeconstants(object):
+class sha1nodeconstants:
nodelen = 20
# In hex, this is '0000000000000000000000000000000000000000'
--- a/mercurial/obsolete.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/obsolete.py Fri Mar 25 11:33:12 2022 -0400
@@ -67,7 +67,6 @@
comment associated with each format for details.
"""
-from __future__ import absolute_import
import errno
import struct
@@ -249,7 +248,7 @@
# if content cannot be translated to nodeid drop the data.
parents = None
- metadata = tuple(sorted(pycompat.iteritems(metadata)))
+ metadata = tuple(sorted(metadata.items()))
yield (pre, sucs, flags, metadata, date, parents)
@@ -279,7 +278,7 @@
"""Return encoded metadata string to string mapping.
Assume no ':' in key and no '\0' in both key and value."""
- for key, value in pycompat.iteritems(meta):
+ for key, value in meta.items():
if b':' in key or b'\0' in key:
raise ValueError(b"':' and '\0' are forbidden in metadata key'")
if b'\0' in value:
@@ -542,7 +541,7 @@
)
-class obsstore(object):
+class obsstore:
"""Store obsolete markers
Markers can be accessed with two mappings:
@@ -653,7 +652,7 @@
'in-marker cycle with %s' % pycompat.sysstr(hex(prec))
)
- metadata = tuple(sorted(pycompat.iteritems(metadata)))
+ metadata = tuple(sorted(metadata.items()))
for k, v in metadata:
try:
# might be better to reject non-ASCII keys
--- a/mercurial/obsutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/obsutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
@@ -19,7 +18,6 @@
encoding,
error,
phases,
- pycompat,
util,
)
from .utils import dateutil
@@ -58,7 +56,7 @@
usingsha256 = 2
-class marker(object):
+class marker:
"""Wrap obsolete marker raw data"""
def __init__(self, repo, data):
@@ -998,7 +996,7 @@
base[tuple(nsuccset)] = n
return [
{b'divergentnodes': divset, b'commonpredecessor': b}
- for divset, b in pycompat.iteritems(base)
+ for divset, b in base.items()
]
--- a/mercurial/parser.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/parser.py Fri Mar 25 11:33:12 2022 -0400
@@ -16,7 +16,6 @@
# an action is a tree node name, a tree label, and an optional match
# __call__(program) parses program into a labeled tree
-from __future__ import absolute_import, print_function
from .i18n import _
from . import (
@@ -26,7 +25,7 @@
from .utils import stringutil
-class parser(object):
+class parser:
def __init__(self, elements, methods=None):
self._elements = elements
self._methods = methods
@@ -416,7 +415,7 @@
return inst.message
-class alias(object):
+class alias:
"""Parsed result of alias"""
def __init__(self, name, args, err, replacement):
@@ -430,7 +429,7 @@
self.warned = False
-class basealiasrules(object):
+class basealiasrules:
"""Parsing and expansion rule set of aliases
This is a helper for fileset/revset/template aliases. A concrete rule set
--- a/mercurial/patch.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/patch.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import collections
import contextlib
@@ -150,7 +149,7 @@
def remainder(cur):
yield chunk(cur)
- class fiter(object):
+ class fiter:
def __init__(self, fp):
self.fp = fp
@@ -343,7 +342,7 @@
return data
-class patchmeta(object):
+class patchmeta:
"""Patched file metadata
'op' is the performed operation within ADD, DELETE, RENAME, MODIFY
@@ -436,7 +435,7 @@
return gitpatches
-class linereader(object):
+class linereader:
# simple class to allow pushing lines back into the input stream
def __init__(self, fp):
self.fp = fp
@@ -457,7 +456,7 @@
return iter(self.readline, b'')
-class abstractbackend(object):
+class abstractbackend:
def __init__(self, ui):
self.ui = ui
@@ -593,7 +592,7 @@
return sorted(self.changed)
-class filestore(object):
+class filestore:
def __init__(self, maxsize=None):
self.opener = None
self.files = {}
@@ -682,7 +681,7 @@
eolmodes = [b'strict', b'crlf', b'lf', b'auto']
-class patchfile(object):
+class patchfile:
def __init__(self, ui, gp, backend, store, eolmode=b'strict'):
self.fname = gp.path
self.eolmode = eolmode
@@ -915,7 +914,7 @@
return len(self.rej)
-class header(object):
+class header:
"""patch header"""
diffgit_re = re.compile(b'diff --git a/(.*) b/(.*)$')
@@ -995,7 +994,7 @@
)
-class recordhunk(object):
+class recordhunk:
"""patch hunk
XXX shouldn't we merge this with the other hunk class?
@@ -1260,7 +1259,7 @@
# Remove comment lines
patchfp = open(patchfn, 'rb')
ncpatchfp = stringio()
- for line in util.iterfile(patchfp):
+ for line in patchfp:
line = util.fromnativeeol(line)
if not line.startswith(b'#'):
ncpatchfp.write(line)
@@ -1343,18 +1342,14 @@
fixoffset += chunk.removed - chunk.added
return (
sum(
- [
- h
- for h in pycompat.itervalues(applied)
- if h[0].special() or len(h) > 1
- ],
+ [h for h in applied.values() if h[0].special() or len(h) > 1],
[],
),
{},
)
-class hunk(object):
+class hunk:
def __init__(self, desc, num, lr, context):
self.number = num
self.desc = desc
@@ -1582,7 +1577,7 @@
return old, oldstart, new, newstart
-class binhunk(object):
+class binhunk:
"""A binary patch file."""
def __init__(self, lr, fname):
@@ -1763,7 +1758,7 @@
+9
"""
- class parser(object):
+ class parser:
"""patch parsing state machine"""
def __init__(self):
@@ -2348,7 +2343,7 @@
ui.debug(b'Using external patch tool: %s\n' % cmd)
fp = procutil.popen(cmd, b'rb')
try:
- for line in util.iterfile(fp):
+ for line in fp:
line = line.rstrip()
ui.note(line + b'\n')
if line.startswith(b'patching file '):
@@ -2644,11 +2639,7 @@
if copysourcematch:
# filter out copies where source side isn't inside the matcher
# (copies.pathcopies() already filtered out the destination)
- copy = {
- dst: src
- for dst, src in pycompat.iteritems(copy)
- if copysourcematch(src)
- }
+ copy = {dst: src for dst, src in copy.items() if copysourcematch(src)}
modifiedset = set(modified)
addedset = set(added)
--- a/mercurial/pathutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pathutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import contextlib
import errno
import os
@@ -33,7 +31,7 @@
return encoding.hfsignoreclean(s.lower())
-class pathauditor(object):
+class pathauditor:
"""ensure that a filesystem path contains no banned components.
the following properties of a path are checked:
@@ -316,7 +314,7 @@
yield b''
-class dirs(object):
+class dirs:
'''a multiset of directory names from a set of file paths'''
def __init__(self, map, only_tracked=False):
@@ -326,7 +324,7 @@
self._dirs = {}
addpath = self.addpath
if isinstance(map, dict) and only_tracked:
- for f, s in pycompat.iteritems(map):
+ for f, s in map.items():
if s.state != b'r':
addpath(f)
elif only_tracked:
--- a/mercurial/phases.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/phases.py Fri Mar 25 11:33:12 2022 -0400
@@ -100,7 +100,6 @@
"""
-from __future__ import absolute_import
import errno
import struct
@@ -220,7 +219,7 @@
The revision lists are encoded as (phase, root) pairs.
"""
binarydata = []
- for phase, nodes in pycompat.iteritems(phasemapping):
+ for phase, nodes in phasemapping.items():
for head in nodes:
binarydata.append(_fphasesentry.pack(phase, head))
return b''.join(binarydata)
@@ -344,7 +343,7 @@
data.insert(low + 1, (pycompat.xrange(rev, rev + 1), t))
-class phasecache(object):
+class phasecache:
def __init__(self, repo, phasedefaults, _load=True):
# type: (localrepo.localrepository, Optional[Phasedefaults], bool) -> None
if _load:
@@ -364,9 +363,7 @@
self.invalidate()
self.loadphaserevs(repo)
return any(
- revs
- for phase, revs in pycompat.iteritems(self.phaseroots)
- if phase != public
+ revs for phase, revs in self.phaseroots.items() if phase != public
)
def nonpublicphaseroots(self, repo):
@@ -384,7 +381,7 @@
return set().union(
*[
revs
- for phase, revs in pycompat.iteritems(self.phaseroots)
+ for phase, revs in self.phaseroots.items()
if phase != public
]
)
@@ -529,7 +526,7 @@
f.close()
def _write(self, fp):
- for phase, roots in pycompat.iteritems(self.phaseroots):
+ for phase, roots in self.phaseroots.items():
for h in sorted(roots):
fp.write(b'%i %s\n' % (phase, hex(h)))
self.dirty = False
@@ -613,7 +610,7 @@
def retractboundary(self, repo, tr, targetphase, nodes):
oldroots = {
phase: revs
- for phase, revs in pycompat.iteritems(self.phaseroots)
+ for phase, revs in self.phaseroots.items()
if phase <= targetphase
}
if tr is None:
@@ -691,7 +688,7 @@
"""
filtered = False
has_node = repo.changelog.index.has_node # to filter unknown nodes
- for phase, nodes in pycompat.iteritems(self.phaseroots):
+ for phase, nodes in self.phaseroots.items():
missing = sorted(node for node in nodes if not has_node(node))
if missing:
for mnode in missing:
@@ -855,7 +852,7 @@
# build list from dictionary
draftroots = []
has_node = repo.changelog.index.has_node # to filter unknown nodes
- for nhex, phase in pycompat.iteritems(roots):
+ for nhex, phase in roots.items():
if nhex == b'publishing': # ignore data related to publish option
continue
node = bin(nhex)
@@ -882,7 +879,7 @@
return publicheads, draftroots
-class remotephasessummary(object):
+class remotephasessummary:
"""summarize phase information on the remote side
:publishing: True is the remote is publishing
--- a/mercurial/policy.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/policy.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
import sys
@@ -54,11 +53,8 @@
policy = b'cffi'
# Environment variable can always force settings.
-if sys.version_info[0] >= 3:
- if 'HGMODULEPOLICY' in os.environ:
- policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
-else:
- policy = os.environ.get('HGMODULEPOLICY', policy)
+if 'HGMODULEPOLICY' in os.environ:
+ policy = os.environ['HGMODULEPOLICY'].encode('utf-8')
def _importfrom(pkgname, modname):
--- a/mercurial/posix.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/posix.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import fcntl
@@ -60,21 +59,7 @@
umask = os.umask(0)
os.umask(umask)
-if not pycompat.ispy3:
-
- def posixfile(name, mode='r', buffering=-1):
- fp = open(name, mode=mode, buffering=buffering)
- # The position when opening in append mode is implementation defined, so
- # make it consistent by always seeking to the end.
- if 'a' in mode:
- fp.seek(0, os.SEEK_END)
- return fp
-
-
-else:
- # The underlying file object seeks as required in Python 3:
- # https://github.com/python/cpython/blob/v3.7.3/Modules/_io/fileio.c#L474
- posixfile = open
+posixfile = open
def split(p):
@@ -679,7 +664,7 @@
pass
-class cachestat(object):
+class cachestat:
def __init__(self, path):
self.stat = os.stat(path)
--- a/mercurial/profiling.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/profiling.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import contextlib
@@ -174,7 +173,7 @@
statprof.display(fp, data=data, format=displayformat, **kwargs)
-class profile(object):
+class profile:
"""Start profiling.
Profiling is active when the context manager is active. When the context
@@ -232,7 +231,7 @@
self._fp = open(path, b'wb')
elif pycompat.iswindows:
# parse escape sequence by win32print()
- class uifp(object):
+ class uifp:
def __init__(self, ui):
self._ui = ui
--- a/mercurial/progress.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/progress.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import threading
@@ -85,7 +84,7 @@
raise
-class progbar(object):
+class progbar:
def __init__(self, ui):
self.ui = ui
self._refreshlock = threading.Lock()
--- a/mercurial/pure/base85.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pure/base85.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import struct
--- a/mercurial/pure/bdiff.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pure/bdiff.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import difflib
import re
--- a/mercurial/pure/charencode.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pure/charencode.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import array
@@ -68,10 +67,7 @@
raise ValueError
-if pycompat.ispy3:
- _utf8strict = r'surrogatepass'
-else:
- _utf8strict = r'strict'
+_utf8strict = r'surrogatepass'
def jsonescapeu8fallback(u8chars, paranoid):
--- a/mercurial/pure/mpatch.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pure/mpatch.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,13 +5,12 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
+import io
import struct
-from .. import pycompat
-stringio = pycompat.bytesio
+stringio = io.BytesIO
class mpatchError(Exception):
--- a/mercurial/pure/osutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pure/osutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, division
import ctypes
import ctypes.util
@@ -221,7 +220,7 @@
err.errno, '%s: %s' % (encoding.strfromlocal(name), err.strerror)
)
- class posixfile(object):
+ class posixfile:
"""a file object aiming for POSIX-like semantics
CPython's open() returns a file that was opened *without* setting the
--- a/mercurial/pure/parsers.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pure/parsers.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,8 +5,8 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
+import io
import stat
import struct
import zlib
@@ -18,7 +18,6 @@
from ..thirdparty import attr
from .. import (
error,
- pycompat,
revlogutils,
util,
)
@@ -26,7 +25,7 @@
from ..revlogutils import nodemap as nodemaputil
from ..revlogutils import constants as revlog_constants
-stringio = pycompat.bytesio
+stringio = io.BytesIO
_pack = struct.pack
@@ -64,7 +63,7 @@
@attr.s(slots=True, init=False)
-class DirstateItem(object):
+class DirstateItem:
"""represent a dirstate entry
It hold multiple attributes
@@ -561,7 +560,7 @@
return int(q & 0xFFFF)
-class BaseIndexObject(object):
+class BaseIndexObject:
# Can I be passed to an algorithme implemented in Rust ?
rust_ext_compat = 0
# Format of an index entry according to Python's `struct` language
@@ -959,7 +958,7 @@
cs = stringio()
write = cs.write
write(b"".join(pl))
- for f, e in pycompat.iteritems(dmap):
+ for f, e in dmap.items():
if f in copymap:
f = b"%s\0%s" % (f, copymap[f])
e = _pack(
--- a/mercurial/pushkey.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pushkey.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from . import (
bookmarks,
--- a/mercurial/pvec.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pvec.py Fri Mar 25 11:33:12 2022 -0400
@@ -48,7 +48,6 @@
different branches
'''
-from __future__ import absolute_import
from .node import nullrev
from . import (
@@ -181,7 +180,7 @@
return pvec(util.b85encode(bs))
-class pvec(object):
+class pvec:
def __init__(self, hashorctx):
if isinstance(hashorctx, bytes):
self._bs = hashorctx
--- a/mercurial/pycompat.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/pycompat.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,15 +8,27 @@
This contains aliases to hide python version-specific details from the core.
"""
-from __future__ import absolute_import
+import builtins
+import codecs
+import concurrent.futures as futures
+import functools
import getopt
+import http.client as httplib
+import http.cookiejar as cookielib
import inspect
+import io
import json
import os
+import pickle
+import queue
import shlex
+import socketserver
+import struct
import sys
import tempfile
+import xmlrpc.client as xmlrpclib
+
ispy3 = sys.version_info[0] >= 3
ispypy = '__pypy__' in sys.builtin_module_names
@@ -27,36 +39,12 @@
TYPE_CHECKING = typing.TYPE_CHECKING
-if not ispy3:
- import cookielib
- import cPickle as pickle
- import httplib
- import Queue as queue
- import SocketServer as socketserver
- import xmlrpclib
-
- from .thirdparty.concurrent import futures
-
- def future_set_exception_info(f, exc_info):
- f.set_exception_info(*exc_info)
- # this is close enough for our usage
- FileNotFoundError = OSError
+def future_set_exception_info(f, exc_info):
+ f.set_exception(exc_info[0])
-else:
- import builtins
- import concurrent.futures as futures
- import http.cookiejar as cookielib
- import http.client as httplib
- import pickle
- import queue as queue
- import socketserver
- import xmlrpc.client as xmlrpclib
- def future_set_exception_info(f, exc_info):
- f.set_exception(exc_info[0])
-
- FileNotFoundError = builtins.FileNotFoundError
+FileNotFoundError = builtins.FileNotFoundError
def identity(a):
@@ -98,402 +86,297 @@
return _rapply(f, xs)
-if ispy3:
- import builtins
- import codecs
- import functools
- import io
- import struct
-
- if os.name == r'nt' and sys.version_info >= (3, 6):
- # MBCS (or ANSI) filesystem encoding must be used as before.
- # Otherwise non-ASCII filenames in existing repositories would be
- # corrupted.
- # This must be set once prior to any fsencode/fsdecode calls.
- sys._enablelegacywindowsfsencoding() # pytype: disable=module-attr
+if os.name == r'nt':
+ # MBCS (or ANSI) filesystem encoding must be used as before.
+ # Otherwise non-ASCII filenames in existing repositories would be
+ # corrupted.
+ # This must be set once prior to any fsencode/fsdecode calls.
+ sys._enablelegacywindowsfsencoding() # pytype: disable=module-attr
- fsencode = os.fsencode
- fsdecode = os.fsdecode
- oscurdir = os.curdir.encode('ascii')
- oslinesep = os.linesep.encode('ascii')
- osname = os.name.encode('ascii')
- ospathsep = os.pathsep.encode('ascii')
- ospardir = os.pardir.encode('ascii')
- ossep = os.sep.encode('ascii')
- osaltsep = os.altsep
- if osaltsep:
- osaltsep = osaltsep.encode('ascii')
- osdevnull = os.devnull.encode('ascii')
+fsencode = os.fsencode
+fsdecode = os.fsdecode
+oscurdir = os.curdir.encode('ascii')
+oslinesep = os.linesep.encode('ascii')
+osname = os.name.encode('ascii')
+ospathsep = os.pathsep.encode('ascii')
+ospardir = os.pardir.encode('ascii')
+ossep = os.sep.encode('ascii')
+osaltsep = os.altsep
+if osaltsep:
+ osaltsep = osaltsep.encode('ascii')
+osdevnull = os.devnull.encode('ascii')
- sysplatform = sys.platform.encode('ascii')
- sysexecutable = sys.executable
- if sysexecutable:
- sysexecutable = os.fsencode(sysexecutable)
- bytesio = io.BytesIO
- # TODO deprecate stringio name, as it is a lie on Python 3.
- stringio = bytesio
+sysplatform = sys.platform.encode('ascii')
+sysexecutable = sys.executable
+if sysexecutable:
+ sysexecutable = os.fsencode(sysexecutable)
+
- def maplist(*args):
- return list(map(*args))
+def maplist(*args):
+ return list(map(*args))
+
- def rangelist(*args):
- return list(range(*args))
+def rangelist(*args):
+ return list(range(*args))
+
- def ziplist(*args):
- return list(zip(*args))
+def ziplist(*args):
+ return list(zip(*args))
+
- rawinput = input
- getargspec = inspect.getfullargspec
+rawinput = input
+getargspec = inspect.getfullargspec
- long = int
+long = int
- if getattr(sys, 'argv', None) is not None:
- # On POSIX, the char** argv array is converted to Python str using
- # Py_DecodeLocale(). The inverse of this is Py_EncodeLocale(), which
- # isn't directly callable from Python code. In practice, os.fsencode()
- # can be used instead (this is recommended by Python's documentation
- # for sys.argv).
- #
- # On Windows, the wchar_t **argv is passed into the interpreter as-is.
- # Like POSIX, we need to emulate what Py_EncodeLocale() would do. But
- # there's an additional wrinkle. What we really want to access is the
- # ANSI codepage representation of the arguments, as this is what
- # `int main()` would receive if Python 3 didn't define `int wmain()`
- # (this is how Python 2 worked). To get that, we encode with the mbcs
- # encoding, which will pass CP_ACP to the underlying Windows API to
- # produce bytes.
- if os.name == r'nt':
- sysargv = [a.encode("mbcs", "ignore") for a in sys.argv]
- else:
- sysargv = [fsencode(a) for a in sys.argv]
+if getattr(sys, 'argv', None) is not None:
+ # On POSIX, the char** argv array is converted to Python str using
+ # Py_DecodeLocale(). The inverse of this is Py_EncodeLocale(), which
+ # isn't directly callable from Python code. In practice, os.fsencode()
+ # can be used instead (this is recommended by Python's documentation
+ # for sys.argv).
+ #
+ # On Windows, the wchar_t **argv is passed into the interpreter as-is.
+ # Like POSIX, we need to emulate what Py_EncodeLocale() would do. But
+ # there's an additional wrinkle. What we really want to access is the
+ # ANSI codepage representation of the arguments, as this is what
+ # `int main()` would receive if Python 3 didn't define `int wmain()`
+ # (this is how Python 2 worked). To get that, we encode with the mbcs
+ # encoding, which will pass CP_ACP to the underlying Windows API to
+ # produce bytes.
+ if os.name == r'nt':
+ sysargv = [a.encode("mbcs", "ignore") for a in sys.argv]
+ else:
+ sysargv = [fsencode(a) for a in sys.argv]
- bytechr = struct.Struct('>B').pack
- byterepr = b'%r'.__mod__
-
- class bytestr(bytes):
- """A bytes which mostly acts as a Python 2 str
+bytechr = struct.Struct('>B').pack
+byterepr = b'%r'.__mod__
- >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
- ('', 'foo', 'ascii', '1')
- >>> s = bytestr(b'foo')
- >>> assert s is bytestr(s)
- __bytes__() should be called if provided:
+class bytestr(bytes):
+ """A bytes which mostly acts as a Python 2 str
- >>> class bytesable(object):
- ... def __bytes__(self):
- ... return b'bytes'
- >>> bytestr(bytesable())
- 'bytes'
+ >>> bytestr(), bytestr(bytearray(b'foo')), bytestr(u'ascii'), bytestr(1)
+ ('', 'foo', 'ascii', '1')
+ >>> s = bytestr(b'foo')
+ >>> assert s is bytestr(s)
+
+ __bytes__() should be called if provided:
- There's no implicit conversion from non-ascii str as its encoding is
- unknown:
+ >>> class bytesable:
+ ... def __bytes__(self):
+ ... return b'bytes'
+ >>> bytestr(bytesable())
+ 'bytes'
- >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
- Traceback (most recent call last):
- ...
- UnicodeEncodeError: ...
-
- Comparison between bytestr and bytes should work:
+ There's no implicit conversion from non-ascii str as its encoding is
+ unknown:
- >>> assert bytestr(b'foo') == b'foo'
- >>> assert b'foo' == bytestr(b'foo')
- >>> assert b'f' in bytestr(b'foo')
- >>> assert bytestr(b'f') in b'foo'
+ >>> bytestr(chr(0x80)) # doctest: +ELLIPSIS
+ Traceback (most recent call last):
+ ...
+ UnicodeEncodeError: ...
- Sliced elements should be bytes, not integer:
+ Comparison between bytestr and bytes should work:
- >>> s[1], s[:2]
- (b'o', b'fo')
- >>> list(s), list(reversed(s))
- ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
-
- As bytestr type isn't propagated across operations, you need to cast
- bytes to bytestr explicitly:
+ >>> assert bytestr(b'foo') == b'foo'
+ >>> assert b'foo' == bytestr(b'foo')
+ >>> assert b'f' in bytestr(b'foo')
+ >>> assert bytestr(b'f') in b'foo'
- >>> s = bytestr(b'foo').upper()
- >>> t = bytestr(s)
- >>> s[0], t[0]
- (70, b'F')
+ Sliced elements should be bytes, not integer:
- Be careful to not pass a bytestr object to a function which expects
- bytearray-like behavior.
+ >>> s[1], s[:2]
+ (b'o', b'fo')
+ >>> list(s), list(reversed(s))
+ ([b'f', b'o', b'o'], [b'o', b'o', b'f'])
- >>> t = bytes(t) # cast to bytes
- >>> assert type(t) is bytes
- """
+ As bytestr type isn't propagated across operations, you need to cast
+ bytes to bytestr explicitly:
- # Trick pytype into not demanding Iterable[int] be passed to __new__(),
- # since the appropriate bytes format is done internally.
- #
- # https://github.com/google/pytype/issues/500
- if TYPE_CHECKING:
+ >>> s = bytestr(b'foo').upper()
+ >>> t = bytestr(s)
+ >>> s[0], t[0]
+ (70, b'F')
- def __init__(self, s=b''):
- pass
+ Be careful to not pass a bytestr object to a function which expects
+ bytearray-like behavior.
+
+ >>> t = bytes(t) # cast to bytes
+ >>> assert type(t) is bytes
+ """
- def __new__(cls, s=b''):
- if isinstance(s, bytestr):
- return s
- if not isinstance(
- s, (bytes, bytearray)
- ) and not hasattr( # hasattr-py3-only
- s, u'__bytes__'
- ):
- s = str(s).encode('ascii')
- return bytes.__new__(cls, s)
+ # Trick pytype into not demanding Iterable[int] be passed to __new__(),
+ # since the appropriate bytes format is done internally.
+ #
+ # https://github.com/google/pytype/issues/500
+ if TYPE_CHECKING:
- def __getitem__(self, key):
- s = bytes.__getitem__(self, key)
- if not isinstance(s, bytes):
- s = bytechr(s)
+ def __init__(self, s=b''):
+ pass
+
+ def __new__(cls, s=b''):
+ if isinstance(s, bytestr):
return s
-
- def __iter__(self):
- return iterbytestr(bytes.__iter__(self))
-
- def __repr__(self):
- return bytes.__repr__(self)[1:] # drop b''
+ if not isinstance(
+ s, (bytes, bytearray)
+ ) and not hasattr( # hasattr-py3-only
+ s, u'__bytes__'
+ ):
+ s = str(s).encode('ascii')
+ return bytes.__new__(cls, s)
- def iterbytestr(s):
- """Iterate bytes as if it were a str object of Python 2"""
- return map(bytechr, s)
-
- def maybebytestr(s):
- """Promote bytes to bytestr"""
- if isinstance(s, bytes):
- return bytestr(s)
+ def __getitem__(self, key):
+ s = bytes.__getitem__(self, key)
+ if not isinstance(s, bytes):
+ s = bytechr(s)
return s
- def sysbytes(s):
- """Convert an internal str (e.g. keyword, __doc__) back to bytes
+ def __iter__(self):
+ return iterbytestr(bytes.__iter__(self))
- This never raises UnicodeEncodeError, but only ASCII characters
- can be round-trip by sysstr(sysbytes(s)).
- """
- if isinstance(s, bytes):
- return s
- return s.encode('utf-8')
+ def __repr__(self):
+ return bytes.__repr__(self)[1:] # drop b''
- def sysstr(s):
- """Return a keyword str to be passed to Python functions such as
- getattr() and str.encode()
- This never raises UnicodeDecodeError. Non-ascii characters are
- considered invalid and mapped to arbitrary but unique code points
- such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
- """
- if isinstance(s, builtins.str):
- return s
- return s.decode('latin-1')
+def iterbytestr(s):
+ """Iterate bytes as if it were a str object of Python 2"""
+ return map(bytechr, s)
+
- def strurl(url):
- """Converts a bytes url back to str"""
- if isinstance(url, bytes):
- return url.decode('ascii')
- return url
+def maybebytestr(s):
+ """Promote bytes to bytestr"""
+ if isinstance(s, bytes):
+ return bytestr(s)
+ return s
- def bytesurl(url):
- """Converts a str url to bytes by encoding in ascii"""
- if isinstance(url, str):
- return url.encode('ascii')
- return url
+
+def sysbytes(s):
+ """Convert an internal str (e.g. keyword, __doc__) back to bytes
- def raisewithtb(exc, tb):
- """Raise exception with the given traceback"""
- raise exc.with_traceback(tb)
+ This never raises UnicodeEncodeError, but only ASCII characters
+ can be round-trip by sysstr(sysbytes(s)).
+ """
+ if isinstance(s, bytes):
+ return s
+ return s.encode('utf-8')
- def getdoc(obj):
- """Get docstring as bytes; may be None so gettext() won't confuse it
- with _('')"""
- doc = getattr(obj, '__doc__', None)
- if doc is None:
- return doc
- return sysbytes(doc)
- def _wrapattrfunc(f):
- @functools.wraps(f)
- def w(object, name, *args):
- return f(object, sysstr(name), *args)
-
- return w
+def sysstr(s):
+ """Return a keyword str to be passed to Python functions such as
+ getattr() and str.encode()
- # these wrappers are automagically imported by hgloader
- delattr = _wrapattrfunc(builtins.delattr)
- getattr = _wrapattrfunc(builtins.getattr)
- hasattr = _wrapattrfunc(builtins.hasattr)
- setattr = _wrapattrfunc(builtins.setattr)
- xrange = builtins.range
- unicode = str
-
- def open(name, mode=b'r', buffering=-1, encoding=None):
- return builtins.open(name, sysstr(mode), buffering, encoding)
-
- safehasattr = _wrapattrfunc(builtins.hasattr)
+ This never raises UnicodeDecodeError. Non-ascii characters are
+ considered invalid and mapped to arbitrary but unique code points
+ such that 'sysstr(a) != sysstr(b)' for all 'a != b'.
+ """
+ if isinstance(s, builtins.str):
+ return s
+ return s.decode('latin-1')
- def _getoptbwrapper(orig, args, shortlist, namelist):
- """
- Takes bytes arguments, converts them to unicode, pass them to
- getopt.getopt(), convert the returned values back to bytes and then
- return them for Python 3 compatibility as getopt.getopt() don't accepts
- bytes on Python 3.
- """
- args = [a.decode('latin-1') for a in args]
- shortlist = shortlist.decode('latin-1')
- namelist = [a.decode('latin-1') for a in namelist]
- opts, args = orig(args, shortlist, namelist)
- opts = [(a[0].encode('latin-1'), a[1].encode('latin-1')) for a in opts]
- args = [a.encode('latin-1') for a in args]
- return opts, args
+
+def strurl(url):
+ """Converts a bytes url back to str"""
+ if isinstance(url, bytes):
+ return url.decode('ascii')
+ return url
+
- def strkwargs(dic):
- """
- Converts the keys of a python dictonary to str i.e. unicodes so that
- they can be passed as keyword arguments as dictionaries with bytes keys
- can't be passed as keyword arguments to functions on Python 3.
- """
- dic = {k.decode('latin-1'): v for k, v in dic.items()}
- return dic
+def bytesurl(url):
+ """Converts a str url to bytes by encoding in ascii"""
+ if isinstance(url, str):
+ return url.encode('ascii')
+ return url
- def byteskwargs(dic):
- """
- Converts keys of python dictionaries to bytes as they were converted to
- str to pass that dictonary as a keyword argument on Python 3.
- """
- dic = {k.encode('latin-1'): v for k, v in dic.items()}
- return dic
- # TODO: handle shlex.shlex().
- def shlexsplit(s, comments=False, posix=True):
- """
- Takes bytes argument, convert it to str i.e. unicodes, pass that into
- shlex.split(), convert the returned value to bytes and return that for
- Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
- """
- ret = shlex.split(s.decode('latin-1'), comments, posix)
- return [a.encode('latin-1') for a in ret]
+def raisewithtb(exc, tb):
+ """Raise exception with the given traceback"""
+ raise exc.with_traceback(tb)
+
- iteritems = lambda x: x.items()
- itervalues = lambda x: x.values()
+def getdoc(obj):
+ """Get docstring as bytes; may be None so gettext() won't confuse it
+ with _('')"""
+ doc = getattr(obj, '__doc__', None)
+ if doc is None:
+ return doc
+ return sysbytes(doc)
- # Python 3.5's json.load and json.loads require str. We polyfill its
- # code for detecting encoding from bytes.
- if sys.version_info[0:2] < (3, 6):
- def _detect_encoding(b):
- bstartswith = b.startswith
- if bstartswith((codecs.BOM_UTF32_BE, codecs.BOM_UTF32_LE)):
- return 'utf-32'
- if bstartswith((codecs.BOM_UTF16_BE, codecs.BOM_UTF16_LE)):
- return 'utf-16'
- if bstartswith(codecs.BOM_UTF8):
- return 'utf-8-sig'
+def _wrapattrfunc(f):
+ @functools.wraps(f)
+ def w(object, name, *args):
+ return f(object, sysstr(name), *args)
+
+ return w
+
- if len(b) >= 4:
- if not b[0]:
- # 00 00 -- -- - utf-32-be
- # 00 XX -- -- - utf-16-be
- return 'utf-16-be' if b[1] else 'utf-32-be'
- if not b[1]:
- # XX 00 00 00 - utf-32-le
- # XX 00 00 XX - utf-16-le
- # XX 00 XX -- - utf-16-le
- return 'utf-16-le' if b[2] or b[3] else 'utf-32-le'
- elif len(b) == 2:
- if not b[0]:
- # 00 XX - utf-16-be
- return 'utf-16-be'
- if not b[1]:
- # XX 00 - utf-16-le
- return 'utf-16-le'
- # default
- return 'utf-8'
+# these wrappers are automagically imported by hgloader
+delattr = _wrapattrfunc(builtins.delattr)
+getattr = _wrapattrfunc(builtins.getattr)
+hasattr = _wrapattrfunc(builtins.hasattr)
+setattr = _wrapattrfunc(builtins.setattr)
+xrange = builtins.range
+unicode = str
- def json_loads(s, *args, **kwargs):
- if isinstance(s, (bytes, bytearray)):
- s = s.decode(_detect_encoding(s), 'surrogatepass')
- return json.loads(s, *args, **kwargs)
+def open(name, mode=b'r', buffering=-1, encoding=None):
+ return builtins.open(name, sysstr(mode), buffering, encoding)
- else:
- json_loads = json.loads
-else:
- import cStringIO
+safehasattr = _wrapattrfunc(builtins.hasattr)
+
- xrange = xrange
- unicode = unicode
- bytechr = chr
- byterepr = repr
- bytestr = str
- iterbytestr = iter
- maybebytestr = identity
- sysbytes = identity
- sysstr = identity
- strurl = identity
- bytesurl = identity
- open = open
- delattr = delattr
- getattr = getattr
- hasattr = hasattr
- setattr = setattr
+def _getoptbwrapper(orig, args, shortlist, namelist):
+ """
+ Takes bytes arguments, converts them to unicode, pass them to
+ getopt.getopt(), convert the returned values back to bytes and then
+ return them for Python 3 compatibility as getopt.getopt() don't accepts
+ bytes on Python 3.
+ """
+ args = [a.decode('latin-1') for a in args]
+ shortlist = shortlist.decode('latin-1')
+ namelist = [a.decode('latin-1') for a in namelist]
+ opts, args = orig(args, shortlist, namelist)
+ opts = [(a[0].encode('latin-1'), a[1].encode('latin-1')) for a in opts]
+ args = [a.encode('latin-1') for a in args]
+ return opts, args
- # this can't be parsed on Python 3
- exec(b'def raisewithtb(exc, tb):\n raise exc, None, tb\n')
- def fsencode(filename):
- """
- Partial backport from os.py in Python 3, which only accepts bytes.
- In Python 2, our paths should only ever be bytes, a unicode path
- indicates a bug.
- """
- if isinstance(filename, str):
- return filename
- else:
- raise TypeError("expect str, not %s" % type(filename).__name__)
-
- # In Python 2, fsdecode() has a very chance to receive bytes. So it's
- # better not to touch Python 2 part as it's already working fine.
- fsdecode = identity
+def strkwargs(dic):
+ """
+ Converts the keys of a python dictonary to str i.e. unicodes so that
+ they can be passed as keyword arguments as dictionaries with bytes keys
+ can't be passed as keyword arguments to functions on Python 3.
+ """
+ dic = {k.decode('latin-1'): v for k, v in dic.items()}
+ return dic
- def getdoc(obj):
- return getattr(obj, '__doc__', None)
-
- _notset = object()
- def safehasattr(thing, attr):
- return getattr(thing, attr, _notset) is not _notset
+def byteskwargs(dic):
+ """
+ Converts keys of python dictionaries to bytes as they were converted to
+ str to pass that dictonary as a keyword argument on Python 3.
+ """
+ dic = {k.encode('latin-1'): v for k, v in dic.items()}
+ return dic
- def _getoptbwrapper(orig, args, shortlist, namelist):
- return orig(args, shortlist, namelist)
-
- strkwargs = identity
- byteskwargs = identity
- oscurdir = os.curdir
- oslinesep = os.linesep
- osname = os.name
- ospathsep = os.pathsep
- ospardir = os.pardir
- ossep = os.sep
- osaltsep = os.altsep
- osdevnull = os.devnull
- long = long
- if getattr(sys, 'argv', None) is not None:
- sysargv = sys.argv
- sysplatform = sys.platform
- sysexecutable = sys.executable
- shlexsplit = shlex.split
- bytesio = cStringIO.StringIO
- stringio = bytesio
- maplist = map
- rangelist = range
- ziplist = zip
- rawinput = raw_input
- getargspec = inspect.getargspec
- iteritems = lambda x: x.iteritems()
- itervalues = lambda x: x.itervalues()
- json_loads = json.loads
+# TODO: handle shlex.shlex().
+def shlexsplit(s, comments=False, posix=True):
+ """
+ Takes bytes argument, convert it to str i.e. unicodes, pass that into
+ shlex.split(), convert the returned value to bytes and return that for
+ Python 3 compatibility as shelx.split() don't accept bytes on Python 3.
+ """
+ ret = shlex.split(s.decode('latin-1'), comments, posix)
+ return [a.encode('latin-1') for a in ret]
+
+
+iteritems = lambda x: x.items()
+itervalues = lambda x: x.values()
+
+json_loads = json.loads
isjython = sysplatform.startswith(b'java')
--- a/mercurial/rcutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/rcutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
--- a/mercurial/registrar.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/registrar.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from . import (
configitems,
@@ -22,7 +21,7 @@
configitem = configitems.getitemregister
-class _funcregistrarbase(object):
+class _funcregistrarbase:
"""Base of decorator to register a function for specific purpose
This decorator stores decorated functions into own dict 'table'.
--- a/mercurial/repair.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/repair.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
@@ -380,7 +379,7 @@
return [c.node() for c in repo.set(b'roots(%ld)', tostrip)]
-class stripcallback(object):
+class stripcallback:
"""used as a transaction postclose callback"""
def __init__(self, ui, repo, backup, topic):
--- a/mercurial/repocache.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/repocache.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import gc
@@ -20,7 +19,7 @@
)
-class repoloader(object):
+class repoloader:
"""Load repositories in background thread
This is designed for a forking server. A cached repo cannot be obtained
--- a/mercurial/repoview.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/repoview.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import copy
import weakref
@@ -262,7 +261,7 @@
return cl
-class filteredchangelogmixin(object):
+class filteredchangelogmixin:
def tiprev(self):
"""filtered version of revlog.tiprev"""
for i in pycompat.xrange(len(self) - 1, -2, -1):
@@ -362,7 +361,7 @@
return super(filteredchangelogmixin, self).flags(rev)
-class repoview(object):
+class repoview:
"""Provide a read/write view of a repo through a filtered changelog
This object is used to access a filtered version of a repository without
--- a/mercurial/requirements.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/requirements.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
# obsolete experimental requirements:
# - manifestv2: An experimental new manifest format that allowed
--- a/mercurial/revlog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlog.py Fri Mar 25 11:33:12 2022 -0400
@@ -12,7 +12,6 @@
and O(changes) merge between branches.
"""
-from __future__ import absolute_import
import binascii
import collections
@@ -172,7 +171,7 @@
@interfaceutil.implementer(repository.irevisiondelta)
@attr.s(slots=True)
-class revlogrevisiondelta(object):
+class revlogrevisiondelta:
node = attr.ib()
p1node = attr.ib()
p2node = attr.ib()
@@ -188,7 +187,7 @@
@interfaceutil.implementer(repository.iverifyproblem)
@attr.s(frozen=True)
-class revlogproblem(object):
+class revlogproblem:
warning = attr.ib(default=None)
error = attr.ib(default=None)
node = attr.ib(default=None)
@@ -238,7 +237,7 @@
)
-class revlog(object):
+class revlog:
"""
the underlying revision storage object
@@ -438,9 +437,7 @@
self._flagprocessors[REVIDX_ELLIPSIS] = ellipsisprocessor
# revlog v0 doesn't have flag processors
- for flag, processor in pycompat.iteritems(
- opts.get(b'flagprocessors', {})
- ):
+ for flag, processor in opts.get(b'flagprocessors', {}).items():
flagutil.insertflagprocessor(flag, processor, self._flagprocessors)
if self._chunkcachesize <= 0:
@@ -869,8 +866,10 @@
the revlog which do not persist the rank.
"""
rank = self.index[rev][ENTRY_RANK]
- if rank == RANK_UNKNOWN:
+ if self._format_version != CHANGELOGV2 or rank == RANK_UNKNOWN:
return None
+ if rev == nullrev:
+ return 0 # convention
return rank
def chainbase(self, rev):
@@ -1043,7 +1042,7 @@
heads = [self.rev(n) for n in heads]
# we want the ancestors, but inclusive
- class lazyset(object):
+ class lazyset:
def __init__(self, lazyvalues):
self.addedvalues = set()
self.lazyvalues = lazyvalues
@@ -1304,7 +1303,7 @@
# But, obviously its parents aren't.
for p in self.parents(n):
heads.pop(p, None)
- heads = [head for head, flag in pycompat.iteritems(heads) if flag]
+ heads = [head for head, flag in heads.items() if flag]
roots = list(roots)
assert orderedout
assert roots
@@ -2469,9 +2468,12 @@
elif p1r == nullrev and p2r != nullrev:
rank = 1 + self.fast_rank(p2r)
else: # merge node
- pmin, pmax = sorted((p1r, p2r))
- rank = 1 + self.fast_rank(pmax)
- rank += sum(1 for _ in self.findmissingrevs([pmax], [pmin]))
+ if rustdagop is not None and self.index.rust_ext_compat:
+ rank = rustdagop.rank(self.index, p1r, p2r)
+ else:
+ pmin, pmax = sorted((p1r, p2r))
+ rank = 1 + self.fast_rank(pmax)
+ rank += sum(1 for _ in self.findmissingrevs([pmax], [pmin]))
e = revlogutils.entry(
flags=flags,
--- a/mercurial/revlogutils/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from ..thirdparty import attr
from ..interfaces import repository
@@ -63,7 +62,7 @@
@attr.s(slots=True, frozen=True)
-class revisioninfo(object):
+class revisioninfo:
"""Information about a revision that allows building its fulltext
node: expected hash of the revision
p1, p2: parent revs of the revision
--- a/mercurial/revlogutils/constants.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/constants.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
"""Helper class to compute deltas stored inside revlogs"""
-from __future__ import absolute_import
import struct
--- a/mercurial/revlogutils/deltas.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/deltas.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# GNU General Public License version 2 or any later version.
"""Helper class to compute deltas stored inside revlogs"""
-from __future__ import absolute_import
import collections
import struct
@@ -39,7 +38,7 @@
LIMIT_DELTA2TEXT = 2
-class _testrevlog(object):
+class _testrevlog:
"""minimalist fake revlog to use in doctests"""
def __init__(self, data, density=0.5, mingap=0, snapshot=()):
@@ -545,7 +544,7 @@
@attr.s(slots=True, frozen=True)
-class _deltainfo(object):
+class _deltainfo:
distance = attr.ib()
deltalen = attr.ib()
data = attr.ib()
@@ -928,7 +927,7 @@
yield (prev,)
-class deltacomputer(object):
+class deltacomputer:
def __init__(self, revlog):
self.revlog = revlog
--- a/mercurial/revlogutils/docket.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/docket.py Fri Mar 25 11:33:12 2022 -0400
@@ -15,7 +15,6 @@
#
# * a data file, containing variable width data for these revisions,
-from __future__ import absolute_import
import errno
import os
@@ -26,7 +25,6 @@
encoding,
error,
node,
- pycompat,
util,
)
@@ -57,12 +55,7 @@
if inst.errno != errno.ENOENT:
raise
seed = b'04' # chosen by a fair dice roll. garanteed to be random
- if pycompat.ispy3:
- iter_seed = iter(seed)
- else:
- # pytype: disable=wrong-arg-types
- iter_seed = (ord(c) for c in seed)
- # pytype: enable=wrong-arg-types
+ iter_seed = iter(seed)
# some basic circular sum hashing on 64 bits
int_seed = 0
low_mask = int('1' * 35, 2)
@@ -71,10 +64,7 @@
low_part = (int_seed & low_mask) << 28
int_seed = high_part + low_part + i
r = random.Random()
- if pycompat.ispy3:
- r.seed(int_seed, version=1)
- else:
- r.seed(int_seed)
+ r.seed(int_seed, version=1)
# once we drop python 3.8 support we can simply use r.randbytes
raw = r.getrandbits(id_size * 4)
assert id_size == 8
@@ -109,7 +99,7 @@
S_OLD_UID = struct.Struct('>BL')
-class RevlogDocket(object):
+class RevlogDocket:
"""metadata associated with revlog"""
def __init__(
--- a/mercurial/revlogutils/flagutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/flagutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from ..i18n import _
--- a/mercurial/revlogutils/nodemap.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/nodemap.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import re
@@ -114,7 +113,7 @@
tr.addfinalize(callback_id, lambda tr: persist_nodemap(tr, revlog))
-class _NoTransaction(object):
+class _NoTransaction:
"""transaction like object to update the nodemap outside a transaction"""
def __init__(self):
@@ -305,7 +304,7 @@
S_HEADER = struct.Struct(">BQQQQ")
-class NodeMapDocket(object):
+class NodeMapDocket:
"""metadata associated with persistent nodemap data
The persistent data may come from disk or be on their way to disk.
--- a/mercurial/revlogutils/randomaccessfile.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/randomaccessfile.py Fri Mar 25 11:33:12 2022 -0400
@@ -23,7 +23,7 @@
return (n & (n - 1) == 0) and n != 0
-class randomaccessfile(object):
+class randomaccessfile:
"""Accessing arbitrary chuncks of data within a file, with some caching"""
def __init__(
--- a/mercurial/revlogutils/revlogv0.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/revlogv0.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from ..node import sha1nodeconstants
--- a/mercurial/revlogutils/sidedata.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revlogutils/sidedata.py Fri Mar 25 11:33:12 2022 -0400
@@ -30,7 +30,6 @@
the concept.
"""
-from __future__ import absolute_import
import collections
import struct
--- a/mercurial/revset.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revset.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
@@ -595,7 +594,7 @@
bms.add(repo[bmrev].rev())
else:
matchrevs = set()
- for name, bmrev in pycompat.iteritems(repo._bookmarks):
+ for name, bmrev in repo._bookmarks.items():
if matcher(name):
matchrevs.add(bmrev)
for bmrev in matchrevs:
@@ -1707,7 +1706,7 @@
)
namespaces.add(repo.names[pattern])
else:
- for name, ns in pycompat.iteritems(repo.names):
+ for name, ns in repo.names.items():
if matcher(name):
namespaces.add(ns)
@@ -2804,7 +2803,7 @@
def loadpredicate(ui, extname, registrarobj):
"""Load revset predicates from specified registrarobj"""
- for name, func in pycompat.iteritems(registrarobj._table):
+ for name, func in registrarobj._table.items():
symbols[name] = func
if func._safe:
safesymbols.add(name)
--- a/mercurial/revsetlang.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/revsetlang.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import string
@@ -613,7 +612,7 @@
tree = _aliasrules.expand(aliases, tree)
# warn about problematic (but not referred) aliases
if warn is not None:
- for name, alias in sorted(pycompat.iteritems(aliases)):
+ for name, alias in sorted(aliases.items()):
if alias.error and not alias.warned:
warn(_(b'warning: %s\n') % (alias.error))
alias.warned = True
--- a/mercurial/rewriteutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/rewriteutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
--- a/mercurial/scmposix.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/scmposix.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import array
import errno
import fcntl
--- a/mercurial/scmutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/scmutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import glob
@@ -63,7 +62,7 @@
@attr.s(slots=True, repr=False)
-class status(object):
+class status:
"""Struct with a list of files per status.
The 'deleted', 'unknown' and 'ignored' properties are only
@@ -109,7 +108,7 @@
del subpaths[subpath]
missing.add(subpath)
- for subpath, ctx in sorted(pycompat.iteritems(subpaths)):
+ for subpath, ctx in sorted(subpaths.items()):
yield subpath, ctx.sub(subpath)
# Yield an empty subrepo based on ctx1 for anything only in ctx2. That way,
@@ -228,7 +227,7 @@
except (AttributeError, IndexError):
# it might be anything, for example a string
reason = inst.reason
- if isinstance(reason, pycompat.unicode):
+ if isinstance(reason, str):
# SSLError of Python 2.7.9 contains a unicode
reason = encoding.unitolocal(reason)
ui.error(_(b"abort: error: %s\n") % stringutil.forcebytestr(reason))
@@ -324,7 +323,7 @@
return abort, warn
-class casecollisionauditor(object):
+class casecollisionauditor:
def __init__(self, ui, abort, dirstate):
self._ui = ui
self._abort = abort
@@ -1020,7 +1019,7 @@
return origvfs.join(filepath)
-class _containsnode(object):
+class _containsnode:
"""proxy __contains__(node) to container.__contains__ which accepts revs"""
def __init__(self, repo, revcontainer):
@@ -1337,7 +1336,7 @@
ignored=False,
full=False,
)
- for abs, st in pycompat.iteritems(walkresults):
+ for abs, st in walkresults.items():
entry = dirstate.get_entry(abs)
if (not entry.any_tracked) and audit_path.check(abs):
unknown.append(abs)
@@ -1384,7 +1383,7 @@
with repo.wlock():
wctx.forget(deleted)
wctx.add(unknown)
- for new, old in pycompat.iteritems(renames):
+ for new, old in renames.items():
wctx.copy(old, new)
@@ -1510,12 +1509,9 @@
# Merge old parent and old working dir copies
oldcopies = copiesmod.pathcopies(newctx, oldctx, match)
oldcopies.update(copies)
- copies = {
- dst: oldcopies.get(src, src)
- for dst, src in pycompat.iteritems(oldcopies)
- }
+ copies = {dst: oldcopies.get(src, src) for dst, src in oldcopies.items()}
# Adjust the dirstate copies
- for dst, src in pycompat.iteritems(copies):
+ for dst, src in copies.items():
if src not in newctx or dst in newctx or not ds.get_entry(dst).added:
src = None
ds.copy(src, dst)
@@ -1571,7 +1567,7 @@
fp.write(b"%s\n" % r)
-class filecachesubentry(object):
+class filecachesubentry:
def __init__(self, path, stat):
self.path = path
self.cachestat = None
@@ -1627,7 +1623,7 @@
raise
-class filecacheentry(object):
+class filecacheentry:
def __init__(self, paths, stat=True):
self._entries = []
for path in paths:
@@ -1645,7 +1641,7 @@
entry.refresh()
-class filecache(object):
+class filecache:
"""A property like decorator that tracks files under .hg/ for updates.
On first access, the files defined as arguments are stat()ed and the
@@ -1802,7 +1798,7 @@
return data
-class progress(object):
+class progress:
def __init__(self, ui, updatebar, topic, unit=b"", total=None):
self.ui = ui
self.pos = 0
@@ -1867,7 +1863,7 @@
return ui.configbool(b'format', b'generaldelta')
-class simplekeyvaluefile(object):
+class simplekeyvaluefile:
"""A simple file with key=value lines
Keys must be alphanumerics and start with a letter, values must not
--- a/mercurial/scmwindows.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/scmwindows.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import os
from . import (
--- a/mercurial/server.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/server.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
--- a/mercurial/setdiscovery.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/setdiscovery.py Fri Mar 25 11:33:12 2022 -0400
@@ -40,7 +40,6 @@
classified with it (since all ancestors or descendants will be marked as well).
"""
-from __future__ import absolute_import
import collections
import random
@@ -107,7 +106,7 @@
return set(sample[:desiredlen])
-class partialdiscovery(object):
+class partialdiscovery:
"""an object representing ongoing discovery
Feed with data from the remote repository, this object keep track of the
--- a/mercurial/shelve.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/shelve.py Fri Mar 25 11:33:12 2022 -0400
@@ -20,7 +20,6 @@
shelved change has a distinct name. For details, see the help for "hg
shelve".
"""
-from __future__ import absolute_import
import collections
import errno
@@ -69,7 +68,7 @@
shelveuser = b'shelve@localhost'
-class ShelfDir(object):
+class ShelfDir:
def __init__(self, repo, for_backups=False):
if for_backups:
self.vfs = vfsmod.vfs(repo.vfs.join(backupdir))
@@ -102,7 +101,7 @@
return sorted(info, reverse=True)
-class Shelf(object):
+class Shelf:
"""Represents a shelf, including possibly multiple files storing it.
Old shelves will have a .patch and a .hg file. Newer shelves will
@@ -214,7 +213,7 @@
self.vfs.tryunlink(self.name + b'.' + ext)
-class shelvedstate(object):
+class shelvedstate:
"""Handle persistence during unshelving operations.
Handles saving and restoring a shelved state. Ensures that different
--- a/mercurial/similar.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/similar.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,12 +5,10 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from . import (
mdiff,
- pycompat,
)
@@ -98,7 +96,7 @@
copies[a] = (r, myscore)
progress.complete()
- for dest, v in pycompat.iteritems(copies):
+ for dest, v in copies.items():
source, bscore = v
yield source, dest, bscore
--- a/mercurial/simplemerge.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/simplemerge.py Fri Mar 25 11:33:12 2022 -0400
@@ -16,7 +16,6 @@
# mbp: "you know that thing where cvs gives you conflict markers?"
# s: "i hate that."
-from __future__ import absolute_import
from .i18n import _
from . import (
@@ -63,7 +62,7 @@
return True
-class Merge3Text(object):
+class Merge3Text:
"""3-way merge of texts.
Given strings BASE, OTHER, THIS, tries to produce a combined text
@@ -469,7 +468,7 @@
return lines
-class MergeInput(object):
+class MergeInput:
def __init__(self, fctx, label=None, label_detail=None):
self.fctx = fctx
self.label = label
@@ -491,6 +490,9 @@
self._text = self.fctx.decodeddata()
return self._text
+ def set_text(self, text):
+ self._text = text
+
def simplemerge(
local,
--- a/mercurial/smartset.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/smartset.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .pycompat import getattr
from . import (
@@ -21,7 +20,7 @@
return pycompat.sysbytes(type(o).__name__).lstrip(b'_')
-class abstractsmartset(object):
+class abstractsmartset:
def __nonzero__(self):
"""True if the smartset is not empty"""
raise NotImplementedError()
--- a/mercurial/sparse.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/sparse.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
@@ -555,7 +554,7 @@
)
# Check for files that were only in the dirstate.
- for file, state in pycompat.iteritems(dirstate):
+ for file, state in dirstate.items():
if not file in files:
old = origsparsematch(file)
new = sparsematch(file)
--- a/mercurial/sshpeer.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/sshpeer.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
import uuid
@@ -48,7 +47,7 @@
display(_(b"remote: "), l, b'\n')
-class doublepipe(object):
+class doublepipe:
"""Operate a side-channel pipe in addition of a main one
The side-channel pipe contains server output to be forwarded to the user
@@ -473,10 +472,10 @@
else:
wireargs[k] = args[k]
del args[k]
- for k, v in sorted(pycompat.iteritems(wireargs)):
+ for k, v in sorted(wireargs.items()):
self._pipeo.write(b"%s %d\n" % (k, len(v)))
if isinstance(v, dict):
- for dk, dv in pycompat.iteritems(v):
+ for dk, dv in v.items():
self._pipeo.write(b"%s %d\n" % (dk, len(dv)))
self._pipeo.write(dv)
else:
--- a/mercurial/sslutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/sslutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import hashlib
import os
--- a/mercurial/stack.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/stack.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,8 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
-
def getstack(repo, rev=None):
"""return a sorted smartrev of the stack containing either rev if it is
--- a/mercurial/state.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/state.py Fri Mar 25 11:33:12 2022 -0400
@@ -17,7 +17,6 @@
the data.
"""
-from __future__ import absolute_import
import contextlib
@@ -40,7 +39,7 @@
assert t
-class cmdstate(object):
+class cmdstate:
"""a wrapper class to store the state of commands like `rebase`, `graft`,
`histedit`, `shelve` etc. Extensions can also use this to write state files.
@@ -103,7 +102,7 @@
return self._repo.vfs.exists(self.fname)
-class _statecheck(object):
+class _statecheck:
"""a utility class that deals with multistep operations like graft,
histedit, bisect, update etc and check whether such commands
are in an unfinished conditition or not and return appropriate message
--- a/mercurial/statichttprepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/statichttprepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
@@ -35,7 +34,7 @@
urlreq = util.urlreq
-class httprangereader(object):
+class httprangereader:
def __init__(self, url, opener):
# we assume opener has HTTPRangeHandler
self.url = url
--- a/mercurial/statprof.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/statprof.py Fri Mar 25 11:33:12 2022 -0400
@@ -101,7 +101,6 @@
main thread's work patterns.
"""
# no-check-code
-from __future__ import absolute_import, division, print_function
import collections
import contextlib
@@ -155,7 +154,7 @@
## Collection data structures
-class ProfileState(object):
+class ProfileState:
def __init__(self, frequency=None):
self.reset(frequency)
self.track = b'cpu'
@@ -203,7 +202,7 @@
state = ProfileState()
-class CodeSite(object):
+class CodeSite:
cache = {}
__slots__ = ('path', 'lineno', 'function', 'source')
@@ -261,7 +260,7 @@
return '%s:%s' % (self.filename(), self.function)
-class Sample(object):
+class Sample:
__slots__ = ('stack', 'time')
def __init__(self, stack, time):
@@ -435,7 +434,7 @@
## Reporting API
-class SiteStats(object):
+class SiteStats:
def __init__(self, site):
self.site = site
self.selfcount = 0
@@ -475,7 +474,7 @@
if i == 0:
sitestat.addself()
- return [s for s in pycompat.itervalues(stats)]
+ return [s for s in stats.values()]
class DisplayFormats:
@@ -574,7 +573,7 @@
# compute sums for each function
functiondata = []
- for fname, sitestats in pycompat.iteritems(grouped):
+ for fname, sitestats in grouped.items():
total_cum_sec = 0
total_self_sec = 0
total_percent = 0
@@ -608,9 +607,7 @@
# only show line numbers for significant locations (>1% time spent)
if stat.selfpercent() > 1:
source = stat.site.getsource(25)
- if sys.version_info.major >= 3 and not isinstance(
- source, bytes
- ):
+ if not isinstance(source, bytes):
source = pycompat.bytestr(source)
stattuple = (
@@ -653,7 +650,7 @@
else:
children[site] = 1
- parents = [(parent, count) for parent, count in pycompat.iteritems(parents)]
+ parents = [(parent, count) for parent, count in parents.items()]
parents.sort(reverse=True, key=lambda x: x[1])
for parent, count in parents:
fp.write(
@@ -697,7 +694,7 @@
)
)
- children = [(child, count) for child, count in pycompat.iteritems(children)]
+ children = [(child, count) for child, count in children.items()]
children.sort(reverse=True, key=lambda x: x[1])
for child, count in children:
fp.write(
@@ -711,7 +708,7 @@
def display_hotpath(data, fp, limit=0.05, **kwargs):
- class HotNode(object):
+ class HotNode:
def __init__(self, site):
self.site = site
self.count = 0
@@ -746,9 +743,7 @@
def _write(node, depth, multiple_siblings):
site = node.site
visiblechildren = [
- c
- for c in pycompat.itervalues(node.children)
- if c.count >= (limit * root.count)
+ c for c in node.children.values() if c.count >= (limit * root.count)
]
if site:
indent = depth * 2 - 1
@@ -784,9 +779,7 @@
)
finalstring = liststring + codestring
- childrensamples = sum(
- [c.count for c in pycompat.itervalues(node.children)]
- )
+ childrensamples = sum([c.count for c in node.children.values()])
# Make frames that performed more than 10% of the operation red
if node.count - childrensamples > (0.1 * root.count):
finalstring = b'\033[91m' + finalstring + b'\033[0m'
@@ -828,7 +821,7 @@
fd, path = pycompat.mkstemp()
with open(path, b"w+") as file:
- for line, count in pycompat.iteritems(lines):
+ for line, count in lines.items():
file.write(b"%s %d\n" % (line, count))
if outputfile is None:
--- a/mercurial/store.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/store.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import functools
@@ -145,7 +144,7 @@
cmap[xchr(x)] = e + xchr(x).lower()
dmap = {}
- for k, v in pycompat.iteritems(cmap):
+ for k, v in cmap.items():
dmap[v] = k
def decode(s):
@@ -456,7 +455,7 @@
FILETYPE_OTHER = FILEFLAGS_OTHER
-class basicstore(object):
+class basicstore:
'''base class for local repository stores'''
def __init__(self, path, vfstype):
@@ -602,7 +601,7 @@
return [b'requires', b'00changelog.i'] + [b'store/' + f for f in _data]
-class fncache(object):
+class fncache:
# the filename used to be partially encoded
# hence the encodedir/decodedir dance
def __init__(self, vfs):
@@ -662,7 +661,7 @@
"""make sure there is no empty string in entries"""
if b'' in self.entries:
fp.seek(0)
- for n, line in enumerate(util.iterfile(fp)):
+ for n, line in enumerate(fp):
if not line.rstrip(b'\n'):
t = _(b'invalid entry in fncache, line %d') % (n + 1)
if warn:
--- a/mercurial/streamclone.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/streamclone.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import errno
@@ -517,7 +516,7 @@
nodemap.post_stream_cleanup(repo)
-class streamcloneapplier(object):
+class streamcloneapplier:
"""Class to manage applying streaming clone bundles.
We need to wrap ``applybundlev1()`` in a dedicated type to enable bundle
--- a/mercurial/strip.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/strip.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from .i18n import _
from .pycompat import getattr
from . import (
@@ -195,7 +193,7 @@
# a revision we have to only delete the bookmark and not strip
# anything. revsets cannot detect that case.
nodetobookmarks = {}
- for mark, node in pycompat.iteritems(repomarks):
+ for mark, node in repomarks.items():
nodetobookmarks.setdefault(node, []).append(mark)
for marks in nodetobookmarks.values():
if bookmarks.issuperset(marks):
--- a/mercurial/subrepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/subrepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import copy
import errno
@@ -221,7 +220,7 @@
# subrepo classes need to implement the following abstract class:
-class abstractsubrepo(object):
+class abstractsubrepo:
def __init__(self, ctx, path):
"""Initialize abstractsubrepo part
@@ -1771,7 +1770,7 @@
for b in rev2branch[self._state[1]]:
if b.startswith(b'refs/remotes/origin/'):
return True
- for b, revision in pycompat.iteritems(branch2rev):
+ for b, revision in branch2rev.items():
if b.startswith(b'refs/remotes/origin/'):
if self._gitisancestor(self._state[1], revision):
return True
--- a/mercurial/subrepoutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/subrepoutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
@@ -191,7 +190,7 @@
repo.ui.debug(b" subrepo %s: %s %s\n" % (s, msg, r))
promptssrc = filemerge.partextras(labels)
- for s, l in sorted(pycompat.iteritems(s1)):
+ for s, l in sorted(s1.items()):
a = sa.get(s, nullstate)
ld = l # local state with possible dirty flag for compares
if wctx.sub(s).dirty():
--- a/mercurial/tagmerge.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/tagmerge.py Fri Mar 25 11:33:12 2022 -0400
@@ -71,7 +71,6 @@
# - put blocks whose nodes come all from p2 first
# - write the tag blocks in the sorted order
-from __future__ import absolute_import
from .i18n import _
from . import (
--- a/mercurial/tags.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/tags.py Fri Mar 25 11:33:12 2022 -0400
@@ -10,7 +10,6 @@
# Eventually, it could take care of updating (adding/removing/moving)
# tags too.
-from __future__ import absolute_import
import errno
import io
@@ -26,7 +25,6 @@
encoding,
error,
match as matchmod,
- pycompat,
scmutil,
util,
)
@@ -355,7 +353,7 @@
if tagtype is None:
assert tagtypes is None
- for name, nodehist in pycompat.iteritems(filetags):
+ for name, nodehist in filetags.items():
if name not in alltags:
alltags[name] = nodehist
if tagtype is not None:
@@ -508,7 +506,7 @@
if unknown_entries:
fixed_nodemap = fnodescache.refresh_invalid_nodes(unknown_entries)
- for node, fnode in pycompat.iteritems(fixed_nodemap):
+ for node, fnode in fixed_nodemap.items():
if fnode != repo.nullid:
cachefnode[node] = fnode
@@ -550,7 +548,7 @@
# we keep them in UTF-8 throughout this module. If we converted
# them local encoding on input, we would lose info writing them to
# the cache.
- for (name, (node, hist)) in sorted(pycompat.iteritems(cachetags)):
+ for (name, (node, hist)) in sorted(cachetags.items()):
for n in hist:
cachefile.write(b"%s %s\n" % (hex(n), name))
cachefile.write(b"%s %s\n" % (hex(node), name))
@@ -686,7 +684,7 @@
_fnodesmissingrec = b'\xff' * 24
-class hgtagsfnodescache(object):
+class hgtagsfnodescache:
"""Persistent cache mapping revisions to .hgtags filenodes.
The cache is an array of records. Each item in the array corresponds to
--- a/mercurial/templatefilters.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/templatefilters.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
import re
@@ -335,7 +334,7 @@
return b'false'
elif obj is True:
return b'true'
- elif isinstance(obj, (int, pycompat.long, float)):
+ elif isinstance(obj, (int, int, float)):
return pycompat.bytestr(obj)
elif isinstance(obj, bytes):
return b'"%s"' % encoding.jsonescape(obj, paranoid=paranoid)
@@ -347,7 +346,7 @@
out = [
b'"%s": %s'
% (encoding.jsonescape(k, paranoid=paranoid), json(v, paranoid))
- for k, v in sorted(pycompat.iteritems(obj))
+ for k, v in sorted(obj.items())
]
return b'{' + b', '.join(out) + b'}'
elif util.safehasattr(obj, b'__iter__'):
@@ -373,9 +372,7 @@
"""Any text. Returns the input text rendered as a sequence of
XML entities.
"""
- text = pycompat.unicode(
- text, pycompat.sysstr(encoding.encoding), r'replace'
- )
+ text = str(text, pycompat.sysstr(encoding.encoding), r'replace')
return b''.join([b'&#%d;' % ord(c) for c in text])
@@ -549,7 +546,7 @@
def loadfilter(ui, extname, registrarobj):
"""Load template filter from specified registrarobj"""
- for name, func in pycompat.iteritems(registrarobj._table):
+ for name, func in registrarobj._table.items():
filters[name] = func
--- a/mercurial/templatefuncs.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/templatefuncs.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
@@ -89,7 +88,7 @@
data.update(
(k, evalfuncarg(context, mapping, v))
- for k, v in pycompat.iteritems(args[b'kwargs'])
+ for k, v in args[b'kwargs'].items()
)
return templateutil.hybriddict(data)
@@ -911,7 +910,7 @@
def loadfunction(ui, extname, registrarobj):
"""Load template function from specified registrarobj"""
- for name, func in pycompat.iteritems(registrarobj._table):
+ for name, func in registrarobj._table.items():
funcs[name] = func
--- a/mercurial/templatekw.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/templatekw.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from .node import (
@@ -603,7 +602,7 @@
# 'name' for iterating over namespaces, templatename for local reference
return lambda v: {b'name': v, ns.templatename: v}
- for k, ns in pycompat.iteritems(repo.names):
+ for k, ns in repo.names.items():
names = ns.names(repo, ctx.node())
f = _showcompatlist(context, mapping, b'name', names)
namespaces[k] = _hybrid(f, names, makensmapfn(ns), pycompat.identity)
@@ -686,12 +685,12 @@
d = {b'name': k}
if len(ps) == 1:
d[b'url'] = ps[0].rawloc
- sub_opts = pycompat.iteritems(ps[0].suboptions)
+ sub_opts = ps[0].suboptions.items()
sub_opts = util.sortdict(sorted(sub_opts))
d.update(sub_opts)
path_dict = util.sortdict()
for p in ps:
- sub_opts = util.sortdict(sorted(pycompat.iteritems(p.suboptions)))
+ sub_opts = util.sortdict(sorted(p.suboptions.items()))
path_dict[b'url'] = p.rawloc
path_dict.update(sub_opts)
d[b'urls'] = [path_dict]
@@ -1024,7 +1023,7 @@
def loadkeyword(ui, extname, registrarobj):
"""Load template keyword from specified registrarobj"""
- for name, func in pycompat.iteritems(registrarobj._table):
+ for name, func in registrarobj._table.items():
keywords[name] = func
--- a/mercurial/templater.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/templater.py Fri Mar 25 11:33:12 2022 -0400
@@ -65,7 +65,6 @@
operation.
"""
-from __future__ import absolute_import, print_function
import abc
import os
@@ -531,8 +530,7 @@
def compiledict(xs):
return util.sortdict(
- (k, compileexp(x, context, curmethods))
- for k, x in pycompat.iteritems(xs)
+ (k, compileexp(x, context, curmethods)) for k, x in xs.items()
)
def compilelist(xs):
@@ -628,7 +626,7 @@
return s[1:-1]
-class resourcemapper(object): # pytype: disable=ignored-metaclass
+class resourcemapper: # pytype: disable=ignored-metaclass
"""Mapper of internal template resources"""
__metaclass__ = abc.ABCMeta
@@ -665,7 +663,7 @@
return {}
-class engine(object):
+class engine:
"""template expansion engine.
template expansion works like this. a map file contains key=value
@@ -709,7 +707,7 @@
newres = self._resources.availablekeys(newmapping)
mapping = {
k: v
- for k, v in pycompat.iteritems(origmapping)
+ for k, v in origmapping.items()
if (
k in knownres # not a symbol per self.symbol()
or newres.isdisjoint(self._defaultrequires(k))
@@ -921,7 +919,7 @@
return cache, tmap, aliases
-class loader(object):
+class loader:
"""Load template fragments optionally from a map file"""
def __init__(self, cache, aliases):
@@ -996,7 +994,7 @@
return syms
-class templater(object):
+class templater:
def __init__(
self,
filters=None,
--- a/mercurial/templateutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/templateutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import abc
import types
@@ -32,7 +31,7 @@
pass
-class wrapped(object): # pytype: disable=ignored-metaclass
+class wrapped: # pytype: disable=ignored-metaclass
"""Object requiring extra conversion prior to displaying or processing
as value
@@ -109,7 +108,7 @@
"""
-class mappable(object): # pytype: disable=ignored-metaclass
+class mappable: # pytype: disable=ignored-metaclass
"""Object which can be converted to a single template mapping"""
__metaclass__ = abc.ABCMeta
@@ -311,7 +310,7 @@
if util.safehasattr(self._values, b'get'):
values = {
k: v
- for k, v in pycompat.iteritems(self._values)
+ for k, v in self._values.items()
if select(self._wrapvalue(k, v))
}
else:
@@ -343,10 +342,7 @@
# TODO: make it non-recursive for trivial lists/dicts
xs = self._values
if util.safehasattr(xs, b'get'):
- return {
- k: unwrapvalue(context, mapping, v)
- for k, v in pycompat.iteritems(xs)
- }
+ return {k: unwrapvalue(context, mapping, v) for k, v in xs.items()}
return [unwrapvalue(context, mapping, x) for x in xs]
@@ -538,7 +534,7 @@
items.append(
{
k: unwrapvalue(context, lm, v)
- for k, v in pycompat.iteritems(nm)
+ for k, v in nm.items()
if k not in knownres
}
)
@@ -716,7 +712,7 @@
This exists for backward compatibility with the old-style template. Use
hybriddict() for new template keywords.
"""
- c = [{key: k, value: v} for k, v in pycompat.iteritems(data)]
+ c = [{key: k, value: v} for k, v in data.items()]
f = _showcompatlist(context, mapping, name, c, plural, separator)
return hybriddict(data, key=key, value=value, fmt=fmt, gen=f)
--- a/mercurial/testing/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/testing/__init__.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,8 +1,3 @@
-from __future__ import (
- absolute_import,
- division,
-)
-
import os
import time
--- a/mercurial/testing/revlog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/testing/revlog.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
import unittest
# picked from test-parse-index2, copied rather than imported
--- a/mercurial/testing/storage.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/testing/storage.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import unittest
--- a/mercurial/thirdparty/concurrent/LICENSE Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,48 +0,0 @@
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF
-hereby grants Licensee a nonexclusive, royalty-free, world-wide
-license to reproduce, analyze, test, perform and/or display publicly,
-prepare derivative works, distribute, and otherwise use Python
-alone or in any derivative version, provided, however, that PSF's
-License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
-2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
-Reserved" are retained in Python alone or in any derivative version
-prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
--- a/mercurial/thirdparty/concurrent/futures/__init__.py Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,27 +0,0 @@
-# Copyright 2009 Brian Quinlan. All Rights Reserved.
-# Licensed to PSF under a Contributor Agreement.
-
-"""Execute computations asynchronously using threads or processes."""
-
-from __future__ import absolute_import
-
-__author__ = 'Brian Quinlan (brian@sweetapp.com)'
-
-from ._base import (
- FIRST_COMPLETED,
- FIRST_EXCEPTION,
- ALL_COMPLETED,
- CancelledError,
- TimeoutError,
- Future,
- Executor,
- wait,
- as_completed,
-)
-from .thread import ThreadPoolExecutor
-
-try:
- from .process import ProcessPoolExecutor
-except ImportError:
- # some platforms don't have multiprocessing
- pass
--- a/mercurial/thirdparty/concurrent/futures/_base.py Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,669 +0,0 @@
-# Copyright 2009 Brian Quinlan. All Rights Reserved.
-# Licensed to PSF under a Contributor Agreement.
-
-from __future__ import absolute_import
-
-import collections
-import logging
-import threading
-import itertools
-import time
-import types
-
-__author__ = 'Brian Quinlan (brian@sweetapp.com)'
-
-FIRST_COMPLETED = 'FIRST_COMPLETED'
-FIRST_EXCEPTION = 'FIRST_EXCEPTION'
-ALL_COMPLETED = 'ALL_COMPLETED'
-_AS_COMPLETED = '_AS_COMPLETED'
-
-# Possible future states (for internal use by the futures package).
-PENDING = 'PENDING'
-RUNNING = 'RUNNING'
-# The future was cancelled by the user...
-CANCELLED = 'CANCELLED'
-# ...and _Waiter.add_cancelled() was called by a worker.
-CANCELLED_AND_NOTIFIED = 'CANCELLED_AND_NOTIFIED'
-FINISHED = 'FINISHED'
-
-_FUTURE_STATES = [
- PENDING,
- RUNNING,
- CANCELLED,
- CANCELLED_AND_NOTIFIED,
- FINISHED
-]
-
-_STATE_TO_DESCRIPTION_MAP = {
- PENDING: "pending",
- RUNNING: "running",
- CANCELLED: "cancelled",
- CANCELLED_AND_NOTIFIED: "cancelled",
- FINISHED: "finished"
-}
-
-# Logger for internal use by the futures package.
-LOGGER = logging.getLogger("concurrent.futures")
-
-class Error(Exception):
- """Base class for all future-related exceptions."""
- pass
-
-class CancelledError(Error):
- """The Future was cancelled."""
- pass
-
-class TimeoutError(Error):
- """The operation exceeded the given deadline."""
- pass
-
-class _Waiter(object):
- """Provides the event that wait() and as_completed() block on."""
- def __init__(self):
- self.event = threading.Event()
- self.finished_futures = []
-
- def add_result(self, future):
- self.finished_futures.append(future)
-
- def add_exception(self, future):
- self.finished_futures.append(future)
-
- def add_cancelled(self, future):
- self.finished_futures.append(future)
-
-class _AsCompletedWaiter(_Waiter):
- """Used by as_completed()."""
-
- def __init__(self):
- super(_AsCompletedWaiter, self).__init__()
- self.lock = threading.Lock()
-
- def add_result(self, future):
- with self.lock:
- super(_AsCompletedWaiter, self).add_result(future)
- self.event.set()
-
- def add_exception(self, future):
- with self.lock:
- super(_AsCompletedWaiter, self).add_exception(future)
- self.event.set()
-
- def add_cancelled(self, future):
- with self.lock:
- super(_AsCompletedWaiter, self).add_cancelled(future)
- self.event.set()
-
-class _FirstCompletedWaiter(_Waiter):
- """Used by wait(return_when=FIRST_COMPLETED)."""
-
- def add_result(self, future):
- super(_FirstCompletedWaiter, self).add_result(future)
- self.event.set()
-
- def add_exception(self, future):
- super(_FirstCompletedWaiter, self).add_exception(future)
- self.event.set()
-
- def add_cancelled(self, future):
- super(_FirstCompletedWaiter, self).add_cancelled(future)
- self.event.set()
-
-class _AllCompletedWaiter(_Waiter):
- """Used by wait(return_when=FIRST_EXCEPTION and ALL_COMPLETED)."""
-
- def __init__(self, num_pending_calls, stop_on_exception):
- self.num_pending_calls = num_pending_calls
- self.stop_on_exception = stop_on_exception
- self.lock = threading.Lock()
- super(_AllCompletedWaiter, self).__init__()
-
- def _decrement_pending_calls(self):
- with self.lock:
- self.num_pending_calls -= 1
- if not self.num_pending_calls:
- self.event.set()
-
- def add_result(self, future):
- super(_AllCompletedWaiter, self).add_result(future)
- self._decrement_pending_calls()
-
- def add_exception(self, future):
- super(_AllCompletedWaiter, self).add_exception(future)
- if self.stop_on_exception:
- self.event.set()
- else:
- self._decrement_pending_calls()
-
- def add_cancelled(self, future):
- super(_AllCompletedWaiter, self).add_cancelled(future)
- self._decrement_pending_calls()
-
-class _AcquireFutures(object):
- """A context manager that does an ordered acquire of Future conditions."""
-
- def __init__(self, futures):
- self.futures = sorted(futures, key=id)
-
- def __enter__(self):
- for future in self.futures:
- future._condition.acquire()
-
- def __exit__(self, *args):
- for future in self.futures:
- future._condition.release()
-
-def _create_and_install_waiters(fs, return_when):
- if return_when == _AS_COMPLETED:
- waiter = _AsCompletedWaiter()
- elif return_when == FIRST_COMPLETED:
- waiter = _FirstCompletedWaiter()
- else:
- pending_count = sum(
- f._state not in [CANCELLED_AND_NOTIFIED, FINISHED] for f in fs)
-
- if return_when == FIRST_EXCEPTION:
- waiter = _AllCompletedWaiter(pending_count, stop_on_exception=True)
- elif return_when == ALL_COMPLETED:
- waiter = _AllCompletedWaiter(pending_count, stop_on_exception=False)
- else:
- raise ValueError("Invalid return condition: %r" % return_when)
-
- for f in fs:
- f._waiters.append(waiter)
-
- return waiter
-
-
-def _yield_finished_futures(fs, waiter, ref_collect):
- """
- Iterate on the list *fs*, yielding finished futures one by one in
- reverse order.
- Before yielding a future, *waiter* is removed from its waiters
- and the future is removed from each set in the collection of sets
- *ref_collect*.
-
- The aim of this function is to avoid keeping stale references after
- the future is yielded and before the iterator resumes.
- """
- while fs:
- f = fs[-1]
- for futures_set in ref_collect:
- futures_set.remove(f)
- with f._condition:
- f._waiters.remove(waiter)
- del f
- # Careful not to keep a reference to the popped value
- yield fs.pop()
-
-
-def as_completed(fs, timeout=None):
- """An iterator over the given futures that yields each as it completes.
-
- Args:
- fs: The sequence of Futures (possibly created by different Executors) to
- iterate over.
- timeout: The maximum number of seconds to wait. If None, then there
- is no limit on the wait time.
-
- Returns:
- An iterator that yields the given Futures as they complete (finished or
- cancelled). If any given Futures are duplicated, they will be returned
- once.
-
- Raises:
- TimeoutError: If the entire result iterator could not be generated
- before the given timeout.
- """
- if timeout is not None:
- end_time = timeout + time.time()
-
- fs = set(fs)
- total_futures = len(fs)
- with _AcquireFutures(fs):
- finished = set(
- f for f in fs
- if f._state in [CANCELLED_AND_NOTIFIED, FINISHED])
- pending = fs - finished
- waiter = _create_and_install_waiters(fs, _AS_COMPLETED)
- finished = list(finished)
- try:
- for f in _yield_finished_futures(finished, waiter,
- ref_collect=(fs,)):
- f = [f]
- yield f.pop()
-
- while pending:
- if timeout is None:
- wait_timeout = None
- else:
- wait_timeout = end_time - time.time()
- if wait_timeout < 0:
- raise TimeoutError(
- '%d (of %d) futures unfinished' % (
- len(pending), total_futures))
-
- waiter.event.wait(wait_timeout)
-
- with waiter.lock:
- finished = waiter.finished_futures
- waiter.finished_futures = []
- waiter.event.clear()
-
- # reverse to keep finishing order
- finished.reverse()
- for f in _yield_finished_futures(finished, waiter,
- ref_collect=(fs, pending)):
- f = [f]
- yield f.pop()
-
- finally:
- # Remove waiter from unfinished futures
- for f in fs:
- with f._condition:
- f._waiters.remove(waiter)
-
-DoneAndNotDoneFutures = collections.namedtuple(
- 'DoneAndNotDoneFutures', 'done not_done')
-def wait(fs, timeout=None, return_when=ALL_COMPLETED):
- """Wait for the futures in the given sequence to complete.
-
- Args:
- fs: The sequence of Futures (possibly created by different Executors) to
- wait upon.
- timeout: The maximum number of seconds to wait. If None, then there
- is no limit on the wait time.
- return_when: Indicates when this function should return. The options
- are:
-
- FIRST_COMPLETED - Return when any future finishes or is
- cancelled.
- FIRST_EXCEPTION - Return when any future finishes by raising an
- exception. If no future raises an exception
- then it is equivalent to ALL_COMPLETED.
- ALL_COMPLETED - Return when all futures finish or are cancelled.
-
- Returns:
- A named 2-tuple of sets. The first set, named 'done', contains the
- futures that completed (is finished or cancelled) before the wait
- completed. The second set, named 'not_done', contains uncompleted
- futures.
- """
- with _AcquireFutures(fs):
- done = set(f for f in fs
- if f._state in [CANCELLED_AND_NOTIFIED, FINISHED])
- not_done = set(fs) - done
-
- if (return_when == FIRST_COMPLETED) and done:
- return DoneAndNotDoneFutures(done, not_done)
- elif (return_when == FIRST_EXCEPTION) and done:
- if any(f for f in done
- if not f.cancelled() and f.exception() is not None):
- return DoneAndNotDoneFutures(done, not_done)
-
- if len(done) == len(fs):
- return DoneAndNotDoneFutures(done, not_done)
-
- waiter = _create_and_install_waiters(fs, return_when)
-
- waiter.event.wait(timeout)
- for f in fs:
- with f._condition:
- f._waiters.remove(waiter)
-
- done.update(waiter.finished_futures)
- return DoneAndNotDoneFutures(done, set(fs) - done)
-
-class Future(object):
- """Represents the result of an asynchronous computation."""
-
- def __init__(self):
- """Initializes the future. Should not be called by clients."""
- self._condition = threading.Condition()
- self._state = PENDING
- self._result = None
- self._exception = None
- self._traceback = None
- self._waiters = []
- self._done_callbacks = []
-
- def _invoke_callbacks(self):
- for callback in self._done_callbacks:
- try:
- callback(self)
- except Exception:
- LOGGER.exception('exception calling callback for %r', self)
- except BaseException:
- # Explicitly let all other new-style exceptions through so
- # that we can catch all old-style exceptions with a simple
- # "except:" clause below.
- #
- # All old-style exception objects are instances of
- # types.InstanceType, but "except types.InstanceType:" does
- # not catch old-style exceptions for some reason. Thus, the
- # only way to catch all old-style exceptions without catching
- # any new-style exceptions is to filter out the new-style
- # exceptions, which all derive from BaseException.
- raise
- except:
- # Because of the BaseException clause above, this handler only
- # executes for old-style exception objects.
- LOGGER.exception('exception calling callback for %r', self)
-
- def __repr__(self):
- with self._condition:
- if self._state == FINISHED:
- if self._exception:
- return '<%s at %#x state=%s raised %s>' % (
- self.__class__.__name__,
- id(self),
- _STATE_TO_DESCRIPTION_MAP[self._state],
- self._exception.__class__.__name__)
- else:
- return '<%s at %#x state=%s returned %s>' % (
- self.__class__.__name__,
- id(self),
- _STATE_TO_DESCRIPTION_MAP[self._state],
- self._result.__class__.__name__)
- return '<%s at %#x state=%s>' % (
- self.__class__.__name__,
- id(self),
- _STATE_TO_DESCRIPTION_MAP[self._state])
-
- def cancel(self):
- """Cancel the future if possible.
-
- Returns True if the future was cancelled, False otherwise. A future
- cannot be cancelled if it is running or has already completed.
- """
- with self._condition:
- if self._state in [RUNNING, FINISHED]:
- return False
-
- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
- return True
-
- self._state = CANCELLED
- self._condition.notify_all()
-
- self._invoke_callbacks()
- return True
-
- def cancelled(self):
- """Return True if the future was cancelled."""
- with self._condition:
- return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]
-
- def running(self):
- """Return True if the future is currently executing."""
- with self._condition:
- return self._state == RUNNING
-
- def done(self):
- """Return True of the future was cancelled or finished executing."""
- with self._condition:
- return self._state in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED]
-
- def __get_result(self):
- if self._exception:
- if isinstance(self._exception, types.InstanceType):
- # The exception is an instance of an old-style class, which
- # means type(self._exception) returns types.ClassType instead
- # of the exception's actual class type.
- exception_type = self._exception.__class__
- else:
- exception_type = type(self._exception)
- raise exception_type, self._exception, self._traceback
- else:
- return self._result
-
- def add_done_callback(self, fn):
- """Attaches a callable that will be called when the future finishes.
-
- Args:
- fn: A callable that will be called with this future as its only
- argument when the future completes or is cancelled. The callable
- will always be called by a thread in the same process in which
- it was added. If the future has already completed or been
- cancelled then the callable will be called immediately. These
- callables are called in the order that they were added.
- """
- with self._condition:
- if self._state not in [CANCELLED, CANCELLED_AND_NOTIFIED, FINISHED]:
- self._done_callbacks.append(fn)
- return
- fn(self)
-
- def result(self, timeout=None):
- """Return the result of the call that the future represents.
-
- Args:
- timeout: The number of seconds to wait for the result if the future
- isn't done. If None, then there is no limit on the wait time.
-
- Returns:
- The result of the call that the future represents.
-
- Raises:
- CancelledError: If the future was cancelled.
- TimeoutError: If the future didn't finish executing before the given
- timeout.
- Exception: If the call raised then that exception will be raised.
- """
- with self._condition:
- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
- raise CancelledError()
- elif self._state == FINISHED:
- return self.__get_result()
-
- self._condition.wait(timeout)
-
- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
- raise CancelledError()
- elif self._state == FINISHED:
- return self.__get_result()
- else:
- raise TimeoutError()
-
- def exception_info(self, timeout=None):
- """Return a tuple of (exception, traceback) raised by the call that the
- future represents.
-
- Args:
- timeout: The number of seconds to wait for the exception if the
- future isn't done. If None, then there is no limit on the wait
- time.
-
- Returns:
- The exception raised by the call that the future represents or None
- if the call completed without raising.
-
- Raises:
- CancelledError: If the future was cancelled.
- TimeoutError: If the future didn't finish executing before the given
- timeout.
- """
- with self._condition:
- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
- raise CancelledError()
- elif self._state == FINISHED:
- return self._exception, self._traceback
-
- self._condition.wait(timeout)
-
- if self._state in [CANCELLED, CANCELLED_AND_NOTIFIED]:
- raise CancelledError()
- elif self._state == FINISHED:
- return self._exception, self._traceback
- else:
- raise TimeoutError()
-
- def exception(self, timeout=None):
- """Return the exception raised by the call that the future represents.
-
- Args:
- timeout: The number of seconds to wait for the exception if the
- future isn't done. If None, then there is no limit on the wait
- time.
-
- Returns:
- The exception raised by the call that the future represents or None
- if the call completed without raising.
-
- Raises:
- CancelledError: If the future was cancelled.
- TimeoutError: If the future didn't finish executing before the given
- timeout.
- """
- return self.exception_info(timeout)[0]
-
- # The following methods should only be used by Executors and in tests.
- def set_running_or_notify_cancel(self):
- """Mark the future as running or process any cancel notifications.
-
- Should only be used by Executor implementations and unit tests.
-
- If the future has been cancelled (cancel() was called and returned
- True) then any threads waiting on the future completing (though calls
- to as_completed() or wait()) are notified and False is returned.
-
- If the future was not cancelled then it is put in the running state
- (future calls to running() will return True) and True is returned.
-
- This method should be called by Executor implementations before
- executing the work associated with this future. If this method returns
- False then the work should not be executed.
-
- Returns:
- False if the Future was cancelled, True otherwise.
-
- Raises:
- RuntimeError: if this method was already called or if set_result()
- or set_exception() was called.
- """
- with self._condition:
- if self._state == CANCELLED:
- self._state = CANCELLED_AND_NOTIFIED
- for waiter in self._waiters:
- waiter.add_cancelled(self)
- # self._condition.notify_all() is not necessary because
- # self.cancel() triggers a notification.
- return False
- elif self._state == PENDING:
- self._state = RUNNING
- return True
- else:
- LOGGER.critical('Future %s in unexpected state: %s',
- id(self),
- self._state)
- raise RuntimeError('Future in unexpected state')
-
- def set_result(self, result):
- """Sets the return value of work associated with the future.
-
- Should only be used by Executor implementations and unit tests.
- """
- with self._condition:
- self._result = result
- self._state = FINISHED
- for waiter in self._waiters:
- waiter.add_result(self)
- self._condition.notify_all()
- self._invoke_callbacks()
-
- def set_exception_info(self, exception, traceback):
- """Sets the result of the future as being the given exception
- and traceback.
-
- Should only be used by Executor implementations and unit tests.
- """
- with self._condition:
- self._exception = exception
- self._traceback = traceback
- self._state = FINISHED
- for waiter in self._waiters:
- waiter.add_exception(self)
- self._condition.notify_all()
- self._invoke_callbacks()
-
- def set_exception(self, exception):
- """Sets the result of the future as being the given exception.
-
- Should only be used by Executor implementations and unit tests.
- """
- self.set_exception_info(exception, None)
-
-class Executor(object):
- """This is an abstract base class for concrete asynchronous executors."""
-
- def submit(self, fn, *args, **kwargs):
- """Submits a callable to be executed with the given arguments.
-
- Schedules the callable to be executed as fn(*args, **kwargs) and returns
- a Future instance representing the execution of the callable.
-
- Returns:
- A Future representing the given call.
- """
- raise NotImplementedError()
-
- def map(self, fn, *iterables, **kwargs):
- """Returns an iterator equivalent to map(fn, iter).
-
- Args:
- fn: A callable that will take as many arguments as there are
- passed iterables.
- timeout: The maximum number of seconds to wait. If None, then there
- is no limit on the wait time.
-
- Returns:
- An iterator equivalent to: map(func, *iterables) but the calls may
- be evaluated out-of-order.
-
- Raises:
- TimeoutError: If the entire result iterator could not be generated
- before the given timeout.
- Exception: If fn(*args) raises for any values.
- """
- timeout = kwargs.get('timeout')
- if timeout is not None:
- end_time = timeout + time.time()
-
- fs = [self.submit(fn, *args) for args in itertools.izip(*iterables)]
-
- # Yield must be hidden in closure so that the futures are submitted
- # before the first iterator value is required.
- def result_iterator():
- try:
- # reverse to keep finishing order
- fs.reverse()
- while fs:
- # Careful not to keep a reference to the popped future
- if timeout is None:
- yield fs.pop().result()
- else:
- yield fs.pop().result(end_time - time.time())
- finally:
- for future in fs:
- future.cancel()
- return result_iterator()
-
- def shutdown(self, wait=True):
- """Clean-up the resources associated with the Executor.
-
- It is safe to call this method several times. Otherwise, no other
- methods can be called after this one.
-
- Args:
- wait: If True then shutdown will not return until all running
- futures have finished executing and the resources used by the
- executor have been reclaimed.
- """
- pass
-
- def __enter__(self):
- return self
-
- def __exit__(self, exc_type, exc_val, exc_tb):
- self.shutdown(wait=True)
- return False
--- a/mercurial/thirdparty/concurrent/futures/process.py Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,365 +0,0 @@
-# Copyright 2009 Brian Quinlan. All Rights Reserved.
-# Licensed to PSF under a Contributor Agreement.
-
-"""Implements ProcessPoolExecutor.
-
-The follow diagram and text describe the data-flow through the system:
-
-|======================= In-process =====================|== Out-of-process ==|
-
-+----------+ +----------+ +--------+ +-----------+ +---------+
-| | => | Work Ids | => | | => | Call Q | => | |
-| | +----------+ | | +-----------+ | |
-| | | ... | | | | ... | | |
-| | | 6 | | | | 5, call() | | |
-| | | 7 | | | | ... | | |
-| Process | | ... | | Local | +-----------+ | Process |
-| Pool | +----------+ | Worker | | #1..n |
-| Executor | | Thread | | |
-| | +----------- + | | +-----------+ | |
-| | <=> | Work Items | <=> | | <= | Result Q | <= | |
-| | +------------+ | | +-----------+ | |
-| | | 6: call() | | | | ... | | |
-| | | future | | | | 4, result | | |
-| | | ... | | | | 3, except | | |
-+----------+ +------------+ +--------+ +-----------+ +---------+
-
-Executor.submit() called:
-- creates a uniquely numbered _WorkItem and adds it to the "Work Items" dict
-- adds the id of the _WorkItem to the "Work Ids" queue
-
-Local worker thread:
-- reads work ids from the "Work Ids" queue and looks up the corresponding
- WorkItem from the "Work Items" dict: if the work item has been cancelled then
- it is simply removed from the dict, otherwise it is repackaged as a
- _CallItem and put in the "Call Q". New _CallItems are put in the "Call Q"
- until "Call Q" is full. NOTE: the size of the "Call Q" is kept small because
- calls placed in the "Call Q" can no longer be cancelled with Future.cancel().
-- reads _ResultItems from "Result Q", updates the future stored in the
- "Work Items" dict and deletes the dict entry
-
-Process #1..n:
-- reads _CallItems from "Call Q", executes the calls, and puts the resulting
- _ResultItems in "Request Q"
-"""
-
-from __future__ import absolute_import
-
-import atexit
-from . import _base
-import Queue as queue
-import multiprocessing
-import threading
-import weakref
-import sys
-
-__author__ = 'Brian Quinlan (brian@sweetapp.com)'
-
-# Workers are created as daemon threads and processes. This is done to allow the
-# interpreter to exit when there are still idle processes in a
-# ProcessPoolExecutor's process pool (i.e. shutdown() was not called). However,
-# allowing workers to die with the interpreter has two undesirable properties:
-# - The workers would still be running during interpretor shutdown,
-# meaning that they would fail in unpredictable ways.
-# - The workers could be killed while evaluating a work item, which could
-# be bad if the callable being evaluated has external side-effects e.g.
-# writing to a file.
-#
-# To work around this problem, an exit handler is installed which tells the
-# workers to exit when their work queues are empty and then waits until the
-# threads/processes finish.
-
-_threads_queues = weakref.WeakKeyDictionary()
-_shutdown = False
-
-def _python_exit():
- global _shutdown
- _shutdown = True
- items = list(_threads_queues.items()) if _threads_queues else ()
- for t, q in items:
- q.put(None)
- for t, q in items:
- t.join(sys.maxint)
-
-# Controls how many more calls than processes will be queued in the call queue.
-# A smaller number will mean that processes spend more time idle waiting for
-# work while a larger number will make Future.cancel() succeed less frequently
-# (Futures in the call queue cannot be cancelled).
-EXTRA_QUEUED_CALLS = 1
-
-class _WorkItem(object):
- def __init__(self, future, fn, args, kwargs):
- self.future = future
- self.fn = fn
- self.args = args
- self.kwargs = kwargs
-
-class _ResultItem(object):
- def __init__(self, work_id, exception=None, result=None):
- self.work_id = work_id
- self.exception = exception
- self.result = result
-
-class _CallItem(object):
- def __init__(self, work_id, fn, args, kwargs):
- self.work_id = work_id
- self.fn = fn
- self.args = args
- self.kwargs = kwargs
-
-def _process_worker(call_queue, result_queue):
- """Evaluates calls from call_queue and places the results in result_queue.
-
- This worker is run in a separate process.
-
- Args:
- call_queue: A multiprocessing.Queue of _CallItems that will be read and
- evaluated by the worker.
- result_queue: A multiprocessing.Queue of _ResultItems that will written
- to by the worker.
- shutdown: A multiprocessing.Event that will be set as a signal to the
- worker that it should exit when call_queue is empty.
- """
- while True:
- call_item = call_queue.get(block=True)
- if call_item is None:
- # Wake up queue management thread
- result_queue.put(None)
- return
- try:
- r = call_item.fn(*call_item.args, **call_item.kwargs)
- except:
- e = sys.exc_info()[1]
- result_queue.put(_ResultItem(call_item.work_id,
- exception=e))
- else:
- result_queue.put(_ResultItem(call_item.work_id,
- result=r))
-
-def _add_call_item_to_queue(pending_work_items,
- work_ids,
- call_queue):
- """Fills call_queue with _WorkItems from pending_work_items.
-
- This function never blocks.
-
- Args:
- pending_work_items: A dict mapping work ids to _WorkItems e.g.
- {5: <_WorkItem...>, 6: <_WorkItem...>, ...}
- work_ids: A queue.Queue of work ids e.g. Queue([5, 6, ...]). Work ids
- are consumed and the corresponding _WorkItems from
- pending_work_items are transformed into _CallItems and put in
- call_queue.
- call_queue: A multiprocessing.Queue that will be filled with _CallItems
- derived from _WorkItems.
- """
- while True:
- if call_queue.full():
- return
- try:
- work_id = work_ids.get(block=False)
- except queue.Empty:
- return
- else:
- work_item = pending_work_items[work_id]
-
- if work_item.future.set_running_or_notify_cancel():
- call_queue.put(_CallItem(work_id,
- work_item.fn,
- work_item.args,
- work_item.kwargs),
- block=True)
- else:
- del pending_work_items[work_id]
- continue
-
-def _queue_management_worker(executor_reference,
- processes,
- pending_work_items,
- work_ids_queue,
- call_queue,
- result_queue):
- """Manages the communication between this process and the worker processes.
-
- This function is run in a local thread.
-
- Args:
- executor_reference: A weakref.ref to the ProcessPoolExecutor that owns
- this thread. Used to determine if the ProcessPoolExecutor has been
- garbage collected and that this function can exit.
- process: A list of the multiprocessing.Process instances used as
- workers.
- pending_work_items: A dict mapping work ids to _WorkItems e.g.
- {5: <_WorkItem...>, 6: <_WorkItem...>, ...}
- work_ids_queue: A queue.Queue of work ids e.g. Queue([5, 6, ...]).
- call_queue: A multiprocessing.Queue that will be filled with _CallItems
- derived from _WorkItems for processing by the process workers.
- result_queue: A multiprocessing.Queue of _ResultItems generated by the
- process workers.
- """
- nb_shutdown_processes = [0]
- def shutdown_one_process():
- """Tell a worker to terminate, which will in turn wake us again"""
- call_queue.put(None)
- nb_shutdown_processes[0] += 1
- while True:
- _add_call_item_to_queue(pending_work_items,
- work_ids_queue,
- call_queue)
-
- result_item = result_queue.get(block=True)
- if result_item is not None:
- work_item = pending_work_items[result_item.work_id]
- del pending_work_items[result_item.work_id]
-
- if result_item.exception:
- work_item.future.set_exception(result_item.exception)
- else:
- work_item.future.set_result(result_item.result)
- # Delete references to object. See issue16284
- del work_item
- # Check whether we should start shutting down.
- executor = executor_reference()
- # No more work items can be added if:
- # - The interpreter is shutting down OR
- # - The executor that owns this worker has been collected OR
- # - The executor that owns this worker has been shutdown.
- if _shutdown or executor is None or executor._shutdown_thread:
- # Since no new work items can be added, it is safe to shutdown
- # this thread if there are no pending work items.
- if not pending_work_items:
- while nb_shutdown_processes[0] < len(processes):
- shutdown_one_process()
- # If .join() is not called on the created processes then
- # some multiprocessing.Queue methods may deadlock on Mac OS
- # X.
- for p in processes:
- p.join()
- call_queue.close()
- return
- del executor
-
-_system_limits_checked = False
-_system_limited = None
-def _check_system_limits():
- global _system_limits_checked, _system_limited
- if _system_limits_checked:
- if _system_limited:
- raise NotImplementedError(_system_limited)
- _system_limits_checked = True
- try:
- import os
- nsems_max = os.sysconf("SC_SEM_NSEMS_MAX")
- except (AttributeError, ValueError):
- # sysconf not available or setting not available
- return
- if nsems_max == -1:
- # indetermine limit, assume that limit is determined
- # by available memory only
- return
- if nsems_max >= 256:
- # minimum number of semaphores available
- # according to POSIX
- return
- _system_limited = "system provides too few semaphores (%d available, 256 necessary)" % nsems_max
- raise NotImplementedError(_system_limited)
-
-
-class ProcessPoolExecutor(_base.Executor):
- def __init__(self, max_workers=None):
- """Initializes a new ProcessPoolExecutor instance.
-
- Args:
- max_workers: The maximum number of processes that can be used to
- execute the given calls. If None or not given then as many
- worker processes will be created as the machine has processors.
- """
- _check_system_limits()
-
- if max_workers is None:
- self._max_workers = multiprocessing.cpu_count()
- else:
- if max_workers <= 0:
- raise ValueError("max_workers must be greater than 0")
-
- self._max_workers = max_workers
-
- # Make the call queue slightly larger than the number of processes to
- # prevent the worker processes from idling. But don't make it too big
- # because futures in the call queue cannot be cancelled.
- self._call_queue = multiprocessing.Queue(self._max_workers +
- EXTRA_QUEUED_CALLS)
- self._result_queue = multiprocessing.Queue()
- self._work_ids = queue.Queue()
- self._queue_management_thread = None
- self._processes = set()
-
- # Shutdown is a two-step process.
- self._shutdown_thread = False
- self._shutdown_lock = threading.Lock()
- self._queue_count = 0
- self._pending_work_items = {}
-
- def _start_queue_management_thread(self):
- # When the executor gets lost, the weakref callback will wake up
- # the queue management thread.
- def weakref_cb(_, q=self._result_queue):
- q.put(None)
- if self._queue_management_thread is None:
- self._queue_management_thread = threading.Thread(
- target=_queue_management_worker,
- args=(weakref.ref(self, weakref_cb),
- self._processes,
- self._pending_work_items,
- self._work_ids,
- self._call_queue,
- self._result_queue))
- self._queue_management_thread.daemon = True
- self._queue_management_thread.start()
- _threads_queues[self._queue_management_thread] = self._result_queue
-
- def _adjust_process_count(self):
- for _ in range(len(self._processes), self._max_workers):
- p = multiprocessing.Process(
- target=_process_worker,
- args=(self._call_queue,
- self._result_queue))
- p.start()
- self._processes.add(p)
-
- def submit(self, fn, *args, **kwargs):
- with self._shutdown_lock:
- if self._shutdown_thread:
- raise RuntimeError('cannot schedule new futures after shutdown')
-
- f = _base.Future()
- w = _WorkItem(f, fn, args, kwargs)
-
- self._pending_work_items[self._queue_count] = w
- self._work_ids.put(self._queue_count)
- self._queue_count += 1
- # Wake up queue management thread
- self._result_queue.put(None)
-
- self._start_queue_management_thread()
- self._adjust_process_count()
- return f
- submit.__doc__ = _base.Executor.submit.__doc__
-
- def shutdown(self, wait=True):
- with self._shutdown_lock:
- self._shutdown_thread = True
- if self._queue_management_thread:
- # Wake up queue management thread
- self._result_queue.put(None)
- if wait:
- self._queue_management_thread.join(sys.maxint)
- # To reduce the risk of openning too many files, remove references to
- # objects that use file descriptors.
- self._queue_management_thread = None
- self._call_queue = None
- self._result_queue = None
- self._processes = None
- shutdown.__doc__ = _base.Executor.shutdown.__doc__
-
-atexit.register(_python_exit)
--- a/mercurial/thirdparty/concurrent/futures/thread.py Tue Mar 22 03:19:01 2022 +0100
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,162 +0,0 @@
-# Copyright 2009 Brian Quinlan. All Rights Reserved.
-# Licensed to PSF under a Contributor Agreement.
-
-"""Implements ThreadPoolExecutor."""
-
-from __future__ import absolute_import
-
-import atexit
-from . import _base
-import itertools
-import Queue as queue
-import threading
-import weakref
-import sys
-
-try:
- from multiprocessing import cpu_count
-except ImportError:
- # some platforms don't have multiprocessing
- def cpu_count():
- return None
-
-__author__ = 'Brian Quinlan (brian@sweetapp.com)'
-
-# Workers are created as daemon threads. This is done to allow the interpreter
-# to exit when there are still idle threads in a ThreadPoolExecutor's thread
-# pool (i.e. shutdown() was not called). However, allowing workers to die with
-# the interpreter has two undesirable properties:
-# - The workers would still be running during interpretor shutdown,
-# meaning that they would fail in unpredictable ways.
-# - The workers could be killed while evaluating a work item, which could
-# be bad if the callable being evaluated has external side-effects e.g.
-# writing to a file.
-#
-# To work around this problem, an exit handler is installed which tells the
-# workers to exit when their work queues are empty and then waits until the
-# threads finish.
-
-_threads_queues = weakref.WeakKeyDictionary()
-_shutdown = False
-
-def _python_exit():
- global _shutdown
- _shutdown = True
- items = list(_threads_queues.items()) if _threads_queues else ()
- for t, q in items:
- q.put(None)
- for t, q in items:
- t.join(sys.maxint)
-
-atexit.register(_python_exit)
-
-class _WorkItem(object):
- def __init__(self, future, fn, args, kwargs):
- self.future = future
- self.fn = fn
- self.args = args
- self.kwargs = kwargs
-
- def run(self):
- if not self.future.set_running_or_notify_cancel():
- return
-
- try:
- result = self.fn(*self.args, **self.kwargs)
- except:
- e, tb = sys.exc_info()[1:]
- self.future.set_exception_info(e, tb)
- else:
- self.future.set_result(result)
-
-def _worker(executor_reference, work_queue):
- try:
- while True:
- work_item = work_queue.get(block=True)
- if work_item is not None:
- work_item.run()
- # Delete references to object. See issue16284
- del work_item
- continue
- executor = executor_reference()
- # Exit if:
- # - The interpreter is shutting down OR
- # - The executor that owns the worker has been collected OR
- # - The executor that owns the worker has been shutdown.
- if _shutdown or executor is None or executor._shutdown:
- # Notice other workers
- work_queue.put(None)
- return
- del executor
- except:
- _base.LOGGER.critical('Exception in worker', exc_info=True)
-
-
-class ThreadPoolExecutor(_base.Executor):
-
- # Used to assign unique thread names when thread_name_prefix is not supplied.
- _counter = itertools.count().next
-
- def __init__(self, max_workers=None, thread_name_prefix=''):
- """Initializes a new ThreadPoolExecutor instance.
-
- Args:
- max_workers: The maximum number of threads that can be used to
- execute the given calls.
- thread_name_prefix: An optional name prefix to give our threads.
- """
- if max_workers is None:
- # Use this number because ThreadPoolExecutor is often
- # used to overlap I/O instead of CPU work.
- max_workers = (cpu_count() or 1) * 5
- if max_workers <= 0:
- raise ValueError("max_workers must be greater than 0")
-
- self._max_workers = max_workers
- self._work_queue = queue.Queue()
- self._threads = set()
- self._shutdown = False
- self._shutdown_lock = threading.Lock()
- self._thread_name_prefix = (thread_name_prefix or
- ("ThreadPoolExecutor-%d" % self._counter()))
-
- def submit(self, fn, *args, **kwargs):
- with self._shutdown_lock:
- if self._shutdown:
- raise RuntimeError('cannot schedule new futures after shutdown')
-
- f = _base.Future()
- w = _WorkItem(f, fn, args, kwargs)
-
- self._work_queue.put(w)
- self._adjust_thread_count()
- return f
- submit.__doc__ = _base.Executor.submit.__doc__
-
- def _adjust_thread_count(self):
- # When the executor gets lost, the weakref callback will wake up
- # the worker threads.
- def weakref_cb(_, q=self._work_queue):
- q.put(None)
- # TODO(bquinlan): Should avoid creating new threads if there are more
- # idle threads than items in the work queue.
- num_threads = len(self._threads)
- if num_threads < self._max_workers:
- thread_name = '%s_%d' % (self._thread_name_prefix or self,
- num_threads)
- t = threading.Thread(name=thread_name, target=_worker,
- args=(weakref.ref(self, weakref_cb),
- self._work_queue))
- t.daemon = True
- t.start()
- self._threads.add(t)
- _threads_queues[t] = self._work_queue
-
- def shutdown(self, wait=True):
- with self._shutdown_lock:
- self._shutdown = True
- self._work_queue.put(None)
- if wait:
- for t in self._threads:
- t.join(sys.maxint)
- shutdown.__doc__ = _base.Executor.shutdown.__doc__
--- a/mercurial/transaction.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/transaction.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,7 +11,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
@@ -383,7 +382,7 @@
skip_pre = group == GEN_GROUP_POST_FINALIZE
skip_post = group == GEN_GROUP_PRE_FINALIZE
- for id, entry in sorted(pycompat.iteritems(self._filegenerators)):
+ for id, entry in sorted(self._filegenerators.items()):
any = True
order, filenames, genfunc, location, post_finalize = entry
--- a/mercurial/treediscovery.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/treediscovery.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
--- a/mercurial/txnutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/txnutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
--- a/mercurial/ui.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/ui.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import collections
import contextlib
@@ -170,7 +169,7 @@
return pycompat.rapply(pycompat.bytesurl, maybestr)
-class httppasswordmgrdbproxy(object):
+class httppasswordmgrdbproxy:
"""Delays loading urllib2 until it's needed."""
def __init__(self):
@@ -208,7 +207,7 @@
_reqexithandlers = []
-class ui(object):
+class ui:
def __init__(self, src=None):
"""Create a fresh new ui object if no src given
@@ -1726,9 +1725,9 @@
if usereadline:
self.flush()
prompt = encoding.strfromlocal(prompt)
- line = encoding.strtolocal(pycompat.rawinput(prompt))
+ line = encoding.strtolocal(input(prompt))
# When stdin is in binary mode on Windows, it can cause
- # raw_input() to emit an extra trailing carriage return
+ # input() to emit an extra trailing carriage return
if pycompat.oslinesep == b'\r\n' and line.endswith(b'\r'):
line = line[:-1]
else:
@@ -2118,9 +2117,7 @@
"""
if not self._loggers:
return
- activeloggers = [
- l for l in pycompat.itervalues(self._loggers) if l.tracked(event)
- ]
+ activeloggers = [l for l in self._loggers.values() if l.tracked(event)]
if not activeloggers:
return
msg = msgfmt % msgargs
--- a/mercurial/unionrepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/unionrepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,7 +11,6 @@
allowing operations like diff and log with revsets.
"""
-from __future__ import absolute_import
from .i18n import _
from .pycompat import getattr
@@ -210,7 +209,7 @@
return False
-class unionrepository(object):
+class unionrepository:
"""Represents the union of data in 2 repositories.
Instances are not usable if constructed directly. Use ``instance()``
--- a/mercurial/upgrade.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/upgrade.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .i18n import _
from . import (
--- a/mercurial/upgrade_utils/actions.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/upgrade_utils/actions.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from ..i18n import _
from .. import (
@@ -46,7 +45,7 @@
OPTIMISATION = b'optimization'
-class improvement(object):
+class improvement:
"""Represents an improvement that can be made as part of an upgrade."""
### The following attributes should be defined for each subclass:
@@ -685,7 +684,7 @@
return newactions
-class UpgradeOperation(object):
+class UpgradeOperation:
"""represent the work to be done during an upgrade"""
def __init__(
--- a/mercurial/upgrade_utils/engine.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/upgrade_utils/engine.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import stat
--- a/mercurial/url.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/url.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,11 +7,9 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import base64
import socket
-import sys
from .i18n import _
from .pycompat import getattr
@@ -52,7 +50,7 @@
return s
-class passwordmgr(object):
+class passwordmgr:
def __init__(self, ui, passwddb):
self.ui = ui
self.passwddb = passwddb
@@ -241,19 +239,15 @@
if x.lower().startswith('proxy-')
}
self.send(b'CONNECT %s HTTP/1.0\r\n' % self.realhostport)
- for header in pycompat.iteritems(proxyheaders):
+ for header in proxyheaders.items():
self.send(b'%s: %s\r\n' % header)
self.send(b'\r\n')
# majority of the following code is duplicated from
# httplib.HTTPConnection as there are no adequate places to
- # override functions to provide the needed functionality
- # strict was removed in Python 3.4.
- kwargs = {}
- if not pycompat.ispy3:
- kwargs[b'strict'] = self.strict
+ # override functions to provide the needed functionality.
- res = self.response_class(self.sock, method=self._method, **kwargs)
+ res = self.response_class(self.sock, method=self._method)
while True:
version, status, reason = res._read_status()
@@ -348,16 +342,6 @@
keepalive.HTTPConnection.__init__(self, *args, **kwargs)
self._create_connection = createconn
- if sys.version_info < (2, 7, 7):
- # copied from 2.7.14, since old implementations directly call
- # socket.create_connection()
- def connect(self):
- self.sock = self._create_connection(
- (self.host, self.port), self.timeout, self.source_address
- )
- if self._tunnel_host:
- self._tunnel()
-
class logginghttphandler(httphandler):
"""HTTP handler that logs socket I/O."""
--- a/mercurial/urllibcompat.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/urllibcompat.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,12 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
+
+import http.server
+import urllib.error
+import urllib.parse
+import urllib.request
+import urllib.response
from .pycompat import getattr
from . import pycompat
@@ -12,7 +17,7 @@
_sysstr = pycompat.sysstr
-class _pycompatstub(object):
+class _pycompatstub:
def __init__(self):
self._aliases = {}
@@ -40,199 +45,109 @@
urlreq = _pycompatstub()
urlerr = _pycompatstub()
-if pycompat.ispy3:
- import urllib.parse
-
- urlreq._registeraliases(
- urllib.parse,
- (
- b"splitattr",
- b"splitpasswd",
- b"splitport",
- b"splituser",
- b"urlparse",
- b"urlunparse",
- ),
- )
- urlreq._registeralias(urllib.parse, b"parse_qs", b"parseqs")
- urlreq._registeralias(urllib.parse, b"parse_qsl", b"parseqsl")
- urlreq._registeralias(urllib.parse, b"unquote_to_bytes", b"unquote")
- import urllib.request
-
- urlreq._registeraliases(
- urllib.request,
- (
- b"AbstractHTTPHandler",
- b"BaseHandler",
- b"build_opener",
- b"FileHandler",
- b"FTPHandler",
- b"ftpwrapper",
- b"HTTPHandler",
- b"HTTPSHandler",
- b"install_opener",
- b"pathname2url",
- b"HTTPBasicAuthHandler",
- b"HTTPDigestAuthHandler",
- b"HTTPPasswordMgrWithDefaultRealm",
- b"ProxyHandler",
- b"Request",
- b"url2pathname",
- b"urlopen",
- ),
- )
- import urllib.response
-
- urlreq._registeraliases(
- urllib.response,
- (
- b"addclosehook",
- b"addinfourl",
- ),
- )
- import urllib.error
+urlreq._registeraliases(
+ urllib.parse,
+ (
+ b"splitattr",
+ b"splitpasswd",
+ b"splitport",
+ b"splituser",
+ b"urlparse",
+ b"urlunparse",
+ ),
+)
+urlreq._registeralias(urllib.parse, b"parse_qs", b"parseqs")
+urlreq._registeralias(urllib.parse, b"parse_qsl", b"parseqsl")
+urlreq._registeralias(urllib.parse, b"unquote_to_bytes", b"unquote")
- urlerr._registeraliases(
- urllib.error,
- (
- b"HTTPError",
- b"URLError",
- ),
- )
- import http.server
-
- httpserver._registeraliases(
- http.server,
- (
- b"HTTPServer",
- b"BaseHTTPRequestHandler",
- b"SimpleHTTPRequestHandler",
- b"CGIHTTPRequestHandler",
- ),
- )
-
- # urllib.parse.quote() accepts both str and bytes, decodes bytes
- # (if necessary), and returns str. This is wonky. We provide a custom
- # implementation that only accepts bytes and emits bytes.
- def quote(s, safe='/'):
- # bytestr has an __iter__ that emits characters. quote_from_bytes()
- # does an iteration and expects ints. We coerce to bytes to appease it.
- if isinstance(s, pycompat.bytestr):
- s = bytes(s)
- s = urllib.parse.quote_from_bytes(s, safe=safe)
- return s.encode('ascii', 'strict')
-
- # urllib.parse.urlencode() returns str. We use this function to make
- # sure we return bytes.
- def urlencode(query, doseq=False):
- s = urllib.parse.urlencode(query, doseq=doseq)
- return s.encode('ascii')
-
- urlreq.quote = quote
- urlreq.urlencode = urlencode
-
- def getfullurl(req):
- return req.full_url
-
- def gethost(req):
- return req.host
-
- def getselector(req):
- return req.selector
-
- def getdata(req):
- return req.data
-
- def hasdata(req):
- return req.data is not None
+urlreq._registeraliases(
+ urllib.request,
+ (
+ b"AbstractHTTPHandler",
+ b"BaseHandler",
+ b"build_opener",
+ b"FileHandler",
+ b"FTPHandler",
+ b"ftpwrapper",
+ b"HTTPHandler",
+ b"HTTPSHandler",
+ b"install_opener",
+ b"pathname2url",
+ b"HTTPBasicAuthHandler",
+ b"HTTPDigestAuthHandler",
+ b"HTTPPasswordMgrWithDefaultRealm",
+ b"ProxyHandler",
+ b"Request",
+ b"url2pathname",
+ b"urlopen",
+ ),
+)
-else:
- # pytype: disable=import-error
- import BaseHTTPServer
- import CGIHTTPServer
- import SimpleHTTPServer
- import urllib2
- import urllib
- import urlparse
+urlreq._registeraliases(
+ urllib.response,
+ (
+ b"addclosehook",
+ b"addinfourl",
+ ),
+)
- # pytype: enable=import-error
+urlerr._registeraliases(
+ urllib.error,
+ (
+ b"HTTPError",
+ b"URLError",
+ ),
+)
+
+httpserver._registeraliases(
+ http.server,
+ (
+ b"HTTPServer",
+ b"BaseHTTPRequestHandler",
+ b"SimpleHTTPRequestHandler",
+ b"CGIHTTPRequestHandler",
+ ),
+)
- urlreq._registeraliases(
- urllib,
- (
- b"addclosehook",
- b"addinfourl",
- b"ftpwrapper",
- b"pathname2url",
- b"quote",
- b"splitattr",
- b"splitpasswd",
- b"splitport",
- b"splituser",
- b"unquote",
- b"url2pathname",
- b"urlencode",
- ),
- )
- urlreq._registeraliases(
- urllib2,
- (
- b"AbstractHTTPHandler",
- b"BaseHandler",
- b"build_opener",
- b"FileHandler",
- b"FTPHandler",
- b"HTTPBasicAuthHandler",
- b"HTTPDigestAuthHandler",
- b"HTTPHandler",
- b"HTTPPasswordMgrWithDefaultRealm",
- b"HTTPSHandler",
- b"install_opener",
- b"ProxyHandler",
- b"Request",
- b"urlopen",
- ),
- )
- urlreq._registeraliases(
- urlparse,
- (
- b"urlparse",
- b"urlunparse",
- ),
- )
- urlreq._registeralias(urlparse, b"parse_qs", b"parseqs")
- urlreq._registeralias(urlparse, b"parse_qsl", b"parseqsl")
- urlerr._registeraliases(
- urllib2,
- (
- b"HTTPError",
- b"URLError",
- ),
- )
- httpserver._registeraliases(
- BaseHTTPServer,
- (
- b"HTTPServer",
- b"BaseHTTPRequestHandler",
- ),
- )
- httpserver._registeraliases(
- SimpleHTTPServer, (b"SimpleHTTPRequestHandler",)
- )
- httpserver._registeraliases(CGIHTTPServer, (b"CGIHTTPRequestHandler",))
+# urllib.parse.quote() accepts both str and bytes, decodes bytes
+# (if necessary), and returns str. This is wonky. We provide a custom
+# implementation that only accepts bytes and emits bytes.
+def quote(s, safe='/'):
+ # bytestr has an __iter__ that emits characters. quote_from_bytes()
+ # does an iteration and expects ints. We coerce to bytes to appease it.
+ if isinstance(s, pycompat.bytestr):
+ s = bytes(s)
+ s = urllib.parse.quote_from_bytes(s, safe=safe)
+ return s.encode('ascii', 'strict')
+
+
+# urllib.parse.urlencode() returns str. We use this function to make
+# sure we return bytes.
+def urlencode(query, doseq=False):
+ s = urllib.parse.urlencode(query, doseq=doseq)
+ return s.encode('ascii')
+
- def gethost(req):
- return req.get_host()
+urlreq.quote = quote
+urlreq.urlencode = urlencode
+
- def getselector(req):
- return req.get_selector()
+def getfullurl(req):
+ return req.full_url
+
+
+def gethost(req):
+ return req.host
- def getfullurl(req):
- return req.get_full_url()
+
+def getselector(req):
+ return req.selector
+
- def getdata(req):
- return req.get_data()
+def getdata(req):
+ return req.data
- def hasdata(req):
- return req.has_data()
+
+def hasdata(req):
+ return req.data is not None
--- a/mercurial/util.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/util.py Fri Mar 25 11:33:12 2022 -0400
@@ -13,7 +13,6 @@
hide platform-specific details from the core.
"""
-from __future__ import absolute_import, print_function
import abc
import collections
@@ -21,11 +20,11 @@
import errno
import gc
import hashlib
+import io
import itertools
import locale
import mmap
import os
-import platform as pyplatform
import re as remod
import shutil
import stat
@@ -76,10 +75,9 @@
cookielib = pycompat.cookielib
httplib = pycompat.httplib
-pickle = pycompat.pickle
safehasattr = pycompat.safehasattr
socketserver = pycompat.socketserver
-bytesio = pycompat.bytesio
+bytesio = io.BytesIO
# TODO deprecate stringio name, as it is a lie on Python 3.
stringio = bytesio
xmlrpclib = pycompat.xmlrpclib
@@ -189,7 +187,7 @@
warnings.filterwarnings('default', '', DeprecationWarning, 'mercurial')
warnings.filterwarnings('default', '', DeprecationWarning, 'hgext')
warnings.filterwarnings('default', '', DeprecationWarning, 'hgext3rd')
-if _dowarn and pycompat.ispy3:
+if _dowarn:
# silence warning emitted by passing user string to re.sub()
warnings.filterwarnings(
'ignore', 'bad escape', DeprecationWarning, 'mercurial'
@@ -233,7 +231,7 @@
assert k in DIGESTS
-class digester(object):
+class digester:
"""helper to compute digests.
This helper can be used to compute one or more digests given their name.
@@ -281,7 +279,7 @@
return None
-class digestchecker(object):
+class digestchecker:
"""file handle wrapper that additionally checks content against a given
size and digests.
@@ -331,7 +329,7 @@
_chunksize = 4096
-class bufferedinputpipe(object):
+class bufferedinputpipe:
"""a manually buffered input pipe
Python will not let us use buffered IO and lazy reading with 'polling' at
@@ -459,7 +457,7 @@
raise
-class fileobjectproxy(object):
+class fileobjectproxy:
"""A proxy around file objects that tells a watcher when events occur.
This type is intended to only be used for testing purposes. Think hard
@@ -695,7 +693,7 @@
}
-class socketproxy(object):
+class socketproxy:
"""A proxy around a socket that tells a watcher when events occur.
This is like ``fileobjectproxy`` except for sockets.
@@ -818,7 +816,7 @@
)
-class baseproxyobserver(object):
+class baseproxyobserver:
def __init__(self, fh, name, logdata, logdataapis):
self.fh = fh
self.name = name
@@ -1258,7 +1256,7 @@
return f
-class cow(object):
+class cow:
"""helper class to make copy-on-write easier
Call preparewrite before doing any writes.
@@ -1302,7 +1300,7 @@
# __setitem__() isn't called as of PyPy 5.8.0
def update(self, src, **f):
if isinstance(src, dict):
- src = pycompat.iteritems(src)
+ src = src.items()
for k, v in src:
self[k] = v
for k in f:
@@ -1351,7 +1349,7 @@
"""
-class transactional(object): # pytype: disable=ignored-metaclass
+class transactional: # pytype: disable=ignored-metaclass
"""Base class for making a transactional type into a context manager."""
__metaclass__ = abc.ABCMeta
@@ -1402,7 +1400,7 @@
yield enter_result
-class _lrucachenode(object):
+class _lrucachenode:
"""A node in a doubly linked list.
Holds a reference to nodes on either side as well as a key-value
@@ -1426,7 +1424,7 @@
self.cost = 0
-class lrucachedict(object):
+class lrucachedict:
"""Dict that caches most recent accesses and sets.
The dict consists of an actual backing dict - indexed by original
@@ -1757,7 +1755,7 @@
return f
-class propertycache(object):
+class propertycache:
def __init__(self, func):
self.func = func
self.name = func.__name__
@@ -2216,7 +2214,7 @@
_re2 = False
-class _re(object):
+class _re:
def _checkre2(self):
global _re2
global _re2_input
@@ -2418,7 +2416,7 @@
return temp
-class filestat(object):
+class filestat:
"""help to exactly detect change of a file
'stat' attribute is result of 'os.stat()' if specified 'path'
@@ -2524,7 +2522,7 @@
return not self == other
-class atomictempfile(object):
+class atomictempfile:
"""writable file object that atomically updates a file
All writes will go to a temporary copy of the original file. Call
@@ -2667,7 +2665,7 @@
fp.write(text)
-class chunkbuffer(object):
+class chunkbuffer:
"""Allow arbitrary sized chunks of data to be efficiently read from an
iterator over chunks of arbitrary size."""
@@ -2772,7 +2770,7 @@
yield s
-class cappedreader(object):
+class cappedreader:
"""A file object proxy that allows reading up to N bytes.
Given a source file object, instances of this type allow reading up to
@@ -2860,7 +2858,7 @@
)
-class transformingwriter(object):
+class transformingwriter:
"""Writable file wrapper to transform data by function"""
def __init__(self, fp, encode):
@@ -2906,50 +2904,10 @@
fromnativeeol = pycompat.identity
nativeeolwriter = pycompat.identity
-if pyplatform.python_implementation() == b'CPython' and sys.version_info < (
- 3,
- 0,
-):
- # There is an issue in CPython that some IO methods do not handle EINTR
- # correctly. The following table shows what CPython version (and functions)
- # are affected (buggy: has the EINTR bug, okay: otherwise):
- #
- # | < 2.7.4 | 2.7.4 to 2.7.12 | >= 3.0
- # --------------------------------------------------
- # fp.__iter__ | buggy | buggy | okay
- # fp.read* | buggy | okay [1] | okay
- #
- # [1]: fixed by changeset 67dc99a989cd in the cpython hg repo.
- #
- # Here we workaround the EINTR issue for fileobj.__iter__. Other methods
- # like "read*" work fine, as we do not support Python < 2.7.4.
- #
- # Although we can workaround the EINTR issue for fp.__iter__, it is slower:
- # "for x in fp" is 4x faster than "for x in iter(fp.readline, '')" in
- # CPython 2, because CPython 2 maintains an internal readahead buffer for
- # fp.__iter__ but not other fp.read* methods.
- #
- # On modern systems like Linux, the "read" syscall cannot be interrupted
- # when reading "fast" files like on-disk files. So the EINTR issue only
- # affects things like pipes, sockets, ttys etc. We treat "normal" (S_ISREG)
- # files approximately as "fast" files and use the fast (unsafe) code path,
- # to minimize the performance impact.
-
- def iterfile(fp):
- fastpath = True
- if type(fp) is file:
- fastpath = stat.S_ISREG(os.fstat(fp.fileno()).st_mode)
- if fastpath:
- return fp
- else:
- # fp.readline deals with EINTR correctly, use it as a workaround.
- return iter(fp.readline, b'')
-
-
-else:
- # PyPy and CPython 3 do not have the EINTR issue thus no workaround needed.
- def iterfile(fp):
- return fp
+
+# TODO delete since workaround variant for Python 2 no longer needed.
+def iterfile(fp):
+ return fp
def iterlines(iterator):
@@ -3008,7 +2966,7 @@
@attr.s
-class timedcmstats(object):
+class timedcmstats:
"""Stats information produced by the timedcm context manager on entering."""
# the starting value of the timer as a float (meaning and resulution is
@@ -3109,7 +3067,7 @@
raise error.ParseError(_(b"couldn't parse size: %s") % s)
-class hooks(object):
+class hooks:
"""A collection of hook functions that can be used to extend a
function's behavior. Hooks are called in lexicographic order,
based on the names of their sources."""
--- a/mercurial/utils/cborutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/cborutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,12 +5,9 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import struct
-import sys
-from .. import pycompat
# Very short very of RFC 7049...
#
@@ -175,9 +172,7 @@
"""
yield encodelength(MAJOR_TYPE_MAP, len(d))
- for key, value in sorted(
- pycompat.iteritems(d), key=lambda x: _mixedtypesortkey(x[0])
- ):
+ for key, value in sorted(d.items(), key=lambda x: _mixedtypesortkey(x[0])):
for chunk in streamencode(key):
yield chunk
for chunk in streamencode(value):
@@ -210,7 +205,7 @@
STREAM_ENCODERS = {
bytes: streamencodebytestring,
int: streamencodeint,
- pycompat.long: streamencodeint,
+ int: streamencodeint,
list: streamencodearray,
tuple: streamencodearray,
dict: streamencodemap,
@@ -250,16 +245,8 @@
"""Represents an error decoding CBOR."""
-if sys.version_info.major >= 3:
-
- def _elementtointeger(b, i):
- return b[i]
-
-
-else:
-
- def _elementtointeger(b, i):
- return ord(b[i])
+def _elementtointeger(b, i):
+ return b[i]
STRUCT_BIG_UBYTE = struct.Struct('>B')
@@ -496,7 +483,7 @@
return self
-class sansiodecoder(object):
+class sansiodecoder:
"""A CBOR decoder that doesn't perform its own I/O.
To use, construct an instance and feed it segments containing
@@ -989,7 +976,7 @@
return l
-class bufferingdecoder(object):
+class bufferingdecoder:
"""A CBOR decoder that buffers undecoded input.
This is a glorified wrapper around ``sansiodecoder`` that adds a buffering
--- a/mercurial/utils/compression.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/compression.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,8 +4,6 @@
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
-
import bz2
import collections
import zlib
@@ -34,7 +32,7 @@
)
-class propertycache(object):
+class propertycache:
def __init__(self, func):
self.func = func
self.name = func.__name__
@@ -49,7 +47,7 @@
obj.__dict__[self.name] = value
-class compressormanager(object):
+class compressormanager:
"""Holds registrations of various compression engines.
This class essentially abstracts the differences between compression
@@ -221,7 +219,7 @@
compengines = compressormanager()
-class compressionengine(object):
+class compressionengine:
"""Base class for compression engines.
Compression engines must implement the interface defined by this class.
@@ -340,7 +338,7 @@
raise NotImplementedError()
-class _CompressedStreamReader(object):
+class _CompressedStreamReader:
def __init__(self, fh):
if safehasattr(fh, 'unbufferedread'):
self._reader = fh.unbufferedread
@@ -484,7 +482,7 @@
def decompressorreader(self, fh):
return _GzipCompressedStreamReader(fh)
- class zlibrevlogcompressor(object):
+ class zlibrevlogcompressor:
def __init__(self, level=None):
self._level = level
@@ -628,7 +626,7 @@
def decompressorreader(self, fh):
return fh
- class nooprevlogcompressor(object):
+ class nooprevlogcompressor:
def compress(self, data):
return None
@@ -700,7 +698,7 @@
def decompressorreader(self, fh):
return _ZstdCompressedStreamReader(fh, self._module)
- class zstdrevlogcompressor(object):
+ class zstdrevlogcompressor:
def __init__(self, zstd, level=3):
# TODO consider omitting frame magic to save 4 bytes.
# This writes content sizes into the frame header. That is
@@ -784,7 +782,7 @@
# We need to format the docstring. So use a dummy object/type to hold it
# rather than mutating the original.
- class docobject(object):
+ class docobject:
pass
for name in compengines:
--- a/mercurial/utils/dateutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/dateutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import calendar
import datetime
--- a/mercurial/utils/hashutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/hashutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import hashlib
try:
--- a/mercurial/utils/procutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/procutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import errno
@@ -60,7 +59,7 @@
raise IOError(errno.EBADF, 'Bad file descriptor')
-class LineBufferedWrapper(object):
+class LineBufferedWrapper:
def __init__(self, orig):
self.orig = orig
@@ -81,7 +80,7 @@
def make_line_buffered(stream):
- if pycompat.ispy3 and not isinstance(stream, io.BufferedIOBase):
+ if not isinstance(stream, io.BufferedIOBase):
# On Python 3, buffered streams can be expected to subclass
# BufferedIOBase. This is definitively the case for the streams
# initialized by the interpreter. For unbuffered streams, we don't need
@@ -99,7 +98,7 @@
return stream
-class WriteAllWrapper(object):
+class WriteAllWrapper:
def __init__(self, orig):
self.orig = orig
@@ -122,7 +121,6 @@
def _make_write_all(stream):
- assert pycompat.ispy3
if isinstance(stream, WriteAllWrapper):
return stream
if isinstance(stream, io.BufferedIOBase):
@@ -134,52 +132,32 @@
return WriteAllWrapper(stream)
-if pycompat.ispy3:
- # Python 3 implements its own I/O streams. Unlike stdio of C library,
- # sys.stdin/stdout/stderr may be None if underlying fd is closed.
-
- # TODO: .buffer might not exist if std streams were replaced; we'll need
- # a silly wrapper to make a bytes stream backed by a unicode one.
+# Python 3 implements its own I/O streams. Unlike stdio of C library,
+# sys.stdin/stdout/stderr may be None if underlying fd is closed.
- if sys.stdin is None:
- stdin = BadFile()
- else:
- stdin = sys.stdin.buffer
- if sys.stdout is None:
- stdout = BadFile()
- else:
- stdout = _make_write_all(sys.stdout.buffer)
- if sys.stderr is None:
- stderr = BadFile()
- else:
- stderr = _make_write_all(sys.stderr.buffer)
+# TODO: .buffer might not exist if std streams were replaced; we'll need
+# a silly wrapper to make a bytes stream backed by a unicode one.
- if pycompat.iswindows:
- # Work around Windows bugs.
- stdout = platform.winstdout(stdout) # pytype: disable=module-attr
- stderr = platform.winstdout(stderr) # pytype: disable=module-attr
- if isatty(stdout):
- # The standard library doesn't offer line-buffered binary streams.
- stdout = make_line_buffered(stdout)
+if sys.stdin is None:
+ stdin = BadFile()
+else:
+ stdin = sys.stdin.buffer
+if sys.stdout is None:
+ stdout = BadFile()
else:
- # Python 2 uses the I/O streams provided by the C library.
- stdin = sys.stdin
- stdout = sys.stdout
- stderr = sys.stderr
- if pycompat.iswindows:
- # Work around Windows bugs.
- stdout = platform.winstdout(stdout) # pytype: disable=module-attr
- stderr = platform.winstdout(stderr) # pytype: disable=module-attr
- if isatty(stdout):
- if pycompat.iswindows:
- # The Windows C runtime library doesn't support line buffering.
- stdout = make_line_buffered(stdout)
- else:
- # glibc determines buffering on first write to stdout - if we
- # replace a TTY destined stdout with a pipe destined stdout (e.g.
- # pager), we want line buffering.
- stdout = os.fdopen(stdout.fileno(), 'wb', 1)
+ stdout = _make_write_all(sys.stdout.buffer)
+if sys.stderr is None:
+ stderr = BadFile()
+else:
+ stderr = _make_write_all(sys.stderr.buffer)
+if pycompat.iswindows:
+ # Work around Windows bugs.
+ stdout = platform.winstdout(stdout) # pytype: disable=module-attr
+ stderr = platform.winstdout(stderr) # pytype: disable=module-attr
+if isatty(stdout):
+ # The standard library doesn't offer line-buffered binary streams.
+ stdout = make_line_buffered(stdout)
findexe = platform.findexe
_gethgcmd = platform.gethgcmd
@@ -215,7 +193,7 @@
return _(b"killed by signal %d") % -code
-class _pfile(object):
+class _pfile:
"""File-like wrapper for a stream opened by subprocess.Popen()"""
def __init__(self, proc, fp):
@@ -364,7 +342,7 @@
def filter(s, cmd):
"""filter a string through a command that transforms its input to its
output"""
- for name, fn in pycompat.iteritems(_filtertable):
+ for name, fn in _filtertable.items():
if cmd.startswith(name):
return fn(s, cmd[len(name) :].lstrip())
return pipefilter(s, cmd)
@@ -470,7 +448,7 @@
env = dict(encoding.environ)
if environ:
- env.update((k, py2shell(v)) for k, v in pycompat.iteritems(environ))
+ env.update((k, py2shell(v)) for k, v in environ.items())
env[b'HG'] = hgexecutable()
return env
@@ -705,7 +683,7 @@
else:
- def runbgcommandpy3(
+ def runbgcommand(
cmd,
env,
shell=False,
@@ -788,128 +766,3 @@
returncode = p.wait
if record_wait is not None:
record_wait(returncode)
-
- def runbgcommandpy2(
- cmd,
- env,
- shell=False,
- stdout=None,
- stderr=None,
- ensurestart=True,
- record_wait=None,
- stdin_bytes=None,
- ):
- """Spawn a command without waiting for it to finish.
-
-
- When `record_wait` is not None, the spawned process will not be fully
- detached and the `record_wait` argument will be called with a the
- `Subprocess.wait` function for the spawned process. This is mostly
- useful for developers that need to make sure the spawned process
- finished before a certain point. (eg: writing test)"""
- if pycompat.isdarwin:
- # avoid crash in CoreFoundation in case another thread
- # calls gui() while we're calling fork().
- gui()
-
- # double-fork to completely detach from the parent process
- # based on http://code.activestate.com/recipes/278731
- if record_wait is None:
- pid = os.fork()
- if pid:
- if not ensurestart:
- # Even though we're not waiting on the child process,
- # we still must call waitpid() on it at some point so
- # it's not a zombie/defunct. This is especially relevant for
- # chg since the parent process won't die anytime soon.
- # We use a thread to make the overhead tiny.
- def _do_wait():
- os.waitpid(pid, 0)
-
- t = threading.Thread(target=_do_wait)
- t.daemon = True
- t.start()
- return
- # Parent process
- (_pid, status) = os.waitpid(pid, 0)
- if os.WIFEXITED(status):
- returncode = os.WEXITSTATUS(status)
- else:
- returncode = -(os.WTERMSIG(status))
- if returncode != 0:
- # The child process's return code is 0 on success, an errno
- # value on failure, or 255 if we don't have a valid errno
- # value.
- #
- # (It would be slightly nicer to return the full exception info
- # over a pipe as the subprocess module does. For now it
- # doesn't seem worth adding that complexity here, though.)
- if returncode == 255:
- returncode = errno.EINVAL
- raise OSError(
- returncode,
- b'error running %r: %s'
- % (cmd, os.strerror(returncode)),
- )
- return
-
- returncode = 255
- stdin = None
-
- try:
- if record_wait is None:
- # Start a new session
- os.setsid()
- # connect stdin to devnull to make sure the subprocess can't
- # muck up that stream for mercurial.
- if stdin_bytes is None:
- stdin = open(os.devnull, b'r')
- else:
- stdin = pycompat.unnamedtempfile()
- stdin.write(stdin_bytes)
- stdin.flush()
- stdin.seek(0)
-
- if stdout is None:
- stdout = open(os.devnull, b'w')
- if stderr is None:
- stderr = open(os.devnull, b'w')
-
- p = subprocess.Popen(
- cmd,
- shell=shell,
- env=env,
- close_fds=True,
- stdin=stdin,
- stdout=stdout,
- stderr=stderr,
- )
- if record_wait is not None:
- record_wait(p.wait)
- returncode = 0
- except EnvironmentError as ex:
- returncode = ex.errno & 0xFF
- if returncode == 0:
- # This shouldn't happen, but just in case make sure the
- # return code is never 0 here.
- returncode = 255
- except Exception:
- returncode = 255
- finally:
- # mission accomplished, this child needs to exit and not
- # continue the hg process here.
- if stdin is not None:
- stdin.close()
- if record_wait is None:
- os._exit(returncode)
-
- if pycompat.ispy3:
- # This branch is more robust, because it avoids running python
- # code (hence gc finalizers, like sshpeer.__del__, which
- # blocks). But we can't easily do the equivalent in py2,
- # because of the lack of start_new_session=True flag. Given
- # that the py2 branch should die soon, the short-lived
- # duplication seems acceptable.
- runbgcommand = runbgcommandpy3
- else:
- runbgcommand = runbgcommandpy2
--- a/mercurial/utils/repoviewutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/repoviewutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
### Nearest subset relation
# Nearest subset of filter X is a filter Y so that:
--- a/mercurial/utils/resourceutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/resourceutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import imp
import os
--- a/mercurial/utils/storageutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/storageutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import re
import struct
--- a/mercurial/utils/stringutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/stringutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import ast
import codecs
@@ -497,7 +496,7 @@
@attr.s(hash=True)
-class mailmapping(object):
+class mailmapping:
"""Represents a username/email key or value in
a mailmap file"""
@@ -965,6 +964,4 @@
def evalpythonliteral(s):
"""Evaluate a string containing a Python literal expression"""
# We could backport our tokenizer hack to rewrite '' to u'' if we want
- if pycompat.ispy3:
- return ast.literal_eval(s.decode('latin1'))
- return ast.literal_eval(s)
+ return ast.literal_eval(s.decode('latin1'))
--- a/mercurial/utils/urlutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/utils/urlutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -54,7 +54,7 @@
)
-class url(object):
+class url:
r"""Reliable URL parser.
This parses URLs and provides attributes for the following
@@ -453,7 +453,7 @@
"""list all the (name, paths) in the passed ui"""
result = []
if target_path is None:
- for name, paths in sorted(pycompat.iteritems(ui.paths)):
+ for name, paths in sorted(ui.paths.items()):
for p in paths:
result.append((name, p))
@@ -832,7 +832,7 @@
return new_paths
-class path(object):
+class path:
"""Represents an individual path and its configuration."""
def __init__(
@@ -919,7 +919,7 @@
# Now process the sub-options. If a sub-option is registered, its
# attribute will always be present. The value will be None if there
# was no valid sub-option.
- for suboption, (attr, func) in pycompat.iteritems(_pathsuboptions):
+ for suboption, (attr, func) in _pathsuboptions.items():
if suboption not in sub_options:
setattr(self, attr, None)
continue
@@ -945,7 +945,7 @@
This is intended to be used for presentation purposes.
"""
d = {}
- for subopt, (attr, _func) in pycompat.iteritems(_pathsuboptions):
+ for subopt, (attr, _func) in _pathsuboptions.items():
value = getattr(self, attr)
if value is not None:
d[subopt] = value
--- a/mercurial/verify.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/verify.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import os
@@ -55,7 +54,7 @@
)
-class verifier(object):
+class verifier:
def __init__(self, repo, level=None):
self.repo = repo.unfiltered()
self.ui = repo.ui
@@ -406,11 +405,11 @@
_(b'checking'), unit=_(b'manifests'), total=len(subdirs)
)
- for subdir, linkrevs in pycompat.iteritems(subdirnodes):
+ for subdir, linkrevs in subdirnodes.items():
subdirfilenodes = self._verifymanifest(
linkrevs, subdir, storefiles, subdirprogress
)
- for f, onefilenodes in pycompat.iteritems(subdirfilenodes):
+ for f, onefilenodes in subdirfilenodes.items():
filenodes.setdefault(f, {}).update(onefilenodes)
if not dir and subdirnodes:
@@ -575,7 +574,7 @@
# cross-check
if f in filenodes:
- fns = [(v, k) for k, v in pycompat.iteritems(filenodes[f])]
+ fns = [(v, k) for k, v in filenodes[f].items()]
for lr, node in sorted(fns):
msg = _(b"manifest refers to unknown revision %s")
self._err(lr, msg % short(node), f)
--- a/mercurial/vfs.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/vfs.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import errno
@@ -47,7 +46,7 @@
checkandavoid()
-class abstractvfs(object):
+class abstractvfs:
"""Abstract base class; cannot be instantiated"""
# default directory separator for vfs
@@ -607,7 +606,7 @@
return self.vfs.join(path, *insidef)
-class closewrapbase(object):
+class closewrapbase:
"""Base class of wrapper, which hooks closing
Do not instantiate outside of the vfs layer.
@@ -653,7 +652,7 @@
self._closer.close(self._origfh)
-class backgroundfilecloser(object):
+class backgroundfilecloser:
"""Coordinates background closing of file handles on multiple threads."""
def __init__(self, ui, expectedcount=-1):
--- a/mercurial/win32.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/win32.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import ctypes
import ctypes.wintypes as wintypes
--- a/mercurial/windows.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/windows.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import getpass
@@ -54,7 +53,7 @@
umask = 0o022
-class mixedfilemodewrapper(object):
+class mixedfilemodewrapper:
"""Wraps a file handle when it is opened in read/write mode.
fopen() and fdopen() on Windows have a specific-to-Windows requirement
@@ -131,7 +130,7 @@
return self._fp.readlines(*args, **kwargs)
-class fdproxy(object):
+class fdproxy:
"""Wraps osutil.posixfile() to override the name attribute to reflect the
underlying file name.
"""
@@ -163,8 +162,7 @@
# PyFile_FromFd() ignores the name, and seems to report fp.name as the
# underlying file descriptor.
- if pycompat.ispy3:
- fp = fdproxy(name, fp)
+ fp = fdproxy(name, fp)
# The position when opening in append mode is implementation defined, so
# make it consistent with other platforms, which position at EOF.
@@ -216,7 +214,7 @@
return encoding.unitolocal(pw)
-class winstdout(object):
+class winstdout:
"""Some files on Windows misbehave.
When writing to a broken pipe, EINVAL instead of EPIPE may be raised.
@@ -227,7 +225,6 @@
def __init__(self, fp):
self.fp = fp
- self.throttle = not pycompat.ispy3 and _isatty(fp)
def __getattr__(self, key):
return getattr(self.fp, key)
@@ -240,17 +237,7 @@
def write(self, s):
try:
- if not self.throttle:
- return self.fp.write(s)
- # This is workaround for "Not enough space" error on
- # writing large size of data to console.
- limit = 16000
- l = len(s)
- start = 0
- while start < l:
- end = start + limit
- self.fp.write(s[start:end])
- start = end
+ return self.fp.write(s)
except IOError as inst:
if inst.errno != 0 and not win32.lasterrorwaspipeerror(inst):
raise
@@ -671,7 +658,7 @@
return False
-class cachestat(object):
+class cachestat:
def __init__(self, path):
pass
--- a/mercurial/wireprotoframing.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/wireprotoframing.py Fri Mar 25 11:33:12 2022 -0400
@@ -9,7 +9,6 @@
# protocol. For details about the protocol, see
# `hg help internals.wireprotocol`.
-from __future__ import absolute_import
import collections
import struct
@@ -123,7 +122,7 @@
def humanflags(mapping, value):
"""Convert a numeric flags value to a human value, using a mapping table."""
- namemap = {v: k for k, v in pycompat.iteritems(mapping)}
+ namemap = {v: k for k, v in mapping.items()}
flags = []
val = 1
while value >= val:
@@ -135,7 +134,7 @@
@attr.s(slots=True)
-class frameheader(object):
+class frameheader:
"""Represents the data in a frame header."""
length = attr.ib()
@@ -147,7 +146,7 @@
@attr.s(slots=True, repr=False)
-class frame(object):
+class frame:
"""Represents a parsed frame."""
requestid = attr.ib()
@@ -160,7 +159,7 @@
@encoding.strmethod
def __repr__(self):
typename = b'<unknown 0x%02x>' % self.typeid
- for name, value in pycompat.iteritems(FRAME_TYPES):
+ for name, value in FRAME_TYPES.items():
if value == self.typeid:
typename = name
break
@@ -590,7 +589,7 @@
)
-class bufferingcommandresponseemitter(object):
+class bufferingcommandresponseemitter:
"""Helper object to emit command response frames intelligently.
Raw command response data is likely emitted in chunks much smaller
@@ -700,7 +699,7 @@
# mechanism.
-class identityencoder(object):
+class identityencoder:
"""Encoder for the "identity" stream encoding profile."""
def __init__(self, ui):
@@ -716,7 +715,7 @@
return b''
-class identitydecoder(object):
+class identitydecoder:
"""Decoder for the "identity" stream encoding profile."""
def __init__(self, ui, extraobjs):
@@ -729,7 +728,7 @@
return data
-class zlibencoder(object):
+class zlibencoder:
def __init__(self, ui):
import zlib
@@ -750,7 +749,7 @@
return res
-class zlibdecoder(object):
+class zlibdecoder:
def __init__(self, ui, extraobjs):
import zlib
@@ -762,15 +761,10 @@
self._decompressor = zlib.decompressobj()
def decode(self, data):
- # Python 2's zlib module doesn't use the buffer protocol and can't
- # handle all bytes-like types.
- if not pycompat.ispy3 and isinstance(data, bytearray):
- data = bytes(data)
-
return self._decompressor.decompress(data)
-class zstdbaseencoder(object):
+class zstdbaseencoder:
def __init__(self, level):
from . import zstd
@@ -798,7 +792,7 @@
super(zstd8mbencoder, self).__init__(3)
-class zstdbasedecoder(object):
+class zstdbasedecoder:
def __init__(self, maxwindowsize):
from . import zstd
@@ -848,7 +842,7 @@
STREAM_ENCODERS_ORDER.append(b'identity')
-class stream(object):
+class stream:
"""Represents a logical unidirectional series of frames."""
def __init__(self, streamid, active=False):
@@ -1001,7 +995,7 @@
}
-class serverreactor(object):
+class serverreactor:
"""Holds state of a server handling frame-based protocol requests.
This class is the "brain" of the unified frame-based protocol server
@@ -1689,7 +1683,7 @@
return self._makeerrorresult(_(b'server already errored'))
-class commandrequest(object):
+class commandrequest:
"""Represents a request to run a command."""
def __init__(self, requestid, name, args, datafh=None, redirect=None):
@@ -1701,7 +1695,7 @@
self.state = b'pending'
-class clientreactor(object):
+class clientreactor:
"""Holds state of a client issuing frame-based protocol requests.
This is like ``serverreactor`` but for client-side state.
--- a/mercurial/wireprotoserver.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/wireprotoserver.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import contextlib
import struct
@@ -57,7 +56,7 @@
@interfaceutil.implementer(wireprototypes.baseprotocolhandler)
-class httpv1protocolhandler(object):
+class httpv1protocolhandler:
def __init__(self, req, ui, checkperm):
self._req = req
self._ui = ui
@@ -375,7 +374,7 @@
@interfaceutil.implementer(wireprototypes.baseprotocolhandler)
-class sshv1protocolhandler(object):
+class sshv1protocolhandler:
"""Handler for requests services via version 1 of SSH protocol."""
def __init__(self, ui, fin, fout):
@@ -521,7 +520,7 @@
)
-class sshserver(object):
+class sshserver:
def __init__(self, ui, repo, logfh=None):
self._ui = ui
self._repo = repo
--- a/mercurial/wireprototypes.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/wireprototypes.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from .node import (
bin,
@@ -40,14 +39,14 @@
}
-class bytesresponse(object):
+class bytesresponse:
"""A wire protocol response consisting of raw bytes."""
def __init__(self, data):
self.data = data
-class ooberror(object):
+class ooberror:
"""wireproto reply: failure of a batch of operation
Something failed during a batch call. The error message is stored in
@@ -58,7 +57,7 @@
self.message = message
-class pushres(object):
+class pushres:
"""wireproto reply: success with simple integer return
The call was successful and returned an integer contained in `self.res`.
@@ -69,7 +68,7 @@
self.output = output
-class pusherr(object):
+class pusherr:
"""wireproto reply: failure
The call failed. The `self.res` attribute contains the error message.
@@ -80,7 +79,7 @@
self.output = output
-class streamres(object):
+class streamres:
"""wireproto reply: binary stream
The call was successful and the result is a stream.
@@ -97,7 +96,7 @@
self.prefer_uncompressed = prefer_uncompressed
-class streamreslegacy(object):
+class streamreslegacy:
"""wireproto reply: uncompressed binary stream
The call was successful and the result is a stream.
@@ -244,7 +243,7 @@
"""
-class commandentry(object):
+class commandentry:
"""Represents a declared wire protocol command."""
def __init__(
@@ -407,7 +406,7 @@
@attr.s
-class encodedresponse(object):
+class encodedresponse:
"""Represents response data that is already content encoded.
Wire protocol version 2 only.
@@ -421,7 +420,7 @@
@attr.s
-class alternatelocationresponse(object):
+class alternatelocationresponse:
"""Represents a response available at an alternate location.
Instances are sent in place of actual response objects when the server
@@ -440,7 +439,7 @@
@attr.s
-class indefinitebytestringresponse(object):
+class indefinitebytestringresponse:
"""Represents an object to be encoded to an indefinite length bytestring.
Instances are initialized from an iterable of chunks, with each chunk being
--- a/mercurial/wireprotov1peer.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/wireprotov1peer.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,11 +5,11 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import sys
import weakref
+from concurrent import futures
from .i18n import _
from .node import bin
from .pycompat import (
@@ -80,15 +80,14 @@
assert all(escapearg(k) == k for k in argsdict)
args = b','.join(
- b'%s=%s' % (escapearg(k), escapearg(v))
- for k, v in pycompat.iteritems(argsdict)
+ b'%s=%s' % (escapearg(k), escapearg(v)) for k, v in argsdict.items()
)
cmds.append(b'%s %s' % (op, args))
return b';'.join(cmds)
-class unsentfuture(pycompat.futures.Future):
+class unsentfuture(futures.Future):
"""A Future variation to represent an unsent command.
Because we buffer commands and don't submit them immediately, calling
@@ -99,7 +98,7 @@
def result(self, timeout=None):
if self.done():
- return pycompat.futures.Future.result(self, timeout)
+ return futures.Future.result(self, timeout)
self._peerexecutor.sendcommands()
@@ -110,7 +109,7 @@
@interfaceutil.implementer(repository.ipeercommandexecutor)
-class peerexecutor(object):
+class peerexecutor:
def __init__(self, peer):
self._peer = peer
self._sent = False
@@ -154,7 +153,7 @@
# a batchable one and refuse to service it.
def addcall():
- f = pycompat.futures.Future()
+ f = futures.Future()
self._futures.add(f)
self._calls.append((command, args, fn, f))
return f
@@ -194,7 +193,7 @@
# cycle between us and futures.
for f in self._futures:
if isinstance(f, unsentfuture):
- f.__class__ = pycompat.futures.Future
+ f.__class__ = futures.Future
f._peerexecutor = None
calls = self._calls
@@ -258,7 +257,7 @@
# hard and it is easy to encounter race conditions, deadlocks, etc.
# concurrent.futures already solves these problems and its thread pool
# executor has minimal overhead. So we use it.
- self._responseexecutor = pycompat.futures.ThreadPoolExecutor(1)
+ self._responseexecutor = futures.ThreadPoolExecutor(1)
self._responsef = self._responseexecutor.submit(
self._readbatchresponse, states, wireresults
)
@@ -438,7 +437,7 @@
self.requirecap(b'getbundle', _(b'look up remote changes'))
opts = {}
bundlecaps = kwargs.get(b'bundlecaps') or set()
- for key, value in pycompat.iteritems(kwargs):
+ for key, value in kwargs.items():
if value is None:
continue
keytype = wireprototypes.GETBUNDLE_ARGUMENTS.get(key)
--- a/mercurial/wireprotov1server.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/wireprotov1server.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import binascii
import os
@@ -236,7 +235,7 @@
def branchmap(repo, proto):
branchmap = repo.branchmap()
heads = []
- for branch, nodes in pycompat.iteritems(branchmap):
+ for branch, nodes in branchmap.items():
branchname = urlreq.quote(encoding.fromlocal(branch))
branchnodes = wireprototypes.encodelist(nodes)
heads.append(b'%s %s' % (branchname, branchnodes))
@@ -433,7 +432,7 @@
opts = options(
b'getbundle', wireprototypes.GETBUNDLE_ARGUMENTS.keys(), others
)
- for k, v in pycompat.iteritems(opts):
+ for k, v in opts.items():
keytype = wireprototypes.GETBUNDLE_ARGUMENTS[k]
if keytype == b'nodes':
opts[k] = wireprototypes.decodelist(v)
--- a/mercurial/worker.py Tue Mar 22 03:19:01 2022 +0100
+++ b/mercurial/worker.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,10 +5,10 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import errno
import os
+import pickle
import signal
import sys
import threading
@@ -27,7 +27,6 @@
error,
pycompat,
scmutil,
- util,
)
@@ -65,51 +64,39 @@
return min(max(countcpus(), 4), 32)
-if pycompat.ispy3:
-
- def ismainthread():
- return threading.current_thread() == threading.main_thread()
-
- class _blockingreader(object):
- def __init__(self, wrapped):
- self._wrapped = wrapped
-
- # Do NOT implement readinto() by making it delegate to
- # _wrapped.readinto(), since that is unbuffered. The unpickler is fine
- # with just read() and readline(), so we don't need to implement it.
-
- def readline(self):
- return self._wrapped.readline()
-
- # issue multiple reads until size is fulfilled
- def read(self, size=-1):
- if size < 0:
- return self._wrapped.readall()
-
- buf = bytearray(size)
- view = memoryview(buf)
- pos = 0
-
- while pos < size:
- ret = self._wrapped.readinto(view[pos:])
- if not ret:
- break
- pos += ret
-
- del view
- del buf[pos:]
- return bytes(buf)
+def ismainthread():
+ return threading.current_thread() == threading.main_thread()
-else:
+class _blockingreader:
+ def __init__(self, wrapped):
+ self._wrapped = wrapped
+
+ # Do NOT implement readinto() by making it delegate to
+ # _wrapped.readinto(), since that is unbuffered. The unpickler is fine
+ # with just read() and readline(), so we don't need to implement it.
+
+ def readline(self):
+ return self._wrapped.readline()
- def ismainthread():
- # pytype: disable=module-attr
- return isinstance(threading.current_thread(), threading._MainThread)
- # pytype: enable=module-attr
+ # issue multiple reads until size is fulfilled
+ def read(self, size=-1):
+ if size < 0:
+ return self._wrapped.readall()
+
+ buf = bytearray(size)
+ view = memoryview(buf)
+ pos = 0
- def _blockingreader(wrapped):
- return wrapped
+ while pos < size:
+ ret = self._wrapped.readinto(view[pos:])
+ if not ret:
+ break
+ pos += ret
+
+ del view
+ del buf[pos:]
+ return bytes(buf)
if pycompat.isposix or pycompat.iswindows:
@@ -256,7 +243,7 @@
os.close(w)
os.close(rfd)
for result in func(*(staticargs + (pargs,))):
- os.write(wfd, util.pickle.dumps(result))
+ os.write(wfd, pickle.dumps(result))
return 0
ret = scmutil.callcatch(ui, workerfunc)
@@ -292,7 +279,11 @@
while openpipes > 0:
for key, events in selector.select():
try:
- res = util.pickle.load(_blockingreader(key.fileobj))
+ # The pytype error likely goes away on a modern version of
+ # pytype having a modern typeshed snapshot.
+ # pytype: disable=wrong-arg-types
+ res = pickle.load(_blockingreader(key.fileobj))
+ # pytype: enable=wrong-arg-types
if hasretval and res[0]:
retval.update(res[1])
else:
--- a/rust/Cargo.lock Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/Cargo.lock Fri Mar 25 11:33:12 2022 -0400
@@ -9,19 +9,25 @@
checksum = "ee2a4ec343196209d6594e19543ae87a39f96d5534d7174822a3ad825dd6ed7e"
[[package]]
+name = "ahash"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "739f4a8db6605981345c5654f3a85b056ce52f37a39d34da03f25bf2151ea16e"
+
+[[package]]
name = "aho-corasick"
-version = "0.7.15"
+version = "0.7.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7404febffaa47dac81aa44dba71523c9d069b1bdc50a77db41195149e17f68e5"
+checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
dependencies = [
"memchr",
]
[[package]]
name = "ansi_term"
-version = "0.11.0"
+version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
dependencies = [
"winapi",
]
@@ -45,9 +51,9 @@
[[package]]
name = "bitflags"
-version = "1.2.1"
+version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
+checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitmaps"
@@ -68,10 +74,19 @@
]
[[package]]
+name = "block-buffer"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0bf7fe51849ea569fd452f37822f606a5cabb684dc918707a0193fd4664ff324"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "byteorder"
-version = "1.3.4"
+version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de"
+checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
[[package]]
name = "bytes-cast"
@@ -129,9 +144,9 @@
[[package]]
name = "clap"
-version = "2.33.3"
+version = "2.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002"
+checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
dependencies = [
"ansi_term",
"atty",
@@ -149,6 +164,12 @@
checksum = "cd51eab21ab4fd6a3bf889e2d0958c0a6e3a61ad04260325e919e652a2a62826"
[[package]]
+name = "convert_case"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
+
+[[package]]
name = "cpufeatures"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -158,6 +179,15 @@
]
[[package]]
+name = "cpufeatures"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95059428f66df56b63431fdb4e1947ed2190586af5c5a8a8b71122bdf5a7f469"
+dependencies = [
+ "libc",
+]
+
+[[package]]
name = "cpython"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -166,7 +196,6 @@
"libc",
"num-traits",
"paste",
- "python27-sys",
"python3-sys",
]
@@ -181,22 +210,12 @@
[[package]]
name = "crossbeam-channel"
-version = "0.4.4"
+version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b153fe7cbef478c567df0f972e02e6d736db11affe43dfc9c56a9374d1adfb87"
-dependencies = [
- "crossbeam-utils 0.7.2",
- "maybe-uninit",
-]
-
-[[package]]
-name = "crossbeam-channel"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "dca26ee1f8d361640700bde38b2c37d8c22b3ce2d360e1fc1c74ea4b0aa7d775"
+checksum = "e54ea8bc3fb1ee042f5aace6e3c6e025d3874866da222930f70ce62aceba0bfa"
dependencies = [
"cfg-if 1.0.0",
- "crossbeam-utils 0.8.1",
+ "crossbeam-utils",
]
[[package]]
@@ -207,7 +226,7 @@
dependencies = [
"cfg-if 1.0.0",
"crossbeam-epoch",
- "crossbeam-utils 0.8.1",
+ "crossbeam-utils",
]
[[package]]
@@ -218,7 +237,7 @@
dependencies = [
"cfg-if 1.0.0",
"const_fn",
- "crossbeam-utils 0.8.1",
+ "crossbeam-utils",
"lazy_static",
"memoffset",
"scopeguard",
@@ -226,17 +245,6 @@
[[package]]
name = "crossbeam-utils"
-version = "0.7.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8"
-dependencies = [
- "autocfg",
- "cfg-if 0.1.10",
- "lazy_static",
-]
-
-[[package]]
-name = "crossbeam-utils"
version = "0.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02d96d1e189ef58269ebe5b97953da3274d83a93af647c2ddd6f9dab28cedb8d"
@@ -247,6 +255,15 @@
]
[[package]]
+name = "crypto-common"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4600d695eb3f6ce1cd44e6e291adceb2cc3ab12f20a33777ecd0bf6eba34e06"
+dependencies = [
+ "generic-array",
+]
+
+[[package]]
name = "ctor"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -258,20 +275,22 @@
[[package]]
name = "derive_more"
-version = "0.99.11"
+version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cb0e6161ad61ed084a36ba71fbba9e3ac5aee3606fb607fe08da6acbcf3d8c"
+checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
+ "convert_case",
"proc-macro2",
"quote",
+ "rustc_version",
"syn",
]
[[package]]
-name = "difference"
-version = "2.0.0"
+name = "diff"
+version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "524cbf6897b527295dff137cec09ecf3a05f4fddffd7dfcd1585403449e74198"
+checksum = "0e25ea47919b1560c4e3b7fe0aaab9becf5b84a10325ddf7db0f0ba5e1026499"
[[package]]
name = "digest"
@@ -283,6 +302,16 @@
]
[[package]]
+name = "digest"
+version = "0.10.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8cb780dce4f9a8f5c087362b3a4595936b2019e7c8b30f2c3e9a7e94e6ae9837"
+dependencies = [
+ "block-buffer 0.10.2",
+ "crypto-common",
+]
+
+[[package]]
name = "either"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -290,9 +319,9 @@
[[package]]
name = "env_logger"
-version = "0.7.1"
+version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
+checksum = "0b2cf0344971ee6c64c31be0d530793fba457d322dfec2810c453d0ef228f9c3"
dependencies = [
"atty",
"humantime",
@@ -302,10 +331,19 @@
]
[[package]]
+name = "fastrand"
+version = "1.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3fcf0cee53519c866c09b5de1f6c56ff9d647101f81c1964fa632e148896cdf"
+dependencies = [
+ "instant",
+]
+
+[[package]]
name = "flate2"
-version = "1.0.19"
+version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7411863d55df97a419aa64cb4d2f167103ea9d767e2c54a1868b7ac3f6b47129"
+checksum = "1e6988e897c1c9c485f43b47a529cef42fde0547f9d8d41a7062518f1d8fc53f"
dependencies = [
"cfg-if 1.0.0",
"crc32fast",
@@ -373,6 +411,16 @@
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
[[package]]
+name = "hashbrown"
+version = "0.9.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d7afe4a420e3fe79967a00898cc1f4db7c8a49a9333a29f8a4bd76a253d5cd04"
+dependencies = [
+ "ahash",
+ "rayon",
+]
+
+[[package]]
name = "hermit-abi"
version = "0.1.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -395,26 +443,27 @@
"byteorder",
"bytes-cast",
"clap",
- "crossbeam-channel 0.4.4",
+ "crossbeam-channel",
"derive_more",
"flate2",
"format-bytes",
+ "hashbrown",
"home",
"im-rc",
- "itertools",
+ "itertools 0.10.3",
"lazy_static",
"libc",
"log",
"memmap2",
"micro-timer",
"pretty_assertions",
- "rand 0.8.4",
+ "rand 0.8.5",
"rand_distr",
"rand_pcg",
"rayon",
"regex",
"same-file",
- "sha-1",
+ "sha-1 0.10.0",
"stable_deref_trait",
"tempfile",
"twox-hash",
@@ -426,7 +475,7 @@
version = "0.1.0"
dependencies = [
"cpython",
- "crossbeam-channel 0.4.4",
+ "crossbeam-channel",
"env_logger",
"hg-core",
"libc",
@@ -446,12 +495,9 @@
[[package]]
name = "humantime"
-version = "1.3.0"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
-dependencies = [
- "quick-error",
-]
+checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4"
[[package]]
name = "im-rc"
@@ -468,6 +514,15 @@
]
[[package]]
+name = "instant"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
+dependencies = [
+ "cfg-if 1.0.0",
+]
+
+[[package]]
name = "itertools"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -477,6 +532,15 @@
]
[[package]]
+name = "itertools"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a9a9d19fa1e79b6215ff29b9d6880b706147f16e9b1dbb1e4e5947b5b02bc5e3"
+dependencies = [
+ "either",
+]
+
+[[package]]
name = "jobserver"
version = "0.1.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -493,9 +557,9 @@
[[package]]
name = "libc"
-version = "0.2.81"
+version = "0.2.119"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1482821306169ec4d07f6aca392a4681f66c75c9918aa49641a2595db64053cb"
+checksum = "1bf2e165bb3457c8e098ea76f3e3bc9db55f87aa90d52d0e6be741470916aaa4"
[[package]]
name = "libm"
@@ -516,30 +580,24 @@
[[package]]
name = "log"
-version = "0.4.11"
+version = "0.4.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "4fabed175da42fed1fa0746b0ea71f412aa9d35e76e95e59b192c64b9dc2bf8b"
+checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
]
[[package]]
-name = "maybe-uninit"
-version = "2.0.0"
+name = "memchr"
+version = "2.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
-
-[[package]]
-name = "memchr"
-version = "2.3.4"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ee1c47aaa256ecabcaea351eae4a9b01ef39ed810004e298d2511ed284b1525"
+checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
[[package]]
name = "memmap2"
-version = "0.4.0"
+version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "de5d3112c080d58ce560081baeaab7e1e864ca21795ddbf533d5b1842bb1ecf8"
+checksum = "057a3db23999c867821a7a59feb06a578fcb03685e983dff90daf9e7d24ac08f"
dependencies = [
"libc",
"stable_deref_trait",
@@ -556,9 +614,9 @@
[[package]]
name = "micro-timer"
-version = "0.3.1"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2620153e1d903d26b72b89f0e9c48d8c4756cba941c185461dddc234980c298c"
+checksum = "5de32cb59a062672560d6f0842c4aa7714727457b9fe2daf8987d995a176a405"
dependencies = [
"micro-timer-macros",
"scopeguard",
@@ -566,9 +624,9 @@
[[package]]
name = "micro-timer-macros"
-version = "0.3.1"
+version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e28a3473e6abd6e9aab36aaeef32ad22ae0bd34e79f376643594c2b152ec1c5d"
+checksum = "cee948b94700125b52dfb68dd17c19f6326696c1df57f92c05ee857463c93ba1"
dependencies = [
"proc-macro2",
"quote",
@@ -651,13 +709,13 @@
[[package]]
name = "pretty_assertions"
-version = "0.6.1"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3f81e1644e1b54f5a68959a29aa86cde704219254669da328ecfdf6a1f09d427"
+checksum = "76d5b548b725018ab5496482b45cb8bef21e9fed1858a6d674e3a8a0f0bb5d50"
dependencies = [
"ansi_term",
"ctor",
- "difference",
+ "diff",
"output_vt100",
]
@@ -671,16 +729,6 @@
]
[[package]]
-name = "python27-sys"
-version = "0.7.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "94670354e264300dde81a5864cbb6bfc9d56ac3dcf3a278c32cb52f816f4dfd1"
-dependencies = [
- "libc",
- "regex",
-]
-
-[[package]]
name = "python3-sys"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -691,12 +739,6 @@
]
[[package]]
-name = "quick-error"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
-
-[[package]]
name = "quote"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -715,19 +757,18 @@
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
- "rand_hc 0.2.0",
+ "rand_hc",
]
[[package]]
name = "rand"
-version = "0.8.4"
+version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
+checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha 0.3.1",
"rand_core 0.6.3",
- "rand_hc 0.3.1",
]
[[package]]
@@ -770,12 +811,12 @@
[[package]]
name = "rand_distr"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "964d548f8e7d12e102ef183a0de7e98180c9f8729f555897a857b96e48122d2f"
+checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
dependencies = [
"num-traits",
- "rand 0.8.4",
+ "rand 0.8.5",
]
[[package]]
@@ -788,15 +829,6 @@
]
[[package]]
-name = "rand_hc"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
-dependencies = [
- "rand_core 0.6.3",
-]
-
-[[package]]
name = "rand_pcg"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -816,9 +848,9 @@
[[package]]
name = "rayon"
-version = "1.5.0"
+version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8b0d8e0819fadc20c74ea8373106ead0600e3a67ef1fe8da56e39b9ae7275674"
+checksum = "c06aca804d41dbc8ba42dfd964f0d01334eceb64314b9ecf7c5fad5188a06d90"
dependencies = [
"autocfg",
"crossbeam-deque",
@@ -828,40 +860,42 @@
[[package]]
name = "rayon-core"
-version = "1.9.0"
+version = "1.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9ab346ac5921dc62ffa9f89b7a773907511cdfa5490c572ae9be1be33e8afa4a"
+checksum = "d78120e2c850279833f1dd3582f730c4ab53ed95aeaaaa862a2a5c71b1656d8e"
dependencies = [
- "crossbeam-channel 0.5.0",
+ "crossbeam-channel",
"crossbeam-deque",
- "crossbeam-utils 0.8.1",
+ "crossbeam-utils",
"lazy_static",
"num_cpus",
]
[[package]]
name = "redox_syscall"
-version = "0.1.57"
+version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce"
+checksum = "8380fe0152551244f0747b1bf41737e0f8a74f97a14ccefd1148187271634f3c"
+dependencies = [
+ "bitflags",
+]
[[package]]
name = "regex"
-version = "1.4.2"
+version = "1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "38cf2c13ed4745de91a5eb834e11c00bcc3709e773173b2ce4c56c9fbde04b9c"
+checksum = "1a11647b6b25ff05a515cb92c365cec08801e83423a235b51e231e1808747286"
dependencies = [
"aho-corasick",
"memchr",
"regex-syntax",
- "thread_local",
]
[[package]]
name = "regex-syntax"
-version = "0.6.21"
+version = "0.6.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3b181ba2dcf07aaccad5448e8ead58db5b742cf85dfe035e2227f137a539a189"
+checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
[[package]]
name = "remove_dir_all"
@@ -892,6 +926,15 @@
]
[[package]]
+name = "rustc_version"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
+dependencies = [
+ "semver",
+]
+
+[[package]]
name = "same-file"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -907,19 +950,36 @@
checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
[[package]]
+name = "semver"
+version = "1.0.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a4a3381e03edd24287172047536f20cabde766e2cd3e65e6b00fb3af51c4f38d"
+
+[[package]]
name = "sha-1"
version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4cfa741c5832d0ef7fab46cabed29c2aae926db0b11bb2069edd8db5e64e16"
dependencies = [
- "block-buffer",
+ "block-buffer 0.9.0",
"cfg-if 1.0.0",
- "cpufeatures",
- "digest",
+ "cpufeatures 0.1.4",
+ "digest 0.9.0",
"opaque-debug",
]
[[package]]
+name = "sha-1"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "028f48d513f9678cda28f6e4064755b3fbb2af6acd672f2c209b62323f7aea0f"
+dependencies = [
+ "cfg-if 1.0.0",
+ "cpufeatures 0.2.1",
+ "digest 0.10.2",
+]
+
+[[package]]
name = "sized-chunks"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -960,13 +1020,13 @@
[[package]]
name = "tempfile"
-version = "3.1.0"
+version = "3.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
+checksum = "5cdb1ef4eaeeaddc8fbd371e5017057064af0911902ef36b39801f67cc6d79e4"
dependencies = [
- "cfg-if 0.1.10",
+ "cfg-if 1.0.0",
+ "fastrand",
"libc",
- "rand 0.7.3",
"redox_syscall",
"remove_dir_all",
"winapi",
@@ -991,15 +1051,6 @@
]
[[package]]
-name = "thread_local"
-version = "1.0.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d40c6d1b69745a6ec6fb1ca717914848da4b44ae29d9b3080cbee91d72a69b14"
-dependencies = [
- "lazy_static",
-]
-
-[[package]]
name = "time"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1012,12 +1063,12 @@
[[package]]
name = "twox-hash"
-version = "1.6.0"
+version = "1.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "04f8ab788026715fa63b31960869617cba39117e520eb415b0139543e325ab59"
+checksum = "4ee73e6e4924fe940354b8d4d98cad5231175d615cd855b758adc658c0aac6a0"
dependencies = [
- "cfg-if 0.1.10",
- "rand 0.7.3",
+ "cfg-if 1.0.0",
+ "rand 0.8.5",
"static_assertions",
]
@@ -1029,9 +1080,9 @@
[[package]]
name = "unicode-width"
-version = "0.1.8"
+version = "0.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3"
+checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
[[package]]
name = "unicode-xid"
@@ -1063,7 +1114,7 @@
dependencies = [
"hex",
"rand 0.7.3",
- "sha-1",
+ "sha-1 0.9.6",
]
[[package]]
@@ -1123,18 +1174,18 @@
[[package]]
name = "zstd"
-version = "0.5.3+zstd.1.4.5"
+version = "0.5.4+zstd.1.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "01b32eaf771efa709e8308605bbf9319bf485dc1503179ec0469b611937c0cd8"
+checksum = "69996ebdb1ba8b1517f61387a883857818a66c8a295f487b1ffd8fd9d2c82910"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
-version = "2.0.5+zstd.1.4.5"
+version = "2.0.6+zstd.1.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1cfb642e0d27f64729a639c52db457e0ae906e7bc6f5fe8f5c453230400f1055"
+checksum = "98aa931fb69ecee256d44589d19754e61851ae4769bf963b385119b1cc37a49e"
dependencies = [
"libc",
"zstd-sys",
@@ -1142,12 +1193,12 @@
[[package]]
name = "zstd-sys"
-version = "1.4.17+zstd.1.4.5"
+version = "1.4.18+zstd.1.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b89249644df056b522696b1bb9e7c18c87e8ffa3e2f0dc3b0155875d6498f01b"
+checksum = "a1e6e8778706838f43f771d80d37787cb2fe06dafe89dd3aebaf6721b9eaec81"
dependencies = [
"cc",
"glob",
- "itertools",
+ "itertools 0.9.0",
"libc",
]
--- a/rust/README.rst Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/README.rst Fri Mar 25 11:33:12 2022 -0400
@@ -40,8 +40,8 @@
Special features
================
-You might want to check the `features` section in ``hg-cpython/Cargo.toml``.
-It may contain features that might be interesting to try out.
+In the future, compile-time opt-ins may be added
+to the `features` section in ``hg-cpython/Cargo.toml``.
To use features from the Makefile, use the `HG_RUST_FEATURES` environment
variable: for instance `HG_RUST_FEATURES="some-feature other-feature"`
--- a/rust/hg-core/Cargo.toml Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/hg-core/Cargo.toml Fri Mar 25 11:33:12 2022 -0400
@@ -9,39 +9,40 @@
name = "hg"
[dependencies]
-bitflags = "1.2"
-bytes-cast = "0.2"
-byteorder = "1.3.4"
-derive_more = "0.99"
-home = "0.5"
-im-rc = "15.0.*"
-itertools = "0.9"
+bitflags = "1.3.2"
+bytes-cast = "0.2.0"
+byteorder = "1.4.3"
+derive_more = "0.99.17"
+hashbrown = { version = "0.9.1", features = ["rayon"] }
+home = "0.5.3"
+im-rc = "15.0.0"
+itertools = "0.10.3"
lazy_static = "1.4.0"
-libc = "0.2"
-rand = "0.8.4"
+libc = "0.2.119"
+rand = "0.8.5"
rand_pcg = "0.3.1"
-rand_distr = "0.4.2"
-rayon = "1.3.0"
-regex = "1.3.9"
-sha-1 = "0.9.6"
-twox-hash = "1.5.0"
+rand_distr = "0.4.3"
+rayon = "1.5.1"
+regex = "1.5.5"
+sha-1 = "0.10.0"
+twox-hash = "1.6.2"
same-file = "1.0.6"
stable_deref_trait = "1.2.0"
-tempfile = "3.1.0"
-crossbeam-channel = "0.4"
-micro-timer = "0.3.0"
-log = "0.4.8"
-memmap2 = {version = "0.4", features = ["stable_deref_trait"]}
+tempfile = "3.3.0"
+crossbeam-channel = "0.5.2"
+micro-timer = "0.4.0"
+log = "0.4.14"
+memmap2 = { version = "0.5.3", features = ["stable_deref_trait"] }
zstd = "0.5.3"
format-bytes = "0.3.0"
# We don't use the `miniz-oxide` backend to not change rhg benchmarks and until
# we have a clearer view of which backend is the fastest.
[dependencies.flate2]
-version = "1.0.16"
+version = "1.0.22"
features = ["zlib"]
default-features = false
[dev-dependencies]
-clap = "*"
-pretty_assertions = "0.6.1"
+clap = "2.34.0"
+pretty_assertions = "1.1.0"
--- a/rust/hg-core/src/dirstate_tree/dirstate_map.rs Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/hg-core/src/dirstate_tree/dirstate_map.rs Fri Mar 25 11:33:12 2022 -0400
@@ -22,7 +22,7 @@
use crate::DirstateParents;
use crate::DirstateStatus;
use crate::EntryState;
-use crate::FastHashMap;
+use crate::FastHashbrownMap as FastHashMap;
use crate::PatternFileWarning;
use crate::StatusError;
use crate::StatusOptions;
@@ -585,13 +585,11 @@
.next()
.expect("expected at least one inclusive ancestor");
loop {
- // TODO: can we avoid allocating an owned key in cases where the
- // map already contains that key, without introducing double
- // lookup?
- let child_node = child_nodes
+ let (_, child_node) = child_nodes
.make_mut(on_disk, unreachable_bytes)?
- .entry(to_cow(ancestor_path))
- .or_default();
+ .raw_entry_mut()
+ .from_key(ancestor_path.base_name())
+ .or_insert_with(|| (to_cow(ancestor_path), Node::default()));
if let Some(next) = inclusive_ancestor_paths.next() {
each_ancestor(child_node);
ancestor_path = next;
--- a/rust/hg-core/src/lib.rs Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/hg-core/src/lib.rs Fri Mar 25 11:33:12 2022 -0400
@@ -56,6 +56,11 @@
/// write access to your repository, you have other issues.
pub type FastHashMap<K, V> = HashMap<K, V, RandomXxHashBuilder64>;
+// TODO: should this be the default `FastHashMap` for all of hg-core, not just
+// dirstate_tree? How does XxHash compare with AHash, hashbrown’s default?
+pub type FastHashbrownMap<K, V> =
+ hashbrown::HashMap<K, V, RandomXxHashBuilder64>;
+
#[derive(Debug, PartialEq)]
pub enum DirstateMapError {
PathNotFound(HgPathBuf),
--- a/rust/hg-core/src/repo.rs Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/hg-core/src/repo.rs Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
use crate::dirstate_tree::owning::OwningDirstateMap;
use crate::errors::HgResultExt;
use crate::errors::{HgError, IoResultExt};
-use crate::exit_codes;
use crate::lock::{try_with_lock_no_wait, LockError};
use crate::manifest::{Manifest, Manifestlog};
use crate::revlog::filelog::Filelog;
@@ -160,31 +159,8 @@
requirements::load(Vfs { base: &shared_path })?
.contains(requirements::SHARESAFE_REQUIREMENT);
- if share_safe && !source_is_share_safe {
- return Err(match config
- .get(b"share", b"safe-mismatch.source-not-safe")
- {
- Some(b"abort") | None => HgError::abort(
- "abort: share source does not support share-safe requirement\n\
- (see `hg help config.format.use-share-safe` for more information)",
- exit_codes::ABORT,
- ),
- _ => HgError::unsupported("share-safe downgrade"),
- }
- .into());
- } else if source_is_share_safe && !share_safe {
- return Err(
- match config.get(b"share", b"safe-mismatch.source-safe") {
- Some(b"abort") | None => HgError::abort(
- "abort: version mismatch: source uses share-safe \
- functionality while the current share does not\n\
- (see `hg help config.format.use-share-safe` for more information)",
- exit_codes::ABORT,
- ),
- _ => HgError::unsupported("share-safe upgrade"),
- }
- .into(),
- );
+ if share_safe != source_is_share_safe {
+ return Err(HgError::unsupported("share-safe mismatch").into());
}
if share_safe {
--- a/rust/hg-cpython/Cargo.toml Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/hg-cpython/Cargo.toml Fri Mar 25 11:33:12 2022 -0400
@@ -8,25 +8,12 @@
name='rusthg'
crate-type = ["cdylib"]
-[features]
-default = ["python3"]
-
-# Features to build an extension module:
-python27 = ["cpython/python27-sys", "cpython/extension-module-2-7"]
-python3 = ["cpython/python3-sys", "cpython/extension-module"]
-
-# Enable one of these features to build a test executable linked to libpython:
-# e.g. cargo test --no-default-features --features python27-bin
-python27-bin = ["cpython/python27-sys"]
-python3-bin = ["cpython/python3-sys"]
-
[dependencies]
-cpython = { version = "0.7.0", default-features = false }
-crossbeam-channel = "0.4"
+cpython = { version = "0.7.0", features = ["extension-module"] }
+crossbeam-channel = "0.5.2"
hg-core = { path = "../hg-core"}
-libc = "0.2"
-log = "0.4.8"
-env_logger = "0.7.1"
+libc = "0.2.119"
+log = "0.4.14"
+env_logger = "0.9.0"
stable_deref_trait = "1.2.0"
vcsgraph = "0.2.0"
-
--- a/rust/hg-cpython/src/cindex.rs Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/hg-cpython/src/cindex.rs Fri Mar 25 11:33:12 2022 -0400
@@ -18,7 +18,7 @@
use hg::{Graph, GraphError, Revision, WORKING_DIRECTORY_REVISION};
use libc::{c_int, ssize_t};
-const REVLOG_CABI_VERSION: c_int = 2;
+const REVLOG_CABI_VERSION: c_int = 3;
#[repr(C)]
pub struct Revlog_CAPI {
@@ -29,6 +29,10 @@
index: *mut revlog_capi::RawPyObject,
rev: ssize_t,
) -> *const Node,
+ fast_rank: unsafe extern "C" fn(
+ index: *mut revlog_capi::RawPyObject,
+ rev: ssize_t,
+ ) -> ssize_t,
index_parents: unsafe extern "C" fn(
index: *mut revlog_capi::RawPyObject,
rev: c_int,
@@ -173,6 +177,20 @@
}
}
+impl vcsgraph::graph::RankedGraph for Index {
+ fn rank(
+ &self,
+ rev: Revision,
+ ) -> Result<vcsgraph::graph::Rank, vcsgraph::graph::GraphReadError> {
+ match unsafe {
+ (self.capi.fast_rank)(self.index.as_ptr(), rev as ssize_t)
+ } {
+ -1 => Err(vcsgraph::graph::GraphReadError::InconsistentGraphData),
+ rank => Ok(rank as usize),
+ }
+ }
+}
+
impl RevlogIndex for Index {
/// Note C return type is Py_ssize_t (hence signed), but we shall
/// force it to unsigned, because it's a length
--- a/rust/hg-cpython/src/dagops.rs Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/hg-cpython/src/dagops.rs Fri Mar 25 11:33:12 2022 -0400
@@ -14,6 +14,8 @@
use hg::dagops;
use hg::Revision;
use std::collections::HashSet;
+use vcsgraph::ancestors::node_rank;
+use vcsgraph::graph::{Parents, Rank};
use crate::revlog::pyindex_to_graph;
@@ -31,6 +33,18 @@
Ok(as_set)
}
+/// Computes the rank, i.e. the number of ancestors including itself,
+/// of a node represented by its parents.
+pub fn rank(
+ py: Python,
+ index: PyObject,
+ p1r: Revision,
+ p2r: Revision,
+) -> PyResult<Rank> {
+ node_rank(&pyindex_to_graph(py, index)?, &Parents([p1r, p2r]))
+ .map_err(|e| GraphError::pynew_from_vcsgraph(py, e))
+}
+
/// Create the module, with `__package__` given from parent
pub fn init_module(py: Python, package: &str) -> PyResult<PyModule> {
let dotted_name = &format!("{}.dagop", package);
@@ -42,6 +56,11 @@
"headrevs",
py_fn!(py, headrevs(index: PyObject, revs: PyObject)),
)?;
+ m.add(
+ py,
+ "rank",
+ py_fn!(py, rank(index: PyObject, p1r: Revision, p2r: Revision)),
+ )?;
let sys = PyModule::import(py, "sys")?;
let sys_modules: PyDict = sys.get(py, "modules")?.extract(py)?;
--- a/rust/hg-cpython/src/lib.rs Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/hg-cpython/src/lib.rs Fri Mar 25 11:33:12 2022 -0400
@@ -62,7 +62,7 @@
Ok(())
});
-#[cfg(not(any(feature = "python27-bin", feature = "python3-bin")))]
+#[cfg(not(feature = "python3-bin"))]
#[test]
#[ignore]
fn libpython_must_be_linked_to_run_tests() {
--- a/rust/rhg/Cargo.toml Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/rhg/Cargo.toml Fri Mar 25 11:33:12 2022 -0400
@@ -8,16 +8,16 @@
edition = "2018"
[dependencies]
-atty = "0.2"
+atty = "0.2.14"
hg-core = { path = "../hg-core"}
chrono = "0.4.19"
-clap = "2.33.1"
-derive_more = "0.99"
+clap = "2.34.0"
+derive_more = "0.99.17"
home = "0.5.3"
lazy_static = "1.4.0"
-log = "0.4.11"
-micro-timer = "0.3.1"
-regex = "1.3.9"
-env_logger = "0.7.1"
+log = "0.4.14"
+micro-timer = "0.4.0"
+regex = "1.5.5"
+env_logger = "0.9.0"
format-bytes = "0.3.0"
users = "0.11.0"
--- a/rust/rhg/src/main.rs Tue Mar 22 03:19:01 2022 +0100
+++ b/rust/rhg/src/main.rs Fri Mar 25 11:33:12 2022 -0400
@@ -643,6 +643,11 @@
&[b"blackbox", b"share", b"sparse", b"narrow", b"*"];
fn check_extensions(config: &Config) -> Result<(), CommandError> {
+ if let Some(b"*") = config.get(b"rhg", b"ignored-extensions") {
+ // All extensions are to be ignored, nothing to do here
+ return Ok(());
+ }
+
let enabled: HashSet<&[u8]> = config
.get_section_keys(b"extensions")
.into_iter()
--- a/setup.py Tue Mar 22 03:19:01 2022 +0100
+++ b/setup.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,99 +5,24 @@
# 'python setup.py --help' for more options
import os
-# Mercurial will never work on Python 3 before 3.5 due to a lack
-# of % formatting on bytestrings, and can't work on 3.6.0 or 3.6.1
-# due to a bug in % formatting in bytestrings.
-# We cannot support Python 3.5.0, 3.5.1, 3.5.2 because of bug in
-# codecs.escape_encode() where it raises SystemError on empty bytestring
-# bug link: https://bugs.python.org/issue25270
+# Mercurial can't work on 3.6.0 or 3.6.1 due to a bug in % formatting
+# in bytestrings.
supportedpy = ','.join(
[
- '>=2.7.4',
- '!=3.0.*',
- '!=3.1.*',
- '!=3.2.*',
- '!=3.3.*',
- '!=3.4.*',
- '!=3.5.0',
- '!=3.5.1',
- '!=3.5.2',
- '!=3.6.0',
- '!=3.6.1',
+ '>=3.6.2',
]
)
import sys, platform
import sysconfig
-if sys.version_info[0] >= 3:
- printf = eval('print')
- libdir_escape = 'unicode_escape'
- def sysstr(s):
- return s.decode('latin-1')
-
-
-else:
- libdir_escape = 'string_escape'
-
- def printf(*args, **kwargs):
- f = kwargs.get('file', sys.stdout)
- end = kwargs.get('end', '\n')
- f.write(b' '.join(args) + end)
-
- def sysstr(s):
- return s
+def sysstr(s):
+ return s.decode('latin-1')
-# Attempt to guide users to a modern pip - this means that 2.6 users
-# should have a chance of getting a 4.2 release, and when we ratchet
-# the version requirement forward again hopefully everyone will get
-# something that works for them.
-if sys.version_info < (2, 7, 4, 'final'):
- pip_message = (
- 'This may be due to an out of date pip. '
- 'Make sure you have pip >= 9.0.1.'
- )
- try:
- import pip
-
- pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
- if pip_version < (9, 0, 1):
- pip_message = (
- 'Your pip version is out of date, please install '
- 'pip >= 9.0.1. pip {} detected.'.format(pip.__version__)
- )
- else:
- # pip is new enough - it must be something else
- pip_message = ''
- except Exception:
- pass
- error = """
-Mercurial does not support Python older than 2.7.4.
-Python {py} detected.
-{pip}
-""".format(
- py=sys.version_info, pip=pip_message
- )
- printf(error, file=sys.stderr)
- sys.exit(1)
-
import ssl
-try:
- ssl.SSLContext
-except AttributeError:
- error = """
-The `ssl` module does not have the `SSLContext` class. This indicates an old
-Python version which does not support modern security features (which were
-added to Python 2.7 as part of "PEP 466"). Please make sure you have installed
-at least Python 2.7.9 or a Python version with backports of these security
-features.
-"""
- printf(error, file=sys.stderr)
- sys.exit(1)
-
# ssl.HAS_TLSv1* are preferred to check support but they were added in Python
# 3.7. Prior to CPython commit 6e8cda91d92da72800d891b2fc2073ecbc134d98
# (backported to the 3.7 branch), ssl.PROTOCOL_TLSv1_1 / ssl.PROTOCOL_TLSv1_2
@@ -117,14 +42,10 @@
version enabling these features (likely this requires the OpenSSL version to
be at least 1.0.1).
"""
- printf(error, file=sys.stderr)
+ print(error, file=sys.stderr)
sys.exit(1)
-if sys.version_info[0] >= 3:
- DYLIB_SUFFIX = sysconfig.get_config_vars()['EXT_SUFFIX']
-else:
- # deprecated in Python 3
- DYLIB_SUFFIX = sysconfig.get_config_vars()['SO']
+DYLIB_SUFFIX = sysconfig.get_config_vars()['EXT_SUFFIX']
# Solaris Python packaging brain damage
try:
@@ -292,7 +213,7 @@
return p.returncode, out, err
-class hgcommand(object):
+class hgcommand:
def __init__(self, cmd, env):
self.cmd = cmd
self.env = env
@@ -302,8 +223,8 @@
returncode, out, err = runcmd(cmd, self.env)
err = filterhgerr(err)
if err or returncode != 0:
- printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
- printf(err, file=sys.stderr)
+ print("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
+ print(err, file=sys.stderr)
return b''
return out
@@ -536,7 +457,7 @@
if hgrustext != 'cpython' and hgrustext is not None:
if hgrustext:
msg = 'unknown HGWITHRUSTEXT value: %s' % hgrustext
- printf(msg, file=sys.stderr)
+ print(msg, file=sys.stderr)
hgrustext = None
self.rust = hgrustext is not None
self.no_rust = not self.rust
@@ -810,12 +731,9 @@
# Copy the pythonXY.dll next to the binary so that it runs
# without tampering with PATH.
- fsdecode = lambda x: x
- if sys.version_info[0] >= 3:
- fsdecode = os.fsdecode
dest = os.path.join(
os.path.dirname(self.hgtarget),
- fsdecode(dllbasename),
+ os.fsdecode(dllbasename),
)
if not os.path.exists(dest):
@@ -823,19 +741,18 @@
# Also overwrite python3.dll so that hgext.git is usable.
# TODO: also handle the MSYS flavor
- if sys.version_info[0] >= 3:
- python_x = os.path.join(
- os.path.dirname(fsdecode(buf.value)),
- "python3.dll",
+ python_x = os.path.join(
+ os.path.dirname(os.fsdecode(buf.value)),
+ "python3.dll",
+ )
+
+ if os.path.exists(python_x):
+ dest = os.path.join(
+ os.path.dirname(self.hgtarget),
+ os.path.basename(python_x),
)
- if os.path.exists(python_x):
- dest = os.path.join(
- os.path.dirname(self.hgtarget),
- os.path.basename(python_x),
- )
-
- shutil.copy(python_x, dest)
+ shutil.copy(python_x, dest)
if not pythonlib:
log.warn(
@@ -850,14 +767,10 @@
f.write(b'/* this file is autogenerated by setup.py */\n')
f.write(b'#define HGPYTHONLIB "%s"\n' % pythonlib)
- macros = None
- if sys.version_info[0] >= 3:
- macros = [('_UNICODE', None), ('UNICODE', None)]
-
objects = self.compiler.compile(
['mercurial/exewrapper.c'],
output_dir=self.build_temp,
- macros=macros,
+ macros=[('_UNICODE', None), ('UNICODE', None)],
)
self.compiler.link_executable(
objects, self.hgtarget, libraries=[], output_dir=self.build_temp
@@ -1183,7 +1096,7 @@
)
continue
- data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape))
+ data = data.replace(b'@LIBDIR@', libdir.encode('unicode_escape'))
with open(outfile, 'wb') as fp:
fp.write(data)
@@ -1324,27 +1237,12 @@
'hgdemandimport',
]
-# The pygit2 dependency dropped py2 support with the 1.0 release in Dec 2019.
-# Prior releases do not build at all on Windows, because Visual Studio 2008
-# doesn't understand C 11. Older Linux releases are buggy.
-if sys.version_info[0] == 2:
- packages.remove('hgext.git')
-
-
for name in os.listdir(os.path.join('mercurial', 'templates')):
if name != '__pycache__' and os.path.isdir(
os.path.join('mercurial', 'templates', name)
):
packages.append('mercurial.templates.%s' % name)
-if sys.version_info[0] == 2:
- packages.extend(
- [
- 'mercurial.thirdparty.concurrent',
- 'mercurial.thirdparty.concurrent.futures',
- ]
- )
-
if 'HG_PY2EXE_EXTRA_INSTALL_PACKAGES' in os.environ:
# py2exe can't cope with namespace packages very well, so we have to
# install any hgext3rd.* extensions that we want in the final py2exe
@@ -1476,19 +1374,9 @@
cargocmd = ['cargo', 'rustc', '--release']
- feature_flags = []
-
- cargocmd.append('--no-default-features')
- if sys.version_info[0] == 2:
- feature_flags.append('python27')
- elif sys.version_info[0] == 3:
- feature_flags.append('python3')
-
rust_features = env.get("HG_RUST_FEATURES")
if rust_features:
- feature_flags.append(rust_features)
-
- cargocmd.extend(('--features', " ".join(feature_flags)))
+ cargocmd.extend(('--features', rust_features))
cargocmd.append('--')
if sys.platform == 'darwin':
@@ -1640,7 +1528,7 @@
# the cygwinccompiler package is not available on some Python
# distributions like the ones from the optware project for Synology
# DiskStation boxes
- class HackedMingw32CCompiler(object):
+ class HackedMingw32CCompiler:
pass
@@ -1763,9 +1651,7 @@
if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[1].splitlines()
if version:
- version = version[0]
- if sys.version_info[0] == 3:
- version = version.decode('utf-8')
+ version = version[0].decode('utf-8')
xcode4 = version.startswith('Xcode') and StrictVersion(
version.split()[1]
) >= StrictVersion('4.0')
--- a/tests/artifacts/scripts/generate-churning-bundle.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/artifacts/scripts/generate-churning-bundle.py Fri Mar 25 11:33:12 2022 -0400
@@ -17,7 +17,6 @@
#
# Running with `chg` in your path and `CHGHG` set is recommended for speed.
-from __future__ import absolute_import, print_function
import hashlib
import os
--- a/tests/autodiff.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/autodiff.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# Extension dedicated to test patch.diff() upgrade modes
-from __future__ import absolute_import
from mercurial import (
error,
--- a/tests/basic_test_result.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/basic_test_result.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import sys
import unittest
--- a/tests/blackbox-readonly-dispatch.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/blackbox-readonly-dispatch.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
import os
from mercurial import (
dispatch,
--- a/tests/bruterebase.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/bruterebase.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial import (
error,
--- a/tests/check-perf-code.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/check-perf-code.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
#
# check-perf-code - (historical) portability checker for contrib/perf.py
-from __future__ import absolute_import
import os
import sys
--- a/tests/common-pattern.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/common-pattern.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
# common patterns in test at can safely be replaced
-from __future__ import absolute_import
import os
--- a/tests/crashgetbundler.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/crashgetbundler.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from mercurial.i18n import _
from mercurial import changegroup, error, extensions
--- a/tests/drawdag.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/drawdag.py Fri Mar 25 11:33:12 2022 -0400
@@ -80,7 +80,6 @@
# split: A -> B, C # 1 to many
# prune: A, B, C # many to nothing
"""
-from __future__ import absolute_import, print_function
import collections
import itertools
@@ -266,7 +265,7 @@
return dict(edges)
-class simplefilectx(object):
+class simplefilectx:
def __init__(self, path, data):
self._data = data
self._path = path
--- a/tests/dumbhttp.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/dumbhttp.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
#!/usr/bin/env python
-from __future__ import absolute_import
"""
Small and dumb HTTP server for use in tests.
@@ -38,7 +37,7 @@
sys.stderr.flush()
-class simplehttpservice(object):
+class simplehttpservice:
def __init__(self, host, port):
self.address = (host, port)
--- a/tests/dummysmtpd.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/dummysmtpd.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
"""dummy SMTP server for use in tests"""
-from __future__ import absolute_import
import asyncore
import optparse
--- a/tests/dummyssh Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/dummyssh Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
-from __future__ import absolute_import
import os
import shlex
--- a/tests/f Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/f Fri Mar 25 11:33:12 2022 -0400
@@ -23,7 +23,6 @@
md5sum.py
"""
-from __future__ import absolute_import
import binascii
import glob
--- a/tests/failfilemerge.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/failfilemerge.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# extension to emulate interrupting filemerge._filemerge
-from __future__ import absolute_import
from mercurial import (
error,
--- a/tests/fakedirstatewritetime.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/fakedirstatewritetime.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# - 'workingctx._poststatusfixup()' (= 'repo.status()')
# - 'committablectx.markcommitted()'
-from __future__ import absolute_import
from mercurial import (
context,
--- a/tests/fakemergerecord.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/fakemergerecord.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
#
#
-from __future__ import absolute_import
from mercurial import (
mergestate as mergestatemod,
--- a/tests/fakepatchtime.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/fakepatchtime.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
# extension to emulate invoking 'patch.internalpatch()' at the time
# specified by '[fakepatchtime] fakenow'
-from __future__ import absolute_import
from mercurial import (
extensions,
--- a/tests/filterpyflakes.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/filterpyflakes.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
# Filter output by pyflakes to control which warnings we check
-from __future__ import absolute_import, print_function
import re
import sys
--- a/tests/filtertraceback.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/filtertraceback.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
# Filters traceback lines from stdin.
-from __future__ import absolute_import, print_function
import io
import sys
--- a/tests/flagprocessorext.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/flagprocessorext.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# coding=UTF-8
-from __future__ import absolute_import
import base64
import zlib
--- a/tests/fsmonitor-run-tests.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/fsmonitor-run-tests.py Fri Mar 25 11:33:12 2022 -0400
@@ -11,8 +11,6 @@
# Watchman and runs the Mercurial tests against it. This ensures that the global
# version of Watchman isn't affected by anything this test does.
-from __future__ import absolute_import
-from __future__ import print_function
import argparse
import contextlib
--- a/tests/generate-working-copy-states.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/generate-working-copy-states.py Fri Mar 25 11:33:12 2022 -0400
@@ -29,7 +29,6 @@
# $ hg forget *_*_*-untracked
# $ rm *_*_missing-*
-from __future__ import absolute_import, print_function
import os
import sys
--- a/tests/get-with-headers.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/get-with-headers.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
"""This does HTTP GET requests given a host:port and path and returns
a subset of the headers plus the body of the result."""
-from __future__ import absolute_import
import argparse
import json
--- a/tests/heredoctest.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/heredoctest.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import sys
--- a/tests/hghave Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/hghave Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
prefixed with "no-", the absence of feature is tested.
"""
-from __future__ import absolute_import, print_function
import hghave
import optparse
--- a/tests/hghave.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/hghave.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import distutils.version
import os
import re
--- a/tests/hgweberror.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/hgweberror.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# A dummy extension that installs an hgweb command that throws an Exception.
-from __future__ import absolute_import
from mercurial.hgweb import webcommands
--- a/tests/httpserverauth.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/httpserverauth.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import base64
import hashlib
@@ -18,7 +16,7 @@
return parsed
-class digestauthserver(object):
+class digestauthserver:
def __init__(self):
self._user_hashes = {}
--- a/tests/hypothesishelpers.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/hypothesishelpers.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
#
# For details see http://hypothesis.readthedocs.org
-from __future__ import absolute_import, print_function
import os
import sys
import traceback
--- a/tests/killdaemons.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/killdaemons.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
-from __future__ import absolute_import
import errno
import os
import signal
--- a/tests/list-tree.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/list-tree.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,8 +1,3 @@
-from __future__ import (
- absolute_import,
- print_function,
-)
-
import argparse
import os
--- a/tests/lockdelay.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/lockdelay.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
#
# This extension can be used to test race conditions between lock acquisition.
-from __future__ import absolute_import
import os
import time
--- a/tests/logexceptions.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/logexceptions.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import inspect
import os
--- a/tests/ls-l.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/ls-l.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
# like ls -l, but do not print date, user, or non-common mode bit, to avoid
# using globs in tests.
-from __future__ import absolute_import, print_function
import os
import stat
--- a/tests/md5sum.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/md5sum.py Fri Mar 25 11:33:12 2022 -0400
@@ -6,7 +6,6 @@
# of the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2, which is
# GPL-compatible.
-from __future__ import absolute_import
import hashlib
import os
--- a/tests/mockblackbox.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/mockblackbox.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
from mercurial.utils import procutil
# XXX: we should probably offer a devel option to do this in blackbox directly
--- a/tests/mockmakedate.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/mockmakedate.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# mock out util.makedate() to supply testable values
-from __future__ import absolute_import
import os
--- a/tests/mocktime.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/mocktime.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,10 +1,8 @@
-from __future__ import absolute_import
-
import os
import time
-class mocktime(object):
+class mocktime:
def __init__(self, increment):
self.time = 0
self.increment = [float(s) for s in increment.split()]
--- a/tests/printenv.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/printenv.py Fri Mar 25 11:33:12 2022 -0400
@@ -12,7 +12,6 @@
# - [output] is the name of the output file (default: use sys.stdout)
# the file will be opened in append mode.
#
-from __future__ import absolute_import
import argparse
import os
import sys
--- a/tests/printrevset.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/printrevset.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
from mercurial.thirdparty import attr
from mercurial import (
cmdutil,
--- a/tests/pullext.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/pullext.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial.i18n import _
from mercurial import (
--- a/tests/readlink.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/readlink.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
-from __future__ import absolute_import, print_function
import errno
import os
--- a/tests/remotefilelog-getflogheads.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/remotefilelog-getflogheads.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from mercurial.i18n import _
from mercurial import (
hg,
--- a/tests/revlog-formatv0.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/revlog-formatv0.py Fri Mar 25 11:33:12 2022 -0400
@@ -17,7 +17,6 @@
empty file
"""
-from __future__ import absolute_import
import binascii
import os
import sys
--- a/tests/revnamesext.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/revnamesext.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# Dummy extension to define a namespace containing revision names
-from __future__ import absolute_import
from mercurial import namespaces
--- a/tests/run-tests.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/run-tests.py Fri Mar 25 11:33:12 2022 -0400
@@ -43,7 +43,6 @@
# completes fairly quickly, includes both shell and Python scripts, and
# includes some scripts that run daemon processes.)
-from __future__ import absolute_import, print_function
import argparse
import collections
@@ -51,12 +50,15 @@
import difflib
import distutils.version as version
import errno
+import functools
import json
import multiprocessing
import os
import platform
+import queue
import random
import re
+import shlex
import shutil
import signal
import socket
@@ -70,21 +72,15 @@
import uuid
import xml.dom.minidom as minidom
+if sys.version_info < (3, 5, 0):
+ print(
+ '%s is only supported on Python 3.5+, not %s'
+ % (sys.argv[0], '.'.join(str(v) for v in sys.version_info[:3]))
+ )
+ sys.exit(70) # EX_SOFTWARE from `man 3 sysexit`
+
WINDOWS = os.name == r'nt'
-
-try:
- import Queue as queue
-except ImportError:
- import queue
-
-try:
- import shlex
-
- shellquote = shlex.quote
-except (ImportError, AttributeError):
- import pipes
-
- shellquote = pipes.quote
+shellquote = shlex.quote
processlock = threading.Lock()
@@ -155,80 +151,62 @@
origenviron = os.environ.copy()
-if sys.version_info > (3, 5, 0):
- PYTHON3 = True
- xrange = range # we use xrange in one place, and we'd rather not use range
-
- def _sys2bytes(p):
- if p is None:
- return p
- return p.encode('utf-8')
-
- def _bytes2sys(p):
- if p is None:
- return p
- return p.decode('utf-8')
-
- osenvironb = getattr(os, 'environb', None)
- if osenvironb is None:
- # Windows lacks os.environb, for instance. A proxy over the real thing
- # instead of a copy allows the environment to be updated via bytes on
- # all platforms.
- class environbytes(object):
- def __init__(self, strenv):
- self.__len__ = strenv.__len__
- self.clear = strenv.clear
- self._strenv = strenv
-
- def __getitem__(self, k):
- v = self._strenv.__getitem__(_bytes2sys(k))
- return _sys2bytes(v)
-
- def __setitem__(self, k, v):
- self._strenv.__setitem__(_bytes2sys(k), _bytes2sys(v))
-
- def __delitem__(self, k):
- self._strenv.__delitem__(_bytes2sys(k))
-
- def __contains__(self, k):
- return self._strenv.__contains__(_bytes2sys(k))
-
- def __iter__(self):
- return iter([_sys2bytes(k) for k in iter(self._strenv)])
-
- def get(self, k, default=None):
- v = self._strenv.get(_bytes2sys(k), _bytes2sys(default))
- return _sys2bytes(v)
-
- def pop(self, k, default=None):
- v = self._strenv.pop(_bytes2sys(k), _bytes2sys(default))
- return _sys2bytes(v)
-
- osenvironb = environbytes(os.environ)
-
- getcwdb = getattr(os, 'getcwdb')
- if not getcwdb or WINDOWS:
- getcwdb = lambda: _sys2bytes(os.getcwd())
-
-elif sys.version_info >= (3, 0, 0):
- print(
- '%s is only supported on Python 3.5+ and 2.7, not %s'
- % (sys.argv[0], '.'.join(str(v) for v in sys.version_info[:3]))
- )
- sys.exit(70) # EX_SOFTWARE from `man 3 sysexit`
-else:
- PYTHON3 = False
-
- # In python 2.x, path operations are generally done using
- # bytestrings by default, so we don't have to do any extra
- # fiddling there. We define the wrapper functions anyway just to
- # help keep code consistent between platforms.
- def _sys2bytes(p):
+xrange = range # we use xrange in one place, and we'd rather not use range
+
+
+def _sys2bytes(p):
+ if p is None:
+ return p
+ return p.encode('utf-8')
+
+
+def _bytes2sys(p):
+ if p is None:
return p
-
- _bytes2sys = _sys2bytes
- osenvironb = os.environ
- getcwdb = os.getcwd
+ return p.decode('utf-8')
+
+
+osenvironb = getattr(os, 'environb', None)
+if osenvironb is None:
+ # Windows lacks os.environb, for instance. A proxy over the real thing
+ # instead of a copy allows the environment to be updated via bytes on
+ # all platforms.
+ class environbytes:
+ def __init__(self, strenv):
+ self.__len__ = strenv.__len__
+ self.clear = strenv.clear
+ self._strenv = strenv
+
+ def __getitem__(self, k):
+ v = self._strenv.__getitem__(_bytes2sys(k))
+ return _sys2bytes(v)
+
+ def __setitem__(self, k, v):
+ self._strenv.__setitem__(_bytes2sys(k), _bytes2sys(v))
+
+ def __delitem__(self, k):
+ self._strenv.__delitem__(_bytes2sys(k))
+
+ def __contains__(self, k):
+ return self._strenv.__contains__(_bytes2sys(k))
+
+ def __iter__(self):
+ return iter([_sys2bytes(k) for k in iter(self._strenv)])
+
+ def get(self, k, default=None):
+ v = self._strenv.get(_bytes2sys(k), _bytes2sys(default))
+ return _sys2bytes(v)
+
+ def pop(self, k, default=None):
+ v = self._strenv.pop(_bytes2sys(k), _bytes2sys(default))
+ return _sys2bytes(v)
+
+ osenvironb = environbytes(os.environ)
+
+getcwdb = getattr(os, 'getcwdb')
+if not getcwdb or WINDOWS:
+ getcwdb = lambda: _sys2bytes(os.getcwd())
+
if WINDOWS:
_getcwdb = getcwdb
@@ -260,10 +238,14 @@
s.bind(('localhost', port))
s.close()
return True
- except socket.error as exc:
+ except (socket.error, OSError) as exc:
if exc.errno == errno.EADDRINUSE:
return True
- elif exc.errno in (errno.EADDRNOTAVAIL, errno.EPROTONOSUPPORT):
+ elif exc.errno in (
+ errno.EADDRNOTAVAIL,
+ errno.EPROTONOSUPPORT,
+ errno.EAFNOSUPPORT,
+ ):
return False
else:
raise
@@ -288,12 +270,11 @@
except socket.error as exc:
if WINDOWS and exc.errno == errno.WSAEACCES:
return False
- elif PYTHON3:
- # TODO: make a proper exception handler after dropping py2. This
- # works because socket.error is an alias for OSError on py3,
- # which is also the baseclass of PermissionError.
- if isinstance(exc, PermissionError):
- return False
+ # TODO: make a proper exception handler after dropping py2. This
+ # works because socket.error is an alias for OSError on py3,
+ # which is also the baseclass of PermissionError.
+ elif isinstance(exc, PermissionError):
+ return False
if exc.errno not in (
errno.EADDRINUSE,
errno.EADDRNOTAVAIL,
@@ -372,18 +353,10 @@
def which(exe):
- if PYTHON3:
- # shutil.which only accept bytes from 3.8
- cmd = _bytes2sys(exe)
- real_exec = shutil.which(cmd)
- return _sys2bytes(real_exec)
- else:
- # let us do the os work
- for p in osenvironb[b'PATH'].split(os.pathsep):
- f = os.path.join(p, exe)
- if os.path.isfile(f):
- return f
- return None
+ # shutil.which only accept bytes from 3.8
+ cmd = _bytes2sys(exe)
+ real_exec = shutil.which(cmd)
+ return _sys2bytes(real_exec)
def parselistfiles(files, listtype, warn=True):
@@ -898,11 +871,7 @@
pass
-_unified_diff = difflib.unified_diff
-if PYTHON3:
- import functools
-
- _unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
+_unified_diff = functools.partial(difflib.diff_bytes, difflib.unified_diff)
def getdiff(expected, output, ref, err):
@@ -1486,7 +1455,7 @@
# This has the same effect as Py_LegacyWindowsStdioFlag in exewrapper.c,
# but this is needed for testing python instances like dummyssh,
# dummysmtpd.py, and dumbhttp.py.
- if PYTHON3 and WINDOWS:
+ if WINDOWS:
env['PYTHONLEGACYWINDOWSSTDIO'] = '1'
# Modified HOME in test environment can confuse Rust tools. So set
@@ -1677,9 +1646,7 @@
re.compile(br'.*\$LOCALIP.*$'),
]
-bchr = chr
-if PYTHON3:
- bchr = lambda x: bytes([x])
+bchr = lambda x: bytes([x])
WARN_UNDEFINED = 1
WARN_YES = 2
@@ -1818,9 +1785,7 @@
script.append(b'echo %s %d $?\n' % (salt, line))
activetrace = []
- session = str(uuid.uuid4())
- if PYTHON3:
- session = session.encode('ascii')
+ session = str(uuid.uuid4()).encode('ascii')
hgcatapult = os.getenv('HGTESTCATAPULTSERVERPIPE') or os.getenv(
'HGCATAPULTSERVERPIPE'
)
@@ -1874,11 +1839,8 @@
script.append(b'alias pwd="pwd -W"\n')
if hgcatapult and hgcatapult != os.devnull:
- if PYTHON3:
- hgcatapult = hgcatapult.encode('utf8')
- cataname = self.name.encode('utf8')
- else:
- cataname = self.name
+ hgcatapult = hgcatapult.encode('utf8')
+ cataname = self.name.encode('utf8')
# Kludge: use a while loop to keep the pipe from getting
# closed by our echo commands. The still-running file gets
@@ -2183,11 +2145,8 @@
return "retry", False
if el.endswith(b" (esc)\n"):
- if PYTHON3:
- el = el[:-7].decode('unicode_escape') + '\n'
- el = el.encode('latin-1')
- else:
- el = el[:-7].decode('string-escape') + '\n'
+ el = el[:-7].decode('unicode_escape') + '\n'
+ el = el.encode('latin-1')
if el == l or WINDOWS and el[:-1] + b'\r\n' == l:
return True, True
if el.endswith(b" (re)\n"):
@@ -2235,10 +2194,7 @@
firstlock = threading.RLock()
firsterror = False
-if PYTHON3:
- base_class = unittest.TextTestResult
-else:
- base_class = unittest._TextTestResult
+base_class = unittest.TextTestResult
class TestResult(base_class):
@@ -2362,13 +2318,9 @@
self.stream.write('\n')
for line in lines:
line = highlightdiff(line, self.color)
- if PYTHON3:
- self.stream.flush()
- self.stream.buffer.write(line)
- self.stream.buffer.flush()
- else:
- self.stream.write(line)
- self.stream.flush()
+ self.stream.flush()
+ self.stream.buffer.write(line)
+ self.stream.buffer.flush()
if servefail:
raise test.failureException(
@@ -3035,7 +2987,7 @@
testdescs.sort(key=sortkey)
-class TestRunner(object):
+class TestRunner:
"""Holds context for executing tests.
Tests rely on a lot of state. This object holds it for them.
@@ -3257,10 +3209,7 @@
fileb = _sys2bytes(__file__)
runtestdir = os.path.abspath(os.path.dirname(fileb))
osenvironb[b'RUNTESTDIR'] = runtestdir
- if PYTHON3:
- sepb = _sys2bytes(os.pathsep)
- else:
- sepb = os.pathsep
+ sepb = _sys2bytes(os.pathsep)
path = [self._bindir, runtestdir] + osenvironb[b"PATH"].split(sepb)
if os.path.islink(__file__):
# test helper will likely be at the end of the symlink
@@ -3456,7 +3405,7 @@
failed = False
kws = self.options.keywords
- if kws is not None and PYTHON3:
+ if kws is not None:
kws = kws.encode('utf-8')
suite = TestSuite(
@@ -3604,14 +3553,10 @@
def _usecorrectpython(self):
"""Configure the environment to use the appropriate Python in tests."""
# Tests must use the same interpreter as us or bad things will happen.
- if WINDOWS and PYTHON3:
+ if WINDOWS:
pyexe_names = [b'python', b'python3', b'python.exe']
- elif WINDOWS:
- pyexe_names = [b'python', b'python.exe']
- elif PYTHON3:
+ else:
pyexe_names = [b'python', b'python3']
- else:
- pyexe_names = [b'python', b'python2']
# os.symlink() is a thing with py3 on Windows, but it requires
# Administrator rights.
@@ -3654,14 +3599,6 @@
f.write(b'%s "$@"\n' % esc_executable)
if WINDOWS:
- if not PYTHON3:
- # lets try to build a valid python3 executable for the
- # scrip that requires it.
- py3exe_name = os.path.join(self._custom_bin_dir, b'python3')
- with open(py3exe_name, 'wb') as f:
- f.write(b'#!/bin/sh\n')
- f.write(b'py -3 "$@"\n')
-
# adjust the path to make sur the main python finds it own dll
path = os.environ['PATH'].split(os.pathsep)
main_exec_dir = os.path.dirname(sysexecutable)
@@ -3674,8 +3611,6 @@
if appdata is not None:
python_dir = 'Python%d%d' % (vi[0], vi[1])
scripts_path = [appdata, 'Python', python_dir, 'Scripts']
- if not PYTHON3:
- scripts_path = [appdata, 'Python', 'Scripts']
scripts_dir = os.path.join(*scripts_path)
extra_paths.append(scripts_dir)
@@ -3719,12 +3654,9 @@
setup_opts = b"--no-rust"
# Run installer in hg root
- script = os.path.realpath(sys.argv[0])
- exe = sysexecutable
- if PYTHON3:
- compiler = _sys2bytes(compiler)
- script = _sys2bytes(script)
- exe = _sys2bytes(exe)
+ compiler = _sys2bytes(compiler)
+ script = _sys2bytes(os.path.realpath(sys.argv[0]))
+ exe = _sys2bytes(sysexecutable)
hgroot = os.path.dirname(os.path.dirname(script))
self._hgroot = hgroot
os.chdir(hgroot)
@@ -3776,10 +3708,7 @@
else:
with open(installerrs, 'rb') as f:
for line in f:
- if PYTHON3:
- sys.stdout.buffer.write(line)
- else:
- sys.stdout.write(line)
+ sys.stdout.buffer.write(line)
sys.exit(1)
os.chdir(self._testdir)
@@ -3840,9 +3769,7 @@
return self._hgpath
cmd = b'"%s" -c "import mercurial; print (mercurial.__path__[0])"'
- cmd = cmd % PYTHON
- if PYTHON3:
- cmd = _bytes2sys(cmd)
+ cmd = _bytes2sys(cmd % PYTHON)
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
out, err = p.communicate()
@@ -3872,10 +3799,7 @@
)
out, _err = proc.communicate()
if proc.returncode != 0:
- if PYTHON3:
- sys.stdout.buffer.write(out)
- else:
- sys.stdout.write(out)
+ sys.stdout.buffer.write(out)
sys.exit(1)
def _installrhg(self):
@@ -3899,10 +3823,7 @@
)
out, _err = proc.communicate()
if proc.returncode != 0:
- if PYTHON3:
- sys.stdout.buffer.write(out)
- else:
- sys.stdout.write(out)
+ sys.stdout.buffer.write(out)
sys.exit(1)
def _build_pyoxidized(self):
@@ -3930,10 +3851,7 @@
)
out, _err = proc.communicate()
if proc.returncode != 0:
- if PYTHON3:
- sys.stdout.buffer.write(out)
- else:
- sys.stdout.write(out)
+ sys.stdout.buffer.write(out)
sys.exit(1)
def _outputcoverage(self):
--- a/tests/seq.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/seq.py Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
# seq START STOP [START, STOP] stepping by 1
# seq START STEP STOP [START, STOP] stepping by STEP
-from __future__ import absolute_import, print_function
import os
import sys
--- a/tests/silenttestrunner.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/silenttestrunner.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
import os
import sys
import unittest
--- a/tests/simplestorerepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/simplestorerepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -10,7 +10,6 @@
# $ HGREPOFEATURES="simplestore" ./run-tests.py \
# --extra-config-opt extensions.simplestore=`pwd`/simplestorerepo.py
-from __future__ import absolute_import
import stat
@@ -71,7 +70,7 @@
@interfaceutil.implementer(repository.irevisiondelta)
@attr.s(slots=True)
-class simplestorerevisiondelta(object):
+class simplestorerevisiondelta:
node = attr.ib()
p1node = attr.ib()
p2node = attr.ib()
@@ -85,14 +84,14 @@
@interfaceutil.implementer(repository.iverifyproblem)
@attr.s(frozen=True)
-class simplefilestoreproblem(object):
+class simplefilestoreproblem:
warning = attr.ib(default=None)
error = attr.ib(default=None)
node = attr.ib(default=None)
@interfaceutil.implementer(repository.ifilestorage)
-class filestorage(object):
+class filestorage:
"""Implements storage for a tracked path.
Data is stored in the VFS in a directory corresponding to the tracked
--- a/tests/sitecustomize.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/sitecustomize.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
import os
if os.environ.get('COVERAGE_PROCESS_START'):
--- a/tests/sshprotoext.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/sshprotoext.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
# This extension replaces the SSH server started via `hg serve --stdio`.
# The server behaves differently depending on environment variables.
-from __future__ import absolute_import
from mercurial import (
error,
--- a/tests/svn-safe-append.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/svn-safe-append.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
-from __future__ import absolute_import
__doc__ = """Same as `echo a >> b`, but ensures a changed mtime of b.
Without this svn will not detect workspace changes."""
--- a/tests/svnurlof.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/svnurlof.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
import sys
from mercurial import (
--- a/tests/svnxml.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/svnxml.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
# Read the output of a "svn log --xml" command on stdin, parse it and
# print a subset of attributes common to all svn versions tested by
# hg.
-from __future__ import absolute_import
import sys
import xml.dom.minidom
--- a/tests/test-absorb-filefixupstate.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-absorb-filefixupstate.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,11 +1,9 @@
-from __future__ import absolute_import, print_function
-
import itertools
from mercurial import pycompat
from hgext import absorb
-class simplefctx(object):
+class simplefctx:
def __init__(self, content):
self.content = content
--- a/tests/test-ancestor.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-ancestor.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import binascii
import getopt
import math
@@ -64,7 +62,7 @@
return ancs
-class naiveincrementalmissingancestors(object):
+class naiveincrementalmissingancestors:
def __init__(self, ancs, bases):
self.ancs = ancs
self.bases = set(bases)
--- a/tests/test-annotate.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-annotate.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,3 @@
-from __future__ import absolute_import
-from __future__ import print_function
-
import unittest
from mercurial import (
--- a/tests/test-annotate.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-annotate.t Fri Mar 25 11:33:12 2022 -0400
@@ -478,7 +478,6 @@
and its ancestor by overriding "repo._filecommit".
$ cat > ../legacyrepo.py <<EOF
- > from __future__ import absolute_import
> from mercurial import commit, error, extensions
> def _filecommit(orig, repo, fctx, manifest1, manifest2,
> linkrev, tr, includecopymeta, ms):
--- a/tests/test-arbitraryfilectx.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-arbitraryfilectx.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
Setup:
$ cat > eval.py <<EOF
- > from __future__ import absolute_import
> import filecmp
> from mercurial import commands, context, pycompat, registrar
> cmdtable = {}
--- a/tests/test-archive.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-archive.t Fri Mar 25 11:33:12 2022 -0400
@@ -320,7 +320,6 @@
$ TIP=`hg id -v | cut -f1 -d' '`
$ QTIP=`hg id -q`
$ cat > getarchive.py <<EOF
- > from __future__ import absolute_import
> import os
> import sys
> from mercurial import (
@@ -455,7 +454,6 @@
> done
$ cat > md5comp.py <<EOF
- > from __future__ import absolute_import, print_function
> import hashlib
> import sys
> f1, f2 = sys.argv[1:3]
@@ -582,16 +580,11 @@
Strms Blocks Compressed Uncompressed Ratio Check Filename (xz !)
$ rm -f ../archive.txz
#endif
-#if py3 no-lzma
+#if no-lzma
$ hg archive ../archive.txz
abort: lzma module is not available
[255]
#endif
-#if no-py3
- $ hg archive ../archive.txz
- abort: xz compression is only available in Python 3
- [255]
-#endif
show an error when a provided pattern matches no files
@@ -617,7 +610,6 @@
$ hg -R repo add repo/a
$ hg -R repo commit -m '#0' -d '456789012 21600'
$ cat > show_mtime.py <<EOF
- > from __future__ import absolute_import, print_function
> import os
> import sys
> print(int(os.stat(sys.argv[1]).st_mtime))
--- a/tests/test-atomictempfile.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-atomictempfile.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import glob
import os
import shutil
--- a/tests/test-bad-extension.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-bad-extension.t Fri Mar 25 11:33:12 2022 -0400
@@ -54,7 +54,6 @@
$ hg -q help help 2>&1 |grep extension
*** failed to import extension "badext" from $TESTTMP/badext.py: bit bucket overflow
*** failed to import extension "badext2": No module named 'badext2' (py3 !)
- *** failed to import extension "badext2": No module named badext2 (no-py3 !)
show traceback
@@ -63,9 +62,7 @@
Traceback (most recent call last):
Exception: bit bucket overflow
*** failed to import extension "badext2": No module named 'badext2' (py3 !)
- *** failed to import extension "badext2": No module named badext2 (no-py3 !)
Traceback (most recent call last):
- ImportError: No module named badext2 (no-py3 !)
ImportError: No module named 'hgext.badext2' (py3 no-py36 !)
ModuleNotFoundError: No module named 'hgext.badext2' (py36 !)
Traceback (most recent call last): (py3 !)
@@ -114,19 +111,16 @@
YYYY/MM/DD HH:MM:SS (PID)> - loading extension: badext2
YYYY/MM/DD HH:MM:SS (PID)> - could not import hgext.badext2 (No module named *badext2*): trying hgext3rd.badext2 (glob)
Traceback (most recent call last):
- ImportError: No module named badext2 (no-py3 !)
ImportError: No module named 'hgext.badext2' (py3 no-py36 !)
ModuleNotFoundError: No module named 'hgext.badext2' (py36 !)
YYYY/MM/DD HH:MM:SS (PID)> - could not import hgext3rd.badext2 (No module named *badext2*): trying badext2 (glob)
Traceback (most recent call last):
- ImportError: No module named badext2 (no-py3 !)
ImportError: No module named 'hgext.badext2' (py3 no-py36 !)
ModuleNotFoundError: No module named 'hgext.badext2' (py36 !)
Traceback (most recent call last): (py3 !)
ImportError: No module named 'hgext3rd.badext2' (py3 no-py36 !)
ModuleNotFoundError: No module named 'hgext3rd.badext2' (py36 !)
*** failed to import extension "badext2": No module named 'badext2' (py3 !)
- *** failed to import extension "badext2": No module named badext2 (no-py3 !)
Traceback (most recent call last):
ImportError: No module named 'hgext.badext2' (py3 no-py36 !)
ModuleNotFoundError: No module named 'hgext.badext2' (py36 !)
@@ -136,7 +130,6 @@
Traceback (most recent call last): (py3 !)
ModuleNotFoundError: No module named 'badext2' (py36 !)
ImportError: No module named 'badext2' (py3 no-py36 !)
- ImportError: No module named badext2 (no-py3 !)
YYYY/MM/DD HH:MM:SS (PID)> > loaded 2 extensions, total time * (glob)
YYYY/MM/DD HH:MM:SS (PID)> - loading configtable attributes
YYYY/MM/DD HH:MM:SS (PID)> - executing uisetup hooks
@@ -165,7 +158,6 @@
$ hg help --keyword baddocext
*** failed to import extension "badext" from $TESTTMP/badext.py: bit bucket overflow
*** failed to import extension "badext2": No module named 'badext2' (py3 !)
- *** failed to import extension "badext2": No module named badext2 (no-py3 !)
Topics:
extensions Using Additional Features
--- a/tests/test-basic.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-basic.t Fri Mar 25 11:33:12 2022 -0400
@@ -240,15 +240,16 @@
Underlying message streams should be updated when ui.fout/ferr are set:
$ cat <<'EOF' > capui.py
- > from mercurial import pycompat, registrar
+ > import io
+ > from mercurial import registrar
> cmdtable = {}
> command = registrar.command(cmdtable)
> @command(b'capui', norepo=True)
> def capui(ui):
> out = ui.fout
- > ui.fout = pycompat.bytesio()
+ > ui.fout = io.BytesIO()
> ui.status(b'status\n')
- > ui.ferr = pycompat.bytesio()
+ > ui.ferr = io.BytesIO()
> ui.warn(b'warn\n')
> out.write(b'stdout: %s' % ui.fout.getvalue())
> out.write(b'stderr: %s' % ui.ferr.getvalue())
--- a/tests/test-batching.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-batching.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import, print_function
import contextlib
@@ -21,7 +20,7 @@
# equivalent of repo.repository
-class thing(object):
+class thing:
def hello(self):
return b"Ready."
@@ -108,7 +107,7 @@
# server side
# equivalent of wireproto's global functions
-class server(object):
+class server:
def __init__(self, local):
self.local = local
--- a/tests/test-bdiff.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-bdiff.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
import collections
import struct
import unittest
--- a/tests/test-bisect.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-bisect.t Fri Mar 25 11:33:12 2022 -0400
@@ -462,7 +462,6 @@
$ cat > script.py <<EOF
> #!$PYTHON
- > from __future__ import absolute_import
> import sys
> from mercurial import hg, ui as uimod
> repo = hg.repository(uimod.ui.load(), b'.')
--- a/tests/test-blackbox.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-blackbox.t Fri Mar 25 11:33:12 2022 -0400
@@ -403,7 +403,6 @@
when using chg, blackbox.log should get rotated correctly
$ cat > $TESTTMP/noop.py << EOF
- > from __future__ import absolute_import
> import time
> from mercurial import registrar, scmutil
> cmdtable = {}
@@ -463,7 +462,6 @@
blackbox should work if repo.ui.log is not called (issue5518)
$ cat > $TESTTMP/raise.py << EOF
- > from __future__ import absolute_import
> from mercurial import registrar, scmutil
> cmdtable = {}
> command = registrar.command(cmdtable)
--- a/tests/test-bookmarks.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-bookmarks.t Fri Mar 25 11:33:12 2022 -0400
@@ -1069,7 +1069,6 @@
$ echo a > a
$ cat > $TESTTMP/pausefinalize.py <<EOF
- > from __future__ import absolute_import
> import os
> import time
> from mercurial import extensions, localrepo
--- a/tests/test-bugzilla.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-bugzilla.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
mock bugzilla driver for testing template output:
$ cat <<EOF > bzmock.py
- > from __future__ import absolute_import
> from mercurial import extensions
> from mercurial import pycompat
> from mercurial import registrar
--- a/tests/test-bundle.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-bundle.t Fri Mar 25 11:33:12 2022 -0400
@@ -466,7 +466,6 @@
transaction)
$ cat > $TESTTMP/showtip.py <<EOF
- > from __future__ import absolute_import
>
> def showtip(ui, repo, hooktype, **kwargs):
> ui.warn(b'%s: %s\n' % (hooktype, repo[b'tip'].hex()[:12]))
--- a/tests/test-bundle2-pushback.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-bundle2-pushback.t Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
> Current bundle2 implementation doesn't provide a way to generate those
> parts, so they must be created by extensions.
> """
- > from __future__ import absolute_import
> from mercurial import bundle2, exchange, pushkey, util
> def _newhandlechangegroup(op, inpart):
> """This function wraps the changegroup part handler for getbundle.
--- a/tests/test-cappedreader.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-cappedreader.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import io
import unittest
--- a/tests/test-cbor.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-cbor.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import os
import sys
import unittest
--- a/tests/test-check-code.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-check-code.t Fri Mar 25 11:33:12 2022 -0400
@@ -27,7 +27,6 @@
Skipping contrib/packaging/hgpackaging/cli.py it has no-che?k-code (glob)
Skipping contrib/packaging/hgpackaging/downloads.py it has no-che?k-code (glob)
Skipping contrib/packaging/hgpackaging/inno.py it has no-che?k-code (glob)
- Skipping contrib/packaging/hgpackaging/py2exe.py it has no-che?k-code (glob)
Skipping contrib/packaging/hgpackaging/pyoxidizer.py it has no-che?k-code (glob)
Skipping contrib/packaging/hgpackaging/util.py it has no-che?k-code (glob)
Skipping contrib/packaging/hgpackaging/wix.py it has no-che?k-code (glob)
--- a/tests/test-check-help.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-check-help.t Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
$ . "$TESTDIR/helpers-testrepo.sh"
$ cat <<'EOF' > scanhelptopics.py
- > from __future__ import absolute_import, print_function
> import re
> import sys
> if sys.platform == "win32":
--- a/tests/test-check-interfaces.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-check-interfaces.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# Test that certain objects conform to well-defined interfaces.
-from __future__ import absolute_import, print_function
from mercurial import encoding
@@ -81,7 +80,7 @@
# Facilitates testing localpeer.
-class dummyrepo(object):
+class dummyrepo:
def __init__(self):
self.ui = uimod.ui()
self._wanted_sidedata = set()
@@ -93,7 +92,7 @@
pass
-class dummyopener(object):
+class dummyopener:
handlers = []
@@ -109,7 +108,7 @@
pass
-class dummypipe(object):
+class dummypipe:
def close(self):
pass
--- a/tests/test-check-py3-compat.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-check-py3-compat.t Fri Mar 25 11:33:12 2022 -0400
@@ -3,35 +3,7 @@
$ . "$TESTDIR/helpers-testrepo.sh"
$ cd "$TESTDIR"/..
-#if no-py3
- $ testrepohg files 'set:(**.py)' \
- > -X contrib/automation/ \
- > -X contrib/packaging/hgpackaging/ \
- > -X contrib/packaging/inno/ \
- > -X contrib/packaging/packaging.py \
- > -X contrib/packaging/wix/ \
- > -X hgdemandimport/demandimportpy2.py \
- > -X mercurial/thirdparty/cbor \
- > | sed 's|\\|/|g' | xargs "$PYTHON" contrib/check-py3-compat.py
- contrib/python-zstandard/setup.py not using absolute_import
- contrib/python-zstandard/setup_zstd.py not using absolute_import
- contrib/python-zstandard/tests/common.py not using absolute_import
- contrib/python-zstandard/tests/test_buffer_util.py not using absolute_import
- contrib/python-zstandard/tests/test_compressor.py not using absolute_import
- contrib/python-zstandard/tests/test_compressor_fuzzing.py not using absolute_import
- contrib/python-zstandard/tests/test_data_structures.py not using absolute_import
- contrib/python-zstandard/tests/test_data_structures_fuzzing.py not using absolute_import
- contrib/python-zstandard/tests/test_decompressor.py not using absolute_import
- contrib/python-zstandard/tests/test_decompressor_fuzzing.py not using absolute_import
- contrib/python-zstandard/tests/test_estimate_sizes.py not using absolute_import
- contrib/python-zstandard/tests/test_module_attributes.py not using absolute_import
- contrib/python-zstandard/tests/test_train_dictionary.py not using absolute_import
- setup.py not using absolute_import
-#endif
-
-#if py3
$ testrepohg files 'set:(**.py) - grep(pygments)' \
- > -X hgdemandimport/demandimportpy2.py \
> -X hgext/fsmonitor/pywatchman \
> -X mercurial/cffi \
> -X mercurial/thirdparty \
@@ -44,9 +16,8 @@
mercurial/windows.py: error importing: <*Error> No module named 'msvcrt' (error at windows.py:*) (glob) (no-windows !)
mercurial/posix.py: error importing: <*Error> No module named 'fcntl' (error at posix.py:*) (glob) (windows !)
mercurial/scmposix.py: error importing: <*Error> No module named 'fcntl' (error at scmposix.py:*) (glob) (windows !)
-#endif
-#if py3 pygments
+#if pygments
$ testrepohg files 'set:(**.py) and grep(pygments)' | sed 's|\\|/|g' \
> | xargs "$PYTHON" contrib/check-py3-compat.py \
> | sed 's/[0-9][0-9]*)$/*)/'
--- a/tests/test-chg.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-chg.t Fri Mar 25 11:33:12 2022 -0400
@@ -132,7 +132,6 @@
> EOF
$ cat > $TESTTMP/fakepager.py <<EOF
- > from __future__ import absolute_import
> import sys
> import time
> for line in iter(sys.stdin.readline, ''):
--- a/tests/test-commandserver.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-commandserver.t Fri Mar 25 11:33:12 2022 -0400
@@ -23,7 +23,6 @@
$ hg init repo
$ cd repo
- >>> from __future__ import absolute_import
>>> import os
>>> import sys
>>> from hgclient import bprint, check, readchannel, runcommand
--- a/tests/test-commit-interactive.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-commit-interactive.t Fri Mar 25 11:33:12 2022 -0400
@@ -938,7 +938,6 @@
$ export LANGUAGE
$ cat > $TESTTMP/escape.py <<EOF
- > from __future__ import absolute_import
> from mercurial import (
> pycompat,
> )
--- a/tests/test-commit.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-commit.t Fri Mar 25 11:33:12 2022 -0400
@@ -645,7 +645,6 @@
verify pathauditor blocks evil filepaths
$ cat > evil-commit.py <<EOF
- > from __future__ import absolute_import
> from mercurial import context, hg, ui as uimod
> notrc = u".h\u200cg".encode('utf-8') + b'/hgrc'
> u = uimod.ui.load()
@@ -671,7 +670,6 @@
$ hg rollback -f
repository tip rolled back to revision 2 (undo commit)
$ cat > evil-commit.py <<EOF
- > from __future__ import absolute_import
> from mercurial import context, hg, ui as uimod
> notrc = b"HG~1/hgrc"
> u = uimod.ui.load()
@@ -691,7 +689,6 @@
$ hg rollback -f
repository tip rolled back to revision 2 (undo commit)
$ cat > evil-commit.py <<EOF
- > from __future__ import absolute_import
> from mercurial import context, hg, ui as uimod
> notrc = b"HG8B6C~2/hgrc"
> u = uimod.ui.load()
--- a/tests/test-config-env.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-config-env.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# Test the config layer generated by environment variables
-from __future__ import absolute_import, print_function
import os
--- a/tests/test-context-metadata.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-context-metadata.t Fri Mar 25 11:33:12 2022 -0400
@@ -12,7 +12,6 @@
$ hg commit -m 'Remove A'
$ cat > metaedit.py <<EOF
- > from __future__ import absolute_import
> from mercurial import context, pycompat, registrar
> cmdtable = {}
> command = registrar.command(cmdtable)
--- a/tests/test-context.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-context.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
import os
import stat
import sys
--- a/tests/test-contrib-check-code.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-contrib-check-code.t Fri Mar 25 11:33:12 2022 -0400
@@ -51,12 +51,6 @@
./quote.py:5:
> '"""', 42+1, """and
missing whitespace in expression
- ./classstyle.py:4:
- > class oldstyle_class:
- old-style class, use class foo(object)
- ./classstyle.py:7:
- > class empty():
- class foo() creates old style object, use class foo(object)
[1]
$ cat > python3-compat.py << NO_CHECK_EOF
> foo <> bar
--- a/tests/test-contrib-perf.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-contrib-perf.t Fri Mar 25 11:33:12 2022 -0400
@@ -301,7 +301,6 @@
malformatted run limit entry, missing "-": 500
! wall * comb * user * sys * (best of 5) (glob)
$ hg perfparents --config perf.stub=no --config perf.run-limits='aaa-12, 0.000000001-5'
- malformatted run limit entry, could not convert string to float: aaa: aaa-12 (no-py3 !)
malformatted run limit entry, could not convert string to float: 'aaa': aaa-12 (py3 !)
! wall * comb * user * sys * (best of 5) (glob)
$ hg perfparents --config perf.stub=no --config perf.run-limits='12-aaaaaa, 0.000000001-5'
--- a/tests/test-convert-clonebranches.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-convert-clonebranches.t Fri Mar 25 11:33:12 2022 -0400
@@ -31,7 +31,6 @@
Miss perl... sometimes
$ cat > filter.py <<EOF
- > from __future__ import absolute_import
> import re
> import sys
>
--- a/tests/test-convert-git.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-convert-git.t Fri Mar 25 11:33:12 2022 -0400
@@ -435,7 +435,7 @@
$ cd git-repo3-hg
$ hg up -C
1 files updated, 0 files merged, 0 files removed, 0 files unresolved
- $ "$PYTHON" -c 'from __future__ import print_function; print(len(open("b", "rb").read()))'
+ $ "$PYTHON" -c 'print(len(open("b", "rb").read()))'
4096
$ cd ..
--- a/tests/test-debugcommands.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-debugcommands.t Fri Mar 25 11:33:12 2022 -0400
@@ -212,7 +212,6 @@
{
"chainid": 1,
"chainlen": 1,
- "chainratio": 1.02325581395, (no-py3 !)
"chainratio": 1.0232558139534884, (py3 !)
"chainsize": 44,
"compsize": 44,
@@ -249,7 +248,6 @@
{
"chainid": 3,
"chainlen": 1,
- "chainratio": 1.02325581395, (no-py3 !)
"chainratio": 1.0232558139534884, (py3 !)
"chainsize": 44,
"compsize": 44,
@@ -289,7 +287,6 @@
{
"chainid": 1,
"chainlen": 1,
- "chainratio": 1.02325581395, (no-py3 !)
"chainratio": 1.0232558139534884, (py3 !)
"chainsize": 44,
"compsize": 44,
@@ -326,7 +323,6 @@
{
"chainid": 3,
"chainlen": 1,
- "chainratio": 1.02325581395, (no-py3 !)
"chainratio": 1.0232558139534884, (py3 !)
"chainsize": 44,
"compsize": 44,
@@ -574,7 +570,6 @@
Test internal debugstacktrace command
$ cat > debugstacktrace.py << EOF
- > from __future__ import absolute_import
> from mercurial import (
> util,
> )
@@ -593,15 +588,15 @@
> EOF
$ "$PYTHON" debugstacktrace.py
stacktrace at:
- *debugstacktrace.py:16 in * (glob)
- *debugstacktrace.py:9 in f (glob)
+ *debugstacktrace.py:15 in * (glob)
+ *debugstacktrace.py:8 in f (glob)
hello from g at:
- *debugstacktrace.py:16 in * (glob)
- *debugstacktrace.py:10 in f (glob)
+ *debugstacktrace.py:15 in * (glob)
+ *debugstacktrace.py:9 in f (glob)
hi ...
from h hidden in g at:
- *debugstacktrace.py:10 in f (glob)
- *debugstacktrace.py:13 in g (glob)
+ *debugstacktrace.py:9 in f (glob)
+ *debugstacktrace.py:12 in g (glob)
Test debugcapabilities command:
--- a/tests/test-demandimport.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-demandimport.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
from mercurial import demandimport
demandimport.enable()
--- a/tests/test-dirs.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-dirs.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import unittest
import silenttestrunner
--- a/tests/test-dirstate.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-dirstate.t Fri Mar 25 11:33:12 2022 -0400
@@ -77,7 +77,6 @@
coherent (issue4353)
$ cat > ../dirstateexception.py <<EOF
- > from __future__ import absolute_import
> from mercurial import (
> error,
> extensions,
--- a/tests/test-dispatch.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-dispatch.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
import os
import sys
from mercurial import dispatch
--- a/tests/test-doctest.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-doctest.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,5 @@
# this is hack to make sure no escape characters are inserted into the output
-from __future__ import absolute_import
-from __future__ import print_function
import doctest
import os
--- a/tests/test-duplicateoptions.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-duplicateoptions.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
import os
from mercurial import (
commands,
--- a/tests/test-encoding-func.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-encoding-func.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import unittest
from mercurial import encoding
--- a/tests/test-eol.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-eol.t Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
Set up helpers
$ cat > switch-eol.py <<'EOF'
- > from __future__ import absolute_import
> import os
> import sys
> try:
--- a/tests/test-extension.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-extension.t Fri Mar 25 11:33:12 2022 -0400
@@ -150,7 +150,6 @@
Check that extensions are loaded in phases:
$ cat > foo.py <<EOF
- > from __future__ import print_function
> import os
> from mercurial import exthelper
> from mercurial.utils import procutil
@@ -295,7 +294,6 @@
$ echo "s = 'libroot/mod/ambig.py'" > $TESTTMP/libroot/mod/ambig.py
$ cat > $TESTTMP/libroot/mod/ambigabs.py <<NO_CHECK_EOF
- > from __future__ import absolute_import, print_function
> import ambig # should load "libroot/ambig.py"
> s = ambig.s
> NO_CHECK_EOF
@@ -309,23 +307,6 @@
ambigabs.s=libroot/ambig.py
$TESTTMP/a
-#if no-py3
- $ cat > $TESTTMP/libroot/mod/ambigrel.py <<NO_CHECK_EOF
- > from __future__ import print_function
- > import ambig # should load "libroot/mod/ambig.py"
- > s = ambig.s
- > NO_CHECK_EOF
- $ cat > loadrel.py <<NO_CHECK_EOF
- > import mod.ambigrel as ambigrel
- > def extsetup(ui):
- > print('ambigrel.s=%s' % ambigrel.s, flush=True)
- > NO_CHECK_EOF
- $ "$PYTHON" $TESTTMP/unflush.py loadrel.py
- $ (PYTHONPATH=${PYTHONPATH}${PATHSEP}${TESTTMP}/libroot; hg --config extensions.loadrel=loadrel.py root)
- ambigrel.s=libroot/mod/ambig.py
- $TESTTMP/a
-#endif
-
Check absolute/relative import of extension specific modules
$ mkdir $TESTTMP/extroot
@@ -340,7 +321,6 @@
> s = b'this is extroot.sub1.baz'
> NO_CHECK_EOF
$ cat > $TESTTMP/extroot/__init__.py <<NO_CHECK_EOF
- > from __future__ import absolute_import
> s = b'this is extroot.__init__'
> from . import foo
> def extsetup(ui):
@@ -377,39 +357,6 @@
(extroot) import extroot.bar in func(): this is extroot.bar
$TESTTMP/a
-#if no-py3
- $ rm "$TESTTMP"/extroot/foo.*
- $ rm -Rf "$TESTTMP/extroot/__pycache__"
- $ cat > $TESTTMP/extroot/foo.py <<NO_CHECK_EOF
- > # test relative import
- > buf = []
- > def func():
- > # "not locals" case
- > import bar
- > buf.append('import bar in func(): %s' % bar.s)
- > return '\n(extroot) '.join(buf)
- > # "fromlist == ('*',)" case
- > from bar import *
- > buf.append('from bar import *: %s' % s)
- > # "not fromlist" and "if '.' in name" case
- > import sub1.baz
- > buf.append('import sub1.baz: %s' % sub1.baz.s)
- > # "not fromlist" and NOT "if '.' in name" case
- > import sub1
- > buf.append('import sub1: %s' % sub1.s)
- > # NOT "not fromlist" and NOT "level != -1" case
- > from bar import s
- > buf.append('from bar import s: %s' % s)
- > NO_CHECK_EOF
- $ hg --config extensions.extroot=$TESTTMP/extroot root
- (extroot) from bar import *: this is extroot.bar
- (extroot) import sub1.baz: this is extroot.sub1.baz
- (extroot) import sub1: this is extroot.sub1.__init__
- (extroot) from bar import s: this is extroot.bar
- (extroot) import bar in func(): this is extroot.bar
- $TESTTMP/a
-#endif
-
#if demandimport
Examine whether module loading is delayed until actual referring, even
@@ -453,7 +400,6 @@
> detail = b"this is extlibroot.recursedown.abs.used"
> NO_CHECK_EOF
$ cat > $TESTTMP/extlibroot/recursedown/abs/__init__.py <<NO_CHECK_EOF
- > from __future__ import absolute_import
> from extlibroot.recursedown.abs.used import detail
> NO_CHECK_EOF
@@ -467,7 +413,6 @@
> NO_CHECK_EOF
$ cat > $TESTTMP/extlibroot/recursedown/__init__.py <<NO_CHECK_EOF
- > from __future__ import absolute_import
> from extlibroot.recursedown.abs import detail as absdetail
> from .legacy import detail as legacydetail
> NO_CHECK_EOF
@@ -481,11 +426,9 @@
> detail = b"this is extlibroot.shadowing.used"
> NO_CHECK_EOF
$ cat > $TESTTMP/extlibroot/shadowing/proxied.py <<NO_CHECK_EOF
- > from __future__ import absolute_import
> from extlibroot.shadowing.used import detail
> NO_CHECK_EOF
$ cat > $TESTTMP/extlibroot/shadowing/__init__.py <<NO_CHECK_EOF
- > from __future__ import absolute_import
> from .used import detail as used
> NO_CHECK_EOF
@@ -514,7 +457,6 @@
> detail = b"this is absextroot.relimportee"
> NO_CHECK_EOF
$ cat > $TESTTMP/absextroot/xsub1/xsub2/relimporter.py <<NO_CHECK_EOF
- > from __future__ import absolute_import
> from mercurial import pycompat
> from ... import relimportee
> detail = b"this relimporter imports %r" % (
@@ -525,7 +467,6 @@
runtime.
$ cat > $TESTTMP/absextroot/absolute.py << NO_CHECK_EOF
- > from __future__ import absolute_import
>
> # import extension local modules absolutely (level = 0)
> from absextroot.xsub1.xsub2 import used, unused
@@ -539,7 +480,6 @@
> NO_CHECK_EOF
$ cat > $TESTTMP/absextroot/relative.py << NO_CHECK_EOF
- > from __future__ import absolute_import
>
> # import extension local modules relatively (level == 1)
> from .xsub1.xsub2 import used, unused
@@ -559,7 +499,6 @@
Setup main procedure of extension.
$ cat > $TESTTMP/absextroot/__init__.py <<NO_CHECK_EOF
- > from __future__ import absolute_import
> from mercurial import registrar
> cmdtable = {}
> command = registrar.command(cmdtable)
@@ -1925,7 +1864,6 @@
$ hg init $TESTTMP/opt-unicode-default
$ cat > $TESTTMP/test_unicode_default_value.py << EOF
- > from __future__ import print_function
> from mercurial import registrar
> cmdtable = {}
> command = registrar.command(cmdtable)
@@ -1940,7 +1878,6 @@
> EOF
$ hg -R $TESTTMP/opt-unicode-default dummy
*** failed to import extension "test_unicode_default_value" from $TESTTMP/test_unicode_default_value.py: unicode 'value' found in cmdtable.dummy (py3 !)
- *** failed to import extension "test_unicode_default_value" from $TESTTMP/test_unicode_default_value.py: unicode u'value' found in cmdtable.dummy (no-py3 !)
*** (use b'' to make it byte string)
hg: unknown command 'dummy'
(did you mean summary?)
--- a/tests/test-extensions-wrapfunction.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-extensions-wrapfunction.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
from mercurial import extensions
@@ -18,7 +16,7 @@
wrappers = [genwrapper(i) for i in range(5)]
-class dummyclass(object):
+class dummyclass:
def getstack(self):
return ['orig']
@@ -69,7 +67,7 @@
print('context manager', dummy.getstack())
# Wrap callable object which has no __name__
-class callableobj(object):
+class callableobj:
def __call__(self):
return ['orig']
--- a/tests/test-fastannotate-hg.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-fastannotate-hg.t Fri Mar 25 11:33:12 2022 -0400
@@ -481,7 +481,6 @@
and its ancestor by overriding "repo._filecommit".
$ cat > ../legacyrepo.py <<EOF
- > from __future__ import absolute_import
> from mercurial import commit, error, extensions
> def _filecommit(orig, repo, fctx, manifest1, manifest2,
> linkrev, tr, includecopymeta, ms):
--- a/tests/test-fastannotate-revmap.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-fastannotate-revmap.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import os
import tempfile
@@ -171,7 +169,7 @@
os.unlink(path2)
-class fakefctx(object):
+class fakefctx:
def __init__(self, node, path=None):
self._node = node
self._path = path
--- a/tests/test-filebranch.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-filebranch.t Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
when we do a merge.
$ cat <<EOF > merge
- > from __future__ import print_function
> import sys, os
> print("merging for", os.path.basename(sys.argv[1]))
> EOF
--- a/tests/test-filecache.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-filecache.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
import os
import stat
import subprocess
@@ -36,11 +35,11 @@
xrange = range
-class fakerepo(object):
+class fakerepo:
def __init__(self):
self._filecache = {}
- class fakevfs(object):
+ class fakevfs:
def join(self, p):
return p
--- a/tests/test-filelog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-filelog.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
"""
Tests the behavior of filelog w.r.t. data starting with '\1\n'
"""
-from __future__ import absolute_import, print_function
from mercurial.node import hex
from mercurial import (
--- a/tests/test-flagprocessor.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-flagprocessor.t Fri Mar 25 11:33:12 2022 -0400
@@ -214,12 +214,10 @@
File "mercurial.revlogutils.flagutil", line *, in insertflagprocessor (glob) (pyoxidizer !)
raise error.Abort(msg)
mercurial.error.Abort: cannot register multiple processors on flag '0x8'. (py3 !)
- Abort: cannot register multiple processors on flag '0x8'. (no-py3 !)
*** failed to set up extension duplicate: cannot register multiple processors on flag '0x8'.
$ hg st 2>&1 | egrep 'cannot register multiple processors|flagprocessorext'
File "*/tests/flagprocessorext.py", line *, in extsetup (glob)
mercurial.error.Abort: cannot register multiple processors on flag '0x8'. (py3 !)
- Abort: cannot register multiple processors on flag '0x8'. (no-py3 !)
*** failed to set up extension duplicate: cannot register multiple processors on flag '0x8'.
File "*/tests/flagprocessorext.py", line *, in b64decode (glob)
--- a/tests/test-fncache.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-fncache.t Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
does not break
$ cat > chunksize.py <<EOF
- > from __future__ import absolute_import
> from mercurial import store
> store.fncache_chunksize = 1
> EOF
@@ -232,7 +231,6 @@
Aborting lock does not prevent fncache writes
$ cat > exceptionext.py <<EOF
- > from __future__ import absolute_import
> import os
> from mercurial import commands, error, extensions
>
@@ -279,7 +277,6 @@
Aborting transaction prevents fncache change
$ cat > ../exceptionext.py <<EOF
- > from __future__ import absolute_import
> import os
> from mercurial import commands, error, extensions, localrepo
>
@@ -315,7 +312,6 @@
Aborted transactions can be recovered later
$ cat > ../exceptionext.py <<EOF
- > from __future__ import absolute_import
> import os
> from mercurial import (
> commands,
@@ -483,7 +479,6 @@
changesets that only contain changes to existing files:
$ cat > fncacheloadwarn.py << EOF
- > from __future__ import absolute_import
> from mercurial import extensions, localrepo
>
> def extsetup(ui):
--- a/tests/test-generaldelta.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-generaldelta.t Fri Mar 25 11:33:12 2022 -0400
@@ -25,7 +25,6 @@
> done
$ cd ..
- >>> from __future__ import print_function
>>> import os
>>> regsize = os.stat("repo/.hg/store/00manifest.i").st_size
>>> gdsize = os.stat("gdrepo/.hg/store/00manifest.i").st_size
--- a/tests/test-hardlinks.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hardlinks.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
#require hardlink reporevlogstore
$ cat > nlinks.py <<EOF
- > from __future__ import print_function
> import sys
> from mercurial import pycompat, util
> for f in sorted(sys.stdin.readlines()):
@@ -17,7 +16,6 @@
Some implementations of cp can't create hardlinks (replaces 'cp -al' on Linux):
$ cat > linkcp.py <<EOF
- > from __future__ import absolute_import
> import sys
> from mercurial import pycompat, util
> util.copyfiles(pycompat.fsencode(sys.argv[1]),
--- a/tests/test-hashutil.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hashutil.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# Tests to ensure that sha1dc.sha1 is exactly a drop-in for
# hashlib.sha1 for our needs.
-from __future__ import absolute_import
import hashlib
import unittest
@@ -13,7 +12,7 @@
sha1dc = None
-class hashertestsbase(object):
+class hashertestsbase:
def test_basic_hash(self):
h = self.hasher()
h.update(b'foo')
--- a/tests/test-help.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-help.t Fri Mar 25 11:33:12 2022 -0400
@@ -1792,7 +1792,6 @@
>
> This paragraph is never omitted, too (for extension)
> '''
- > from __future__ import absolute_import
> from mercurial import commands, help
> testtopic = br"""This paragraph is never omitted (for topic).
>
--- a/tests/test-hg-parseurl.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hg-parseurl.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import unittest
from mercurial.utils import urlutil
--- a/tests/test-hgrc.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hgrc.t Fri Mar 25 11:33:12 2022 -0400
@@ -71,7 +71,7 @@
config error at $TESTTMP/hgrc:2: unexpected leading whitespace: x = y
[255]
- $ "$PYTHON" -c "from __future__ import print_function; print('[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n')" \
+ $ "$PYTHON" -c "print('[foo]\nbar = a\n b\n c \n de\n fg \nbaz = bif cb \n')" \
> > $HGRC
$ hg showconfig foo
foo.bar=a\nb\nc\nde\nfg
--- a/tests/test-hgweb-auth.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hgweb-auth.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
from mercurial import demandimport
demandimport.enable()
--- a/tests/test-hgweb-no-path-info.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hgweb-no-path-info.t Fri Mar 25 11:33:12 2022 -0400
@@ -15,7 +15,6 @@
summary: test
$ cat > request.py <<EOF
- > from __future__ import absolute_import
> import os
> import sys
> from mercurial import (
--- a/tests/test-hgweb-no-request-uri.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hgweb-no-request-uri.t Fri Mar 25 11:33:12 2022 -0400
@@ -15,7 +15,6 @@
summary: test
$ cat > request.py <<EOF
- > from __future__ import absolute_import
> import os
> import sys
> from mercurial import (
--- a/tests/test-hgweb-non-interactive.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hgweb-non-interactive.t Fri Mar 25 11:33:12 2022 -0400
@@ -7,7 +7,6 @@
$ hg add bar
$ hg commit -m "test"
$ cat > request.py <<EOF
- > from __future__ import absolute_import
> import os
> import sys
> from mercurial import (
--- a/tests/test-hgweb.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hgweb.t Fri Mar 25 11:33:12 2022 -0400
@@ -329,7 +329,7 @@
Test the access/error files are opened in append mode
- $ "$PYTHON" -c "from __future__ import print_function; print(len(open('access.log', 'rb').readlines()), 'log lines written')"
+ $ "$PYTHON" -c "print(len(open('access.log', 'rb').readlines()), 'log lines written')"
14 log lines written
static file
--- a/tests/test-hgwebdir-gc.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hgwebdir-gc.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import os
from mercurial.hgweb import hgwebdir_mod
--- a/tests/test-hgwebdir-paths.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hgwebdir-paths.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import os
from mercurial import (
hg,
--- a/tests/test-hook.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hook.t Fri Mar 25 11:33:12 2022 -0400
@@ -831,7 +831,6 @@
$ cd "$TESTTMP/b"
$ cat > hooktests.py <<EOF
- > from __future__ import print_function
> from mercurial import (
> error,
> pycompat,
@@ -979,7 +978,6 @@
Traceback (most recent call last): (py3 !)
SyntaxError: * (glob) (py3 !)
Traceback (most recent call last):
- ImportError: No module named hgext_syntaxerror (no-py3 !)
ImportError: No module named 'hgext_syntaxerror' (py3 no-py36 !)
ModuleNotFoundError: No module named 'hgext_syntaxerror' (py36 !)
Traceback (most recent call last):
@@ -988,7 +986,6 @@
ImportError: No module named 'hgext_syntaxerror' (py3 no-py36 !)
ModuleNotFoundError: No module named 'hgext_syntaxerror' (py36 !)
Traceback (most recent call last): (py3 !)
- HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed (no-py3 !)
raise error.HookLoadError( (py38 !)
mercurial.error.HookLoadError: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed (py3 !)
abort: preoutgoing.syntaxerror hook is invalid: import of "syntaxerror" failed
@@ -1123,7 +1120,6 @@
$ hg id
loading pre-identify.npmd hook failed:
- abort: No module named repo (no-py3 !)
abort: No module named 'repo' (py3 !)
[255]
@@ -1144,7 +1140,6 @@
$ hg --traceback commit -ma 2>&1 | egrep '^exception|ImportError|ModuleNotFoundError|Traceback|HookLoadError|abort'
exception from first failed import attempt:
Traceback (most recent call last):
- ImportError: No module named somebogusmodule (no-py3 !)
ImportError: No module named 'somebogusmodule' (py3 no-py36 !)
ModuleNotFoundError: No module named 'somebogusmodule' (py36 !)
exception from second failed import attempt:
@@ -1158,11 +1153,9 @@
ImportError: No module named 'somebogusmodule' (py3 no-py36 !)
ModuleNotFoundError: No module named 'somebogusmodule' (py36 !)
Traceback (most recent call last):
- ImportError: No module named hgext_importfail (no-py3 !)
ImportError: No module named 'hgext_importfail' (py3 no-py36 !)
ModuleNotFoundError: No module named 'hgext_importfail' (py36 !)
Traceback (most recent call last):
- HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed (no-py3 !)
raise error.HookLoadError( (py38 !)
mercurial.error.HookLoadError: precommit.importfail hook is invalid: import of "importfail" failed (py3 !)
abort: precommit.importfail hook is invalid: import of "importfail" failed
--- a/tests/test-http-bad-server.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-http-bad-server.t Fri Mar 25 11:33:12 2022 -0400
@@ -134,13 +134,6 @@
sendall(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py36 !)
write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-py3 !)
readline(~) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
readline(*) -> (1?) Accept-Encoding* (glob)
read limit reached; closing socket
@@ -183,13 +176,6 @@
sendall(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py36 !)
write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-py3 !)
readline(~) -> (26) GET /?cmd=batch HTTP/1.1\r\n (glob)
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -209,13 +195,6 @@
sendall(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
write(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(20) -> Content-Length: 42\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
readline(24 from ~) -> (*) GET /?cmd=getbundle HTTP* (glob)
read limit reached; closing socket
readline(~) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
@@ -253,13 +232,6 @@
sendall(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py36 !)
write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx httppostargs known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-py3 !)
readline(~) -> (27) POST /?cmd=batch HTTP/1.1\r\n (glob)
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (41) content-type: application/mercurial-0.1\r\n (glob)
@@ -312,7 +284,6 @@
readline(*) -> (2) \r\n (glob)
sendall(1 from 160) -> (0) H (py36 !)
write(1 from 160) -> (0) H (py3 no-py36 !)
- write(1 from 36) -> (0) H (no-py3 !)
write limit reached; closing socket
$LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=capabilities': (glob)
Traceback (most recent call last):
@@ -348,13 +319,6 @@
sendall(20 from *) -> (0) batch branchmap bund (glob) (py36 !)
write(160) -> (20) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(20 from *) -> (0) batch branchmap bund (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(20 from *) -> (0) batch branchmap bund (glob) (no-py3 !)
write limit reached; closing socket
$LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=capabilities': (glob)
Traceback (most recent call last):
@@ -394,13 +358,6 @@
sendall(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py36 !)
write(160) -> (568) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-py3 !)
readline(~) -> (26) GET /?cmd=batch HTTP/1.1\r\n
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -412,10 +369,6 @@
readline(*) -> (2) \r\n (glob)
sendall(118 from 159) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: applicat (py36 !)
write(118 from 159) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: applicat (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(22 from 41) -> (0) Content-Type: applicat (no-py3 !)
write limit reached; closing socket
$LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
Traceback (most recent call last):
@@ -455,13 +408,6 @@
sendall(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py36 !)
write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-py3 !)
readline(~) -> (26) GET /?cmd=batch HTTP/1.1\r\n
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -475,13 +421,6 @@
sendall(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (py36 !)
write(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
write(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(20) -> Content-Length: 42\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(24 from 42) -> (0) 96ee1d7354c4ad7372047672 (no-py3 !)
write limit reached; closing socket
$LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=batch': (glob)
Traceback (most recent call last):
@@ -522,13 +461,6 @@
sendall(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py36 !)
write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-py3 !)
readline(~) -> (26) GET /?cmd=batch HTTP/1.1\r\n
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -542,13 +474,6 @@
sendall(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
write(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(20) -> Content-Length: 42\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
readline(~) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -560,10 +485,6 @@
readline(*) -> (2) \r\n (glob)
sendall(129 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercuri (py36 !)
write(129 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercuri (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(33 from 41) -> (0) Content-Type: application/mercuri (no-py3 !)
write limit reached; closing socket
$LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
Traceback (most recent call last):
@@ -638,13 +559,6 @@
sendall(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py36 !)
write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-py3 !)
readline(~) -> (26) GET /?cmd=batch HTTP/1.1\r\n
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -658,13 +572,6 @@
sendall(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
write(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(20) -> Content-Length: 42\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
readline(~) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -676,12 +583,6 @@
readline(*) -> (2) \r\n (glob)
sendall(167 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py36 !)
write(167 from 167) -> (0) HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.2\r\n (no-py3 !)
- write(28) -> Transfer-Encoding: chunked\r\n (no-py3 !)
- write(2 from 2) -> (0) \r\n (no-py3 !)
write limit reached; closing socket
$LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
Traceback (most recent call last):
@@ -718,13 +619,6 @@
sendall(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py36 !)
write(160) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: *\r\n\r\n (glob) (py3 no-py36 !)
write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(21) -> Content-Length: *\r\n (glob) (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(*) -> batch branchmap $USUAL_BUNDLE2_CAPS_NO_PHASES$ changegroupsubset compression=none getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=* unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash (glob) (no-py3 !)
readline(~) -> (26) GET /?cmd=batch HTTP/1.1\r\n
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -737,13 +631,6 @@
sendall(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py36 !)
sendall(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (py36 !)
write(159) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.1\r\nContent-Length: 42\r\n\r\n (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.1\r\n (no-py3 !)
- write(20) -> Content-Length: 42\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(42) -> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n; (no-py3 !)
readline(~) -> (30) GET /?cmd=getbundle HTTP/1.1\r\n
readline(*) -> (27) Accept-Encoding: identity\r\n (glob)
readline(*) -> (29) vary: X-HgArg-1,X-HgProto-1\r\n (glob)
@@ -758,15 +645,6 @@
sendall(9) -> 4\r\nnone\r\n (py36 !)
sendall(9 from 9) -> (0) 4\r\nHG20\r\n (py36 !)
write(167) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 no-py36 !)
- write(36) -> HTTP/1.1 200 Script output follows\r\n (no-py3 !)
- write(23) -> Server: badhttpserver\r\n (no-py3 !)
- write(37) -> Date: $HTTP_DATE$\r\n (no-py3 !)
- write(41) -> Content-Type: application/mercurial-0.2\r\n (no-py3 !)
- write(28) -> Transfer-Encoding: chunked\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
- write(6) -> 1\\r\\n\x04\\r\\n (esc) (no-py3 !)
- write(9) -> 4\r\nnone\r\n (no-py3 !)
- write(9 from 9) -> (0) 4\r\nHG20\r\n (no-py3 !)
write limit reached; closing socket
$LOCALIP - - [$ERRDATE$] Exception happened during processing request '/?cmd=getbundle': (glob)
Traceback (most recent call last):
@@ -786,7 +664,6 @@
$ hg clone http://localhost:$HGPORT/ clone
requesting all changes
abort: HTTP request error (incomplete response) (py3 !)
- abort: HTTP request error (incomplete response; expected 4 bytes got 3) (no-py3 !)
(this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
[255]
@@ -808,9 +685,6 @@
$ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -11
readline(~) -> (2) \r\n (py3 !)
write(167) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
- write(41) -> Content-Type: application/mercurial-0.2\r\n (no-py3 !)
- write(28) -> Transfer-Encoding: chunked\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
write(6) -> 1\\r\\n\x04\\r\\n (esc)
write(9) -> 4\r\nnone\r\n
write(6 from 9) -> (0) 4\r\nHG2
@@ -834,7 +708,6 @@
$ hg clone http://localhost:$HGPORT/ clone
requesting all changes
abort: HTTP request error (incomplete response) (py3 !)
- abort: HTTP request error (incomplete response; expected 4 bytes got 3) (no-py3 !)
(this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
[255]
@@ -858,8 +731,6 @@
readline(~) -> (2) \r\n (py3 !)
write(167) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
write(41) -> Content-Type: application/mercurial-0.2\r\n
- write(28) -> Transfer-Encoding: chunked\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
write(6) -> 1\\r\\n\x04\\r\\n (esc)
write(9) -> 4\r\nnone\r\n
write(9) -> 4\r\nHG20\r\n
@@ -907,8 +778,6 @@
readline(~) -> (2) \r\n (py3 !)
write(167) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
write(41) -> Content-Type: application/mercurial-0.2\r\n
- write(28) -> Transfer-Encoding: chunked\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
write(6) -> 1\\r\\n\x04\\r\\n (esc)
write(9) -> 4\r\nnone\r\n
write(9) -> 4\r\nHG20\r\n
@@ -958,8 +827,6 @@
readline(~) -> (2) \r\n (py3 !)
write(167) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
write(41) -> Content-Type: application/mercurial-0.2\r\n
- write(28) -> Transfer-Encoding: chunked\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
write(6) -> 1\\r\\n\x04\\r\\n (esc)
write(9) -> 4\r\nnone\r\n
write(9) -> 4\r\nHG20\r\n
@@ -1013,8 +880,6 @@
readline(~) -> (2) \r\n (py3 !)
write(167) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
write(41) -> Content-Type: application/mercurial-0.2\r\n
- write(28) -> Transfer-Encoding: chunked\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
write(6) -> 1\\r\\n\x04\\r\\n (esc)
write(9) -> 4\r\nnone\r\n
write(9) -> 4\r\nHG20\r\n
@@ -1044,7 +909,6 @@
transaction abort!
rollback completed
abort: HTTP request error (incomplete response) (py3 !)
- abort: HTTP request error (incomplete response; expected 466 bytes got 7) (no-py3 !)
(this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
[255]
@@ -1071,7 +935,6 @@
$ "$PYTHON" $TESTDIR/filtertraceback.py < error.log | tail -15
write(167) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
write(28) -> Transfer-Encoding: chunked\r\n
- write(2) -> \r\n (no-py3 !)
write(6) -> 1\\r\\n\x04\\r\\n (esc)
write(9) -> 4\r\nnone\r\n
write(9) -> 4\r\nHG20\r\n
@@ -1130,8 +993,6 @@
readline(~) -> (2) \r\n (py3 !)
write(167) -> HTTP/1.1 200 Script output follows\r\nServer: badhttpserver\r\nDate: $HTTP_DATE$\r\nContent-Type: application/mercurial-0.2\r\nTransfer-Encoding: chunked\r\n\r\n (py3 !)
write(41) -> Content-Type: application/mercurial-0.2\r\n
- write(28) -> Transfer-Encoding: chunked\r\n (no-py3 !)
- write(2) -> \r\n (no-py3 !)
write(6) -> 1\\r\\n\x04\\r\\n (esc)
write(9) -> 4\r\nnone\r\n
write(9) -> 4\r\nHG20\r\n
@@ -1165,7 +1026,6 @@
transaction abort!
rollback completed
abort: HTTP request error (incomplete response) (py3 !)
- abort: HTTP request error (incomplete response; expected 32 bytes got 9) (no-py3 !)
(this may be an intermittent network failure; if the error persists, consider contacting the network or server operator)
[255]
--- a/tests/test-hybridencode.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-hybridencode.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import unittest
from mercurial import store
--- a/tests/test-impexp-branch.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-impexp-branch.t Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
$ echo 'strip =' >> $HGRCPATH
$ cat >findbranch.py <<EOF
- > from __future__ import absolute_import
> import re
> import sys
>
--- a/tests/test-import.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-import.t Fri Mar 25 11:33:12 2022 -0400
@@ -71,7 +71,6 @@
regardless of the commit message in the patch)
$ cat > dummypatch.py <<EOF
- > from __future__ import print_function
> print('patching file a')
> open('a', 'wb').write(b'line2\n')
> EOF
--- a/tests/test-imports-checker.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-imports-checker.t Fri Mar 25 11:33:12 2022 -0400
@@ -16,74 +16,61 @@
$ touch testpackage/__init__.py
$ cat > testpackage/multiple.py << EOF
- > from __future__ import absolute_import
> import os, sys
> EOF
$ cat > testpackage/unsorted.py << EOF
- > from __future__ import absolute_import
> import sys
> import os
> EOF
$ cat > testpackage/stdafterlocal.py << EOF
- > from __future__ import absolute_import
> from . import unsorted
> import os
> EOF
$ cat > testpackage/requirerelative.py << EOF
- > from __future__ import absolute_import
> import testpackage.unsorted
> EOF
$ cat > testpackage/importalias.py << EOF
- > from __future__ import absolute_import
> import ui
> EOF
$ cat > testpackage/relativestdlib.py << EOF
- > from __future__ import absolute_import
> from .. import os
> EOF
$ cat > testpackage/stdlibfrom.py << EOF
- > from __future__ import absolute_import
> from collections import abc
> EOF
$ cat > testpackage/symbolimport.py << EOF
- > from __future__ import absolute_import
> from .unsorted import foo
> EOF
$ cat > testpackage/latesymbolimport.py << EOF
- > from __future__ import absolute_import
> from . import unsorted
> from mercurial.node import hex
> EOF
$ cat > testpackage/multiplegroups.py << EOF
- > from __future__ import absolute_import
> from . import unsorted
> from . import more
> EOF
$ mkdir testpackage/subpackage
$ cat > testpackage/subpackage/levelpriority.py << EOF
- > from __future__ import absolute_import
> from . import foo
> from .. import parent
> EOF
$ touch testpackage/subpackage/foo.py
$ cat > testpackage/subpackage/__init__.py << EOF
- > from __future__ import absolute_import
> from . import levelpriority # should not cause cycle
> EOF
$ cat > testpackage/subpackage/localimport.py << EOF
- > from __future__ import absolute_import
> from . import foo
> def bar():
> # should not cause "higher-level import should come first"
@@ -94,17 +81,14 @@
> EOF
$ cat > testpackage/importmodulefromsub.py << EOF
- > from __future__ import absolute_import
> from .subpackage import foo # not a "direct symbol import"
> EOF
$ cat > testpackage/importsymbolfromsub.py << EOF
- > from __future__ import absolute_import
> from .subpackage import foo, nonmodule
> EOF
$ cat > testpackage/sortedentries.py << EOF
- > from __future__ import absolute_import
> from . import (
> foo,
> bar,
@@ -112,12 +96,10 @@
> EOF
$ cat > testpackage/importfromalias.py << EOF
- > from __future__ import absolute_import
> from . import ui
> EOF
$ cat > testpackage/importfromrelative.py << EOF
- > from __future__ import absolute_import
> from testpackage.unsorted import foo
> EOF
@@ -125,7 +107,6 @@
$ touch testpackage2/__init__.py
$ cat > testpackage2/latesymbolimport.py << EOF
- > from __future__ import absolute_import
> from testpackage import unsorted
> from mercurial.node import hex
> EOF
@@ -137,29 +118,28 @@
$ touch email/__init__.py
$ touch email/errors.py
$ cat > email/utils.py << EOF
- > from __future__ import absolute_import
> from . import errors
> EOF
$ "$PYTHON" "$import_checker" testpackage*/*.py testpackage/subpackage/*.py \
> email/*.py
- testpackage/importalias.py:2: ui module must be "as" aliased to uimod
- testpackage/importfromalias.py:2: ui from testpackage must be "as" aliased to uimod
- testpackage/importfromrelative.py:2: import should be relative: testpackage.unsorted
- testpackage/importfromrelative.py:2: direct symbol import foo from testpackage.unsorted
- testpackage/importsymbolfromsub.py:2: direct symbol import nonmodule from testpackage.subpackage
- testpackage/latesymbolimport.py:3: symbol import follows non-symbol import: mercurial.node
- testpackage/multiple.py:2: multiple imported names: os, sys
- testpackage/multiplegroups.py:3: multiple "from . import" statements
- testpackage/relativestdlib.py:2: relative import of stdlib module
- testpackage/requirerelative.py:2: import should be relative: testpackage.unsorted
- testpackage/sortedentries.py:2: imports from testpackage not lexically sorted: bar < foo
- testpackage/stdafterlocal.py:3: stdlib import "os" follows local import: testpackage
- testpackage/stdlibfrom.py:2: direct symbol import abc from collections
- testpackage/subpackage/levelpriority.py:3: higher-level import should come first: testpackage
- testpackage/subpackage/localimport.py:7: multiple "from .. import" statements
- testpackage/subpackage/localimport.py:8: import should be relative: testpackage.subpackage.levelpriority
- testpackage/symbolimport.py:2: direct symbol import foo from testpackage.unsorted
- testpackage/unsorted.py:3: imports not lexically sorted: os < sys
- testpackage2/latesymbolimport.py:3: symbol import follows non-symbol import: mercurial.node
+ testpackage/importalias.py:1: ui module must be "as" aliased to uimod
+ testpackage/importfromalias.py:1: ui from testpackage must be "as" aliased to uimod
+ testpackage/importfromrelative.py:1: import should be relative: testpackage.unsorted
+ testpackage/importfromrelative.py:1: direct symbol import foo from testpackage.unsorted
+ testpackage/importsymbolfromsub.py:1: direct symbol import nonmodule from testpackage.subpackage
+ testpackage/latesymbolimport.py:2: symbol import follows non-symbol import: mercurial.node
+ testpackage/multiple.py:1: multiple imported names: os, sys
+ testpackage/multiplegroups.py:2: multiple "from . import" statements
+ testpackage/relativestdlib.py:1: relative import of stdlib module
+ testpackage/requirerelative.py:1: import should be relative: testpackage.unsorted
+ testpackage/sortedentries.py:1: imports from testpackage not lexically sorted: bar < foo
+ testpackage/stdafterlocal.py:2: stdlib import "os" follows local import: testpackage
+ testpackage/stdlibfrom.py:1: direct symbol import abc from collections
+ testpackage/subpackage/levelpriority.py:2: higher-level import should come first: testpackage
+ testpackage/subpackage/localimport.py:6: multiple "from .. import" statements
+ testpackage/subpackage/localimport.py:7: import should be relative: testpackage.subpackage.levelpriority
+ testpackage/symbolimport.py:1: direct symbol import foo from testpackage.unsorted
+ testpackage/unsorted.py:2: imports not lexically sorted: os < sys
+ testpackage2/latesymbolimport.py:2: symbol import follows non-symbol import: mercurial.node
[1]
--- a/tests/test-inherit-mode.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-inherit-mode.t Fri Mar 25 11:33:12 2022 -0400
@@ -10,7 +10,6 @@
$ cd dir
$ cat >printmodes.py <<EOF
- > from __future__ import absolute_import, print_function
> import os
> import sys
>
@@ -31,7 +30,6 @@
> EOF
$ cat >mode.py <<EOF
- > from __future__ import absolute_import, print_function
> import os
> import sys
> print('%05o' % os.lstat(sys.argv[1]).st_mode)
--- a/tests/test-install.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-install.t Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
checking encoding (ascii)...
checking Python executable (*) (glob)
checking Python implementation (*) (glob)
- checking Python version (2.*) (glob) (no-py3 !)
checking Python version (3.*) (glob) (py3 !)
checking Python lib (.*[Ll]ib.*)... (re) (no-pyoxidizer !)
checking Python lib (.*pyoxidizer.*)... (re) (pyoxidizer !)
@@ -67,7 +66,6 @@
checking encoding (ascii)...
checking Python executable (*) (glob)
checking Python implementation (*) (glob)
- checking Python version (2.*) (glob) (no-py3 !)
checking Python version (3.*) (glob) (py3 !)
checking Python lib (.*[Ll]ib.*)... (re) (no-pyoxidizer !)
checking Python lib (.*pyoxidizer.*)... (re) (pyoxidizer !)
@@ -117,7 +115,6 @@
checking encoding (ascii)...
checking Python executable (*) (glob)
checking Python implementation (*) (glob)
- checking Python version (2.*) (glob) (no-py3 !)
checking Python version (3.*) (glob) (py3 !)
checking Python lib (.*[Ll]ib.*)... (re) (no-pyoxidizer !)
checking Python lib (.*pyoxidizer.*)... (re) (pyoxidizer !)
@@ -147,7 +144,6 @@
checking encoding (ascii)...
checking Python executable (*) (glob)
checking Python implementation (*) (glob)
- checking Python version (2.*) (glob) (no-py3 !)
checking Python version (3.*) (glob) (py3 !)
checking Python lib (.*[Ll]ib.*)... (re) (no-pyoxidizer !)
checking Python lib (.*pyoxidizer.*)... (re) (pyoxidizer !)
--- a/tests/test-keyword.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-keyword.t Fri Mar 25 11:33:12 2022 -0400
@@ -1412,7 +1412,6 @@
$ grep -v '^promptecho ' < $HGRCPATH >> $HGRCPATH.new
$ mv $HGRCPATH.new $HGRCPATH
- >>> from __future__ import print_function
>>> from hgclient import check, readchannel, runcommand
>>> @check
... def check(server):
--- a/tests/test-largefiles-cache.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-largefiles-cache.t Fri Mar 25 11:33:12 2022 -0400
@@ -96,7 +96,6 @@
$ cat > ls-l.py <<EOF
> #!$PYTHON
- > from __future__ import absolute_import, print_function
> import os
> import sys
> path = sys.argv[1]
--- a/tests/test-largefiles-small-disk.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-largefiles-small-disk.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
Test how largefiles abort in case the disk runs full
$ cat > criple.py <<EOF
- > from __future__ import absolute_import
> import errno
> import os
> import shutil
--- a/tests/test-lfs-pointer.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-lfs-pointer.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
# Import something from Mercurial, so the module loader gets initialized.
from mercurial import pycompat
--- a/tests/test-lfs-serve-access.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-lfs-serve-access.t Fri Mar 25 11:33:12 2022 -0400
@@ -355,7 +355,6 @@
$LOCALIP - - [$ERRDATE$] HG error: super(badstore, self).download(oid, src, contentlength)
$LOCALIP - - [$ERRDATE$] HG error: raise LfsCorruptionError( (glob) (py38 !)
$LOCALIP - - [$ERRDATE$] HG error: _(b'corrupt remote lfs object: %s') % oid (glob) (no-py38 !)
- $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (no-py3 !)
$LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: corrupt remote lfs object: b5bb9d8014a0f9b1d61e21e796d78dccdf1352f23cd32812f4850b878ae4944c (py3 !)
$LOCALIP - - [$ERRDATE$] HG error: (glob)
$LOCALIP - - [$ERRDATE$] Exception happened during processing request '/.hg/lfs/objects/276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d': (glob)
@@ -367,7 +366,6 @@
handled = wireprotoserver.handlewsgirequest( (py38 !)
return _processbasictransfer( (py38 !)
rctx, req, res, self.check_perm (no-py38 !)
- return func(*(args + a), **kw) (no-py3 !)
rctx.repo, req, res, lambda perm: checkperm(rctx, req, perm) (no-py38 !)
res.setbodybytes(localstore.read(oid))
blob = self._read(self.vfs, oid, verify)
@@ -381,7 +379,6 @@
$LOCALIP - - [$ERRDATE$] HG error: blobstore._verify(oid, b'dummy content') (glob)
$LOCALIP - - [$ERRDATE$] HG error: raise LfsCorruptionError( (glob) (py38 !)
$LOCALIP - - [$ERRDATE$] HG error: hint=_(b'run hg verify'), (glob) (no-py38 !)
- $LOCALIP - - [$ERRDATE$] HG error: LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (no-py3 !)
$LOCALIP - - [$ERRDATE$] HG error: hgext.lfs.blobstore.LfsCorruptionError: detected corrupt lfs object: 276f73cfd75f9fb519810df5f5d96d6594ca2521abd86cbcd92122f7d51a1f3d (py3 !)
$LOCALIP - - [$ERRDATE$] HG error: (glob)
--- a/tests/test-lfs-serve.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-lfs-serve.t Fri Mar 25 11:33:12 2022 -0400
@@ -107,7 +107,6 @@
$ cd client
$ echo 'non-lfs' > nonlfs.txt
- >>> from __future__ import absolute_import
>>> from hgclient import check, readchannel, runcommand
>>> @check
... def diff(server):
@@ -240,7 +239,6 @@
$ cd ../cmdserve_client3
- >>> from __future__ import absolute_import
>>> from hgclient import check, readchannel, runcommand
>>> @check
... def addrequirement(server):
@@ -355,7 +353,6 @@
$ mv $HGRCPATH $HGRCPATH.tmp
$ cp $HGRCPATH.orig $HGRCPATH
- >>> from __future__ import absolute_import
>>> from hgclient import bprint, check, readchannel, runcommand, stdout
>>> @check
... def checkflags(server):
@@ -404,7 +401,6 @@
> lfs = !
> EOF
- >>> from __future__ import absolute_import, print_function
>>> from hgclient import bprint, check, readchannel, runcommand, stdout
>>> @check
... def checkflags2(server):
--- a/tests/test-linelog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-linelog.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import difflib
import random
import unittest
--- a/tests/test-linerange.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-linerange.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import unittest
from mercurial import error, mdiff
from mercurial.utils import stringutil
--- a/tests/test-lock.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-lock.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import copy
import errno
import tempfile
@@ -37,7 +35,7 @@
return super(lockwrapper, self)._getpid() + self._pidoffset
-class teststate(object):
+class teststate:
def __init__(self, testcase, dir, pidoffset=0):
self._testcase = testcase
self._acquirecalled = False
--- a/tests/test-log-exthook.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-log-exthook.t Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
-------------------------------------------
$ cat > $TESTTMP/logexthook.py <<EOF
- > from __future__ import absolute_import
> import codecs
> from mercurial import (
> commands,
--- a/tests/test-log.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-log.t Fri Mar 25 11:33:12 2022 -0400
@@ -2451,7 +2451,6 @@
$ cat > ../names.py <<EOF
> """A small extension to test adding arbitrary names to a repo"""
- > from __future__ import absolute_import
> from mercurial import namespaces
>
> def reposetup(ui, repo):
--- a/tests/test-logtoprocess.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-logtoprocess.t Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
$ hg init
$ cat > $TESTTMP/foocommand.py << EOF
- > from __future__ import absolute_import
> from mercurial import registrar
> cmdtable = {}
> command = registrar.command(cmdtable)
--- a/tests/test-lrucachedict.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-lrucachedict.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import unittest
import silenttestrunner
--- a/tests/test-manifest.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-manifest.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import binascii
import itertools
import silenttestrunner
@@ -76,7 +74,7 @@
)
-class basemanifesttests(object):
+class basemanifesttests:
def parsemanifest(self, text):
raise NotImplementedError('parsemanifest not implemented by test case')
--- a/tests/test-match.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-match.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import unittest
import silenttestrunner
--- a/tests/test-mdiff.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-mdiff.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,3 @@
-from __future__ import absolute_import
-from __future__ import print_function
-
import unittest
from mercurial import mdiff
--- a/tests/test-merge-halt.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-merge-halt.t Fri Mar 25 11:33:12 2022 -0400
@@ -210,6 +210,6 @@
merge halted after failed merge (see hg resolve)
[240]
$ hg shelve --list
- default (* ago) changes to: foo (glob)
+ default (*s ago) * changes to: foo (glob)
$ hg unshelve --abort
unshelve of 'default' aborted
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/tests/test-merge-partial-tool.t Fri Mar 25 11:33:12 2022 -0400
@@ -0,0 +1,241 @@
+Test support for partial-resolution tools
+
+Create a tool that resolves conflicts after line 5 by simply dropping those
+lines (even if there are no conflicts there)
+ $ cat >> "$TESTTMP/head.sh" <<'EOF'
+ > #!/bin/sh
+ > for f in "$@"; do
+ > head -5 $f > tmp
+ > mv -f tmp $f
+ > done
+ > EOF
+ $ chmod +x "$TESTTMP/head.sh"
+...and another tool that keeps only the last 5 lines instead of the first 5.
+ $ cat >> "$TESTTMP/tail.sh" <<'EOF'
+ > #!/bin/sh
+ > for f in "$@"; do
+ > tail -5 $f > tmp
+ > mv -f tmp $f
+ > done
+ > EOF
+ $ chmod +x "$TESTTMP/tail.sh"
+
+Set up both tools to run on all patterns (the default), and let the `tail` tool
+run after the `head` tool, which means it will have no effect (we'll override it
+to test order later)
+ $ cat >> "$HGRCPATH" <<EOF
+ > [partial-merge-tools]
+ > head.executable=$TESTTMP/head.sh
+ > tail.executable=$TESTTMP/tail.sh
+ > tail.order=1
+ > EOF
+
+ $ make_commit() {
+ > echo "$@" | xargs -n1 > file
+ > hg add file 2> /dev/null
+ > hg ci -m "$*"
+ > }
+
+
+Let a partial-resolution tool resolve some conflicts and leave other conflicts
+for the regular merge tool (:merge3 here)
+
+ $ hg init repo
+ $ cd repo
+ $ make_commit a b c d e f
+ $ make_commit a b2 c d e f2
+ $ hg up 0
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ make_commit a b3 c d e f3
+ created new head
+ $ hg merge 1 -t :merge3
+ merging file
+ warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
+ [1]
+ $ cat file
+ a
+ <<<<<<< working copy: e11a49d4b620 - test: a b3 c d e f3
+ b3
+ ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
+ b
+ =======
+ b2
+ >>>>>>> merge rev: fbc096a40cc5 - test: a b2 c d e f2
+ c
+ d
+ e
+
+
+With premerge=keep, the partial-resolution tools runs before and doesn't see
+the conflict markers
+
+ $ hg up -C 2
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ cat >> .hg/hgrc <<EOF
+ > [merge-tools]
+ > my-local.executable = cat
+ > my-local.args = $local
+ > my-local.premerge = keep-merge3
+ > EOF
+ $ hg merge 1 -t my-local
+ merging file
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ cat file
+ a
+ <<<<<<< working copy: e11a49d4b620 - test: a b3 c d e f3
+ b3
+ ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
+ b
+ =======
+ b2
+ >>>>>>> merge rev: fbc096a40cc5 - test: a b2 c d e f2
+ c
+ d
+ e
+
+
+When a partial-resolution tool resolves all conflicts, the resolution should
+be recorded and the regular merge tool should not be invoked for the file.
+
+ $ hg up -C 0
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ make_commit a b c d e f2
+ created new head
+ $ hg up 0
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ make_commit a b c d e f3
+ created new head
+ $ hg merge 3 -t false
+ merging file
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ cat file
+ a
+ b
+ c
+ d
+ e
+
+
+Only tools whose patterns match are run. We make `head` not match here, so
+only `tail` should run
+
+ $ hg up -C 4
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg merge 3 -t :merge3 --config partial-merge-tools.head.patterns=other
+ merging file
+ warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
+ [1]
+ $ cat file
+ b
+ c
+ d
+ e
+ <<<<<<< working copy: d57edaa6e21a - test: a b c d e f3
+ f3
+ ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
+ f
+ =======
+ f2
+ >>>>>>> merge rev: 8c217da987be - test: a b c d e f2
+
+
+If there are several matching tools, they are run in requested order. We move
+`head` after `tail` in order here so it has no effect (the conflict in "f" thus
+remains).
+
+ $ hg up -C 4
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg merge 3 -t :merge3 --config partial-merge-tools.head.order=2
+ merging file
+ warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
+ [1]
+ $ cat file
+ b
+ c
+ d
+ e
+ <<<<<<< working copy: d57edaa6e21a - test: a b c d e f3
+ f3
+ ||||||| common ancestor: 8ae8bb9cc43a - test: a b c d e f
+ f
+ =======
+ f2
+ >>>>>>> merge rev: 8c217da987be - test: a b c d e f2
+
+
+When using "nomerge" tools (e.g. `:other`), the partial-resolution tools
+should not be run.
+
+ $ hg up -C 4
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg merge 3 -t :other
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ cat file
+ a
+ b
+ c
+ d
+ e
+ f2
+
+
+If a partial-resolution tool resolved some conflict and simplemerge can
+merge the rest, then the regular merge tool should not be used. Here we merge
+"a b c d e3 f3" with "a b2 c d e f2". The `head` tool resolves the conflict in
+"f" and the internal simplemerge merges the remaining changes in "b" and "e".
+
+ $ hg up -C 0
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ make_commit a b c d e3 f3
+ created new head
+ $ hg merge 1 -t false
+ merging file
+ 0 files updated, 1 files merged, 0 files removed, 0 files unresolved
+ (branch merge, don't forget to commit)
+ $ cat file
+ a
+ b2
+ c
+ d
+ e3
+
+Test that arguments get passed as expected.
+
+ $ cat >> "$TESTTMP/log-args.sh" <<'EOF'
+ > #!/bin/sh
+ > echo "$@" > args.log
+ > EOF
+ $ chmod +x "$TESTTMP/log-args.sh"
+ $ cat >> "$HGRCPATH" <<EOF
+ > [partial-merge-tools]
+ > log-args.executable=$TESTTMP/log-args.sh
+ > EOF
+ $ hg up -C 2
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg merge 1
+ merging file
+ warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
+ [1]
+ $ cat args.log
+ */hgmerge-*/file~local */hgmerge-*/file~base */hgmerge-*/file~other (glob)
+ $ hg up -C 2
+ 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
+ $ hg merge 1 --config partial-merge-tools.log-args.args='--other $other $base --foo --local $local --also-other $other'
+ merging file
+ warning: conflicts while merging file! (edit, then use 'hg resolve --mark')
+ 0 files updated, 0 files merged, 0 files removed, 1 files unresolved
+ use 'hg resolve' to retry unresolved file merges or 'hg merge --abort' to abandon
+ [1]
+ $ cat args.log
+ --other */hgmerge-*/file~other */hgmerge-*/file~base --foo --local */hgmerge-*/file~local --also-other */hgmerge-*/file~other (glob)
--- a/tests/test-merge-symlinks.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-merge-symlinks.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
$ cat > echo.py <<EOF
> #!$PYTHON
- > from __future__ import absolute_import, print_function
> import os
> import sys
> try:
--- a/tests/test-merge1.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-merge1.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
$ cat <<EOF > merge
- > from __future__ import print_function
> import sys, os
>
> try:
@@ -354,7 +353,6 @@
trigger it. If you see flakyness here, there is a race.
$ cat > $TESTTMP/abort.py <<EOF
- > from __future__ import absolute_import
> # emulate aborting before "recordupdates()". in this case, files
> # are changed without updating dirstate
> from mercurial import (
--- a/tests/test-minifileset.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-minifileset.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,3 @@
-from __future__ import absolute_import
-from __future__ import print_function
-
from mercurial import minifileset
--- a/tests/test-minirst.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-minirst.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
from mercurial import minirst
from mercurial.utils import stringutil
--- a/tests/test-mq-missingfiles.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-mq-missingfiles.t Fri Mar 25 11:33:12 2022 -0400
@@ -5,10 +5,7 @@
$ cat > writelines.py <<EOF
> import sys
- > if sys.version_info[0] >= 3:
- > encode = lambda x: x.encode('utf-8').decode('unicode_escape').encode('utf-8')
- > else:
- > encode = lambda x: x.decode('string_escape')
+ > encode = lambda x: x.encode('utf-8').decode('unicode_escape').encode('utf-8')
> path = sys.argv[1]
> args = sys.argv[2:]
> assert (len(args) % 2) == 0
--- a/tests/test-mq-qimport.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-mq-qimport.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,9 +1,6 @@
$ cat > writelines.py <<EOF
> import sys
- > if sys.version_info[0] >= 3:
- > encode = lambda x: x.encode('utf-8').decode('unicode_escape').encode('utf-8')
- > else:
- > encode = lambda x: x.decode('string_escape')
+ > encode = lambda x: x.encode('utf-8').decode('unicode_escape').encode('utf-8')
> path = sys.argv[1]
> args = sys.argv[2:]
> assert (len(args) % 2) == 0
--- a/tests/test-narrow-clone-non-narrow-server.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-narrow-clone-non-narrow-server.t Fri Mar 25 11:33:12 2022 -0400
@@ -20,7 +20,6 @@
Verify that narrow is advertised in the bundle2 capabilities:
$ cat >> unquote.py <<EOF
- > from __future__ import print_function
> import sys
> if sys.version[0] == '3':
> import urllib.parse as up
--- a/tests/test-notify-changegroup.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-notify-changegroup.t Fri Mar 25 11:33:12 2022 -0400
@@ -40,7 +40,7 @@
$ hg --traceback --cwd b push ../a 2>&1 |
> "$PYTHON" $TESTDIR/unwrap-message-id.py | \
- > "$PYTHON" -c 'from __future__ import print_function ; import sys,re; print(re.sub("\n\t", " ", sys.stdin.read()), end="")'
+ > "$PYTHON" -c 'import sys,re; print(re.sub("\n\t", " ", sys.stdin.read()), end="")'
pushing to ../a
searching for changes
adding changesets
@@ -95,7 +95,7 @@
$ hg --config notify.sources=unbundle --cwd a unbundle ../test.hg 2>&1 |
> "$PYTHON" $TESTDIR/unwrap-message-id.py | \
- > "$PYTHON" -c 'from __future__ import print_function ; import sys,re; print(re.sub("\n\t", " ", sys.stdin.read()), end="")'
+ > "$PYTHON" -c 'import sys,re; print(re.sub("\n\t", " ", sys.stdin.read()), end="")'
adding changesets
adding manifests
adding file changes
@@ -172,7 +172,7 @@
$ hg --traceback --cwd b --config notify.fromauthor=True push ../a 2>&1 |
> "$PYTHON" $TESTDIR/unwrap-message-id.py | \
- > "$PYTHON" -c 'from __future__ import print_function ; import sys,re; print(re.sub("\n\t", " ", sys.stdin.read()), end="")'
+ > "$PYTHON" -c 'import sys,re; print(re.sub("\n\t", " ", sys.stdin.read()), end="")'
pushing to ../a
searching for changes
adding changesets
--- a/tests/test-notify.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-notify.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,16 +1,14 @@
$ cat > $TESTTMP/filter.py <<EOF
- > from __future__ import absolute_import, print_function
> import io
> import re
> import sys
- > if sys.version_info[0] >= 3:
- > sys.stdout = io.TextIOWrapper(
- > sys.stdout.buffer,
- > sys.stdout.encoding,
- > sys.stdout.errors,
- > newline="\n",
- > line_buffering=sys.stdout.line_buffering,
- > )
+ > sys.stdout = io.TextIOWrapper(
+ > sys.stdout.buffer,
+ > sys.stdout.encoding,
+ > sys.stdout.errors,
+ > newline="\n",
+ > line_buffering=sys.stdout.line_buffering,
+ > )
> print(re.sub("\n[ \t]", " ", sys.stdin.read()), end="")
> EOF
@@ -469,7 +467,6 @@
Content-Transfer-Encoding: 8bit
X-Test: foo
Date: * (glob)
- Subject: \xc3\xa0... (esc) (no-py3 !)
Subject: =?utf-8?b?w6AuLi4=?= (py3 !)
From: test@test.com
X-Hg-Notification: changeset 0f25f9c22b4c
--- a/tests/test-obsolete.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-obsolete.t Fri Mar 25 11:33:12 2022 -0400
@@ -1465,7 +1465,6 @@
Test heads computation on pending index changes with obsolescence markers
$ cd ..
$ cat >$TESTTMP/test_extension.py << EOF
- > from __future__ import absolute_import
> from mercurial.i18n import _
> from mercurial import cmdutil, pycompat, registrar
> from mercurial.utils import stringutil
@@ -1499,7 +1498,6 @@
bookmarks change
$ cd ..
$ cat >$TESTTMP/test_extension.py << EOF
- > from __future__ import absolute_import, print_function
> import weakref
> from mercurial import (
> bookmarks,
--- a/tests/test-pager.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-pager.t Fri Mar 25 11:33:12 2022 -0400
@@ -411,7 +411,6 @@
Environment variables like LESS and LV are set automatically:
$ cat > $TESTTMP/printlesslv.py <<EOF
- > from __future__ import absolute_import
> import os
> import sys
> sys.stdin.read()
--- a/tests/test-parseindex.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-parseindex.t Fri Mar 25 11:33:12 2022 -0400
@@ -26,7 +26,6 @@
summary: change foo
$ cat >> test.py << EOF
- > from __future__ import print_function
> from mercurial import changelog, node, pycompat, vfs
>
> class singlebyteread(object):
@@ -75,7 +74,6 @@
$ cd a
$ "$PYTHON" <<EOF
- > from __future__ import print_function
> from mercurial import changelog, vfs
> cl = changelog.changelog(vfs.vfs(b'.hg/store'))
> print('good heads:')
@@ -177,7 +175,6 @@
1 2 1 -1 base 66 65 66 1.01538 66 0 0.00000
$ cat <<EOF > test.py
- > from __future__ import print_function
> import sys
> from mercurial import changelog, pycompat, vfs
> cl = changelog.changelog(vfs.vfs(pycompat.fsencode(sys.argv[1])))
--- a/tests/test-parseindex2.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-parseindex2.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
It also checks certain aspects of the parsers module as a whole.
"""
-from __future__ import absolute_import, print_function
import os
import struct
--- a/tests/test-patch.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-patch.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
$ cat > patchtool.py <<EOF
- > from __future__ import absolute_import, print_function
> import sys
> print('Using custom patch')
> if '--binary' in sys.argv:
--- a/tests/test-patchbomb.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-patchbomb.t Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
--===+[0-9]+=+$ -> --===*= (glob)
$ cat > prune-blank-after-boundary.py <<EOF
- > from __future__ import absolute_import, print_function
> import sys
> skipblank = False
> trim = lambda x: x.strip(' \r\n')
@@ -514,7 +513,6 @@
X-Mercurial-Series-Id: <f81ef97829467e868fc4.240@test-hostname>
User-Agent: Mercurial-patchbomb/* (glob)
Date: Thu, 01 Jan 1970 00:04:00 +0000
- From: Q <quux> (no-py3 !)
From: =?iso-8859-1?q?Q?= <quux> (py3 !)
To: foo
Cc: bar
@@ -2400,9 +2398,6 @@
User-Agent: Mercurial-patchbomb/* (glob)
Date: Tue, 01 Jan 1980 00:01:00 +0000
From: quux
- To: spam <spam>, eggs, toast (no-py3 !)
- Cc: foo, bar@example.com, "A, B <>" <a@example.com> (no-py3 !)
- Bcc: "Quux, A." <quux> (no-py3 !)
To: =?iso-8859-1?q?spam?= <spam>, eggs, toast (py3 !)
Cc: foo, bar@example.com, =?iso-8859-1?q?A=2C_B_=3C=3E?= <a@example.com> (py3 !)
Bcc: =?iso-8859-1?q?Quux=2C_A=2E?= <quux> (py3 !)
@@ -2722,7 +2717,6 @@
MIME-Version: 1.0
Content-Type: text/plain; charset="iso-8859-1"
Content-Transfer-Encoding: quoted-printable
- Subject: [PATCH 2 of 6] \xe7a (esc) (no-py3 !)
Subject: =?utf-8?b?W1BBVENIIDIgb2YgNl0gw6dh?= (py3 !)
X-Mercurial-Node: f81ef97829467e868fc405fccbcfa66217e4d3e6
X-Mercurial-Series-Index: 2
--- a/tests/test-pathencode.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-pathencode.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# that have proven likely to expose bugs and divergent behavior in
# different encoding implementations.
-from __future__ import absolute_import, print_function
import binascii
import collections
@@ -67,7 +66,7 @@
counts[c] += 1
for c in '\r/\n':
counts.pop(c, None)
- t = sum(pycompat.itervalues(counts)) / 100.0
+ t = sum(counts.values()) / 100.0
fp.write('probtable = (')
for i, (k, v) in enumerate(
sorted(counts.items(), key=lambda x: x[1], reverse=True)
--- a/tests/test-profile.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-profile.t Fri Mar 25 11:33:12 2022 -0400
@@ -132,7 +132,6 @@
profiler extension could be loaded before other extensions
$ cat > fooprof.py <<EOF
- > from __future__ import absolute_import
> import contextlib
> import sys
> @contextlib.contextmanager
@@ -147,7 +146,6 @@
> EOF
$ cat > otherextension.py <<EOF
- > from __future__ import absolute_import
> def extsetup(ui):
> ui.write(b'otherextension: loaded\n')
> EOF
--- a/tests/test-progress.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-progress.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
$ cat > loop.py <<EOF
- > from __future__ import absolute_import
> import time
> from mercurial import commands, registrar
>
--- a/tests/test-propertycache.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-propertycache.py Fri Mar 25 11:33:12 2022 -0400
@@ -4,7 +4,6 @@
property cache of both localrepo and repoview to prevent
regression."""
-from __future__ import absolute_import, print_function
import os
import subprocess
--- a/tests/test-pull-network.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-pull-network.t Fri Mar 25 11:33:12 2022 -0400
@@ -90,12 +90,12 @@
It's tricky to make file:// URLs working on every platform with
regular shell commands.
- $ URL=`"$PYTHON" -c "from __future__ import print_function; import os; print('file://foobar' + ('/' + os.getcwd().replace(os.sep, '/')).replace('//', '/') + '/../test')"`
+ $ URL=`"$PYTHON" -c "import os; print('file://foobar' + ('/' + os.getcwd().replace(os.sep, '/')).replace('//', '/') + '/../test')"`
$ hg pull -q "$URL"
abort: file:// URLs can only refer to localhost
[255]
- $ URL=`"$PYTHON" -c "from __future__ import print_function; import os; print('file://localhost' + ('/' + os.getcwd().replace(os.sep, '/')).replace('//', '/') + '/../test')"`
+ $ URL=`"$PYTHON" -c "import os; print('file://localhost' + ('/' + os.getcwd().replace(os.sep, '/')).replace('//', '/') + '/../test')"`
$ hg pull -q "$URL"
SEC: check for unsafe ssh url
--- a/tests/test-rebase-dest.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-rebase-dest.t Fri Mar 25 11:33:12 2022 -0400
@@ -81,7 +81,6 @@
$ cd $TESTTMP
$ cat >> $TESTTMP/maprevset.py <<EOF
- > from __future__ import absolute_import
> from mercurial import registrar, revset, revsetlang, smartset
> revsetpredicate = registrar.revsetpredicate()
> cache = {}
--- a/tests/test-rebase-scenario-global.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-rebase-scenario-global.t Fri Mar 25 11:33:12 2022 -0400
@@ -949,7 +949,6 @@
$ hg init tr-state
$ cd tr-state
$ cat > $TESTTMP/wraprebase.py <<EOF
- > from __future__ import absolute_import
> from mercurial import extensions
> def _rebase(orig, ui, repo, *args, **kwargs):
> with repo.wlock():
--- a/tests/test-relink.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-relink.t Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
> }
$ cat > arelinked.py <<EOF
- > from __future__ import absolute_import, print_function
> import os
> import sys
> from mercurial import (
--- a/tests/test-remotefilelog-corrupt-cache.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-remotefilelog-corrupt-cache.t Fri Mar 25 11:33:12 2022 -0400
@@ -38,7 +38,6 @@
$ chmod u+w $CACHEDIR/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/1406e74118627694268417491f018a4a883152f0
$ echo x > $CACHEDIR/master/11/f6ad8ec52a2984abaafd7c3b516503785c2072/1406e74118627694268417491f018a4a883152f0
$ hg up tip 2>&1 | egrep "^[^ ].*unexpected remotefilelog"
- abort: unexpected remotefilelog header: illegal format (no-py3 !)
hgext.remotefilelog.shallowutil.BadRemotefilelogHeader: unexpected remotefilelog header: illegal format (py3 !)
Verify detection and remediation when remotefilelog.validatecachelog is set
--- a/tests/test-remotefilelog-datapack.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-remotefilelog-datapack.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-from __future__ import absolute_import, print_function
import hashlib
import os
@@ -36,7 +35,7 @@
)
-class datapacktestsbase(object):
+class datapacktestsbase:
def __init__(self, datapackreader, paramsavailable):
self.datapackreader = datapackreader
self.paramsavailable = paramsavailable
--- a/tests/test-remotefilelog-histpack.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-remotefilelog-histpack.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-from __future__ import absolute_import
import hashlib
import os
--- a/tests/test-rename.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-rename.t Fri Mar 25 11:33:12 2022 -0400
@@ -682,7 +682,6 @@
"hg cp" does not preserve the mtime, so it should be newer than the 2009
timestamp.
$ hg cp -q mtime mtime_cp
- >>> from __future__ import print_function
>>> import os
>>> filename = "mtime_cp/f"
>>> print(os.stat(filename).st_mtime < 1234567999)
@@ -691,7 +690,6 @@
(modulo some fudge factor due to not every system supporting 1s-level
precision).
$ hg mv -q mtime mtime_mv
- >>> from __future__ import print_function
>>> import os
>>> filename = "mtime_mv/f"
>>> print(os.stat(filename).st_mtime < 1234567999)
--- a/tests/test-requires.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-requires.t Fri Mar 25 11:33:12 2022 -0400
@@ -32,7 +32,6 @@
$ echo 'featuresetup-test' >> supported/.hg/requires
$ cat > $TESTTMP/supported-locally/supportlocally.py <<EOF
- > from __future__ import absolute_import
> from mercurial import extensions, localrepo
> def featuresetup(ui, supported):
> for name, module in extensions.extensions(ui):
--- a/tests/test-revert.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-revert.t Fri Mar 25 11:33:12 2022 -0400
@@ -550,7 +550,6 @@
$ cat << EOF >> dircontent.py
> # generate a simple text view of the directory for easy comparison
- > from __future__ import print_function
> import os
> files = os.listdir('.')
> files.sort()
--- a/tests/test-revlog-ancestry.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-revlog-ancestry.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
import os
from mercurial import (
hg,
--- a/tests/test-revlog-mmapindex.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-revlog-mmapindex.t Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
$ cat << EOF > verbosemmap.py
> # extension to make util.mmapread verbose
>
- > from __future__ import absolute_import
>
> from mercurial import (
> extensions,
--- a/tests/test-revlog-raw.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-revlog-raw.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# test revlog interaction about raw data (flagprocessor)
-from __future__ import absolute_import, print_function
import collections
import hashlib
@@ -20,7 +19,7 @@
)
-class _NoTransaction(object):
+class _NoTransaction:
"""transaction like object to update the nodemap outside a transaction"""
def __init__(self):
@@ -151,7 +150,7 @@
code path, which is not covered by "appendrev" alone.
"""
- class dummychangegroup(object):
+ class dummychangegroup:
@staticmethod
def deltachunk(pnode):
pnode = pnode or rlog.nullid
--- a/tests/test-revset.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-revset.t Fri Mar 25 11:33:12 2022 -0400
@@ -36,7 +36,6 @@
these predicates use '\0' as a separator:
$ cat <<EOF > debugrevlistspec.py
- > from __future__ import absolute_import
> from mercurial import (
> node as nodemod,
> registrar,
--- a/tests/test-rhg.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-rhg.t Fri Mar 25 11:33:12 2022 -0400
@@ -391,3 +391,17 @@
$ echo "*:required = yes" >> $HGRCPATH
$ rhg files
a
+
+We can ignore all extensions at once
+
+ $ echo "[extensions]" >> $HGRCPATH
+ $ echo "thisextensionbetternotexist=" >> $HGRCPATH
+ $ echo "thisextensionbetternotexisteither=" >> $HGRCPATH
+ $ $NO_FALLBACK rhg files
+ unsupported feature: extensions: thisextensionbetternotexist, thisextensionbetternotexisteither (consider adding them to 'rhg.ignored-extensions' config)
+ [252]
+
+ $ echo "[rhg]" >> $HGRCPATH
+ $ echo "ignored-extensions=*" >> $HGRCPATH
+ $ $NO_FALLBACK rhg files
+ a
--- a/tests/test-run-tests.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-run-tests.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
run-test.t only checks positive matches and can not see warnings
(both by design)
"""
-from __future__ import absolute_import, print_function
import doctest
import os
--- a/tests/test-run-tests.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-run-tests.t Fri Mar 25 11:33:12 2022 -0400
@@ -2086,5 +2086,4 @@
$ ./test-py3.py
3.* (glob)
$ ./test-py.py
- 2.* (glob) (no-py3 !)
3.* (glob) (py3 !)
--- a/tests/test-rust-ancestor.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-rust-ancestor.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
import sys
import unittest
--- a/tests/test-rust-discovery.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-rust-discovery.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
import unittest
from mercurial import policy
@@ -32,12 +31,12 @@
)
-class fakechangelog(object):
+class fakechangelog:
def __init__(self, idx):
self.index = idx
-class fakerepo(object):
+class fakerepo:
def __init__(self, idx):
"""Just make so that self.changelog.index is the given idx."""
self.changelog = fakechangelog(idx)
--- a/tests/test-rust-revlog.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-rust-revlog.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import
import unittest
try:
--- a/tests/test-share-bookmarks.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-share-bookmarks.t Fri Mar 25 11:33:12 2022 -0400
@@ -222,7 +222,6 @@
$ cat > failpullbookmarks.py << EOF
> """A small extension that makes bookmark pulls fail, for testing"""
- > from __future__ import absolute_import
> from mercurial import (
> error,
> exchange,
--- a/tests/test-shelve.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-shelve.t Fri Mar 25 11:33:12 2022 -0400
@@ -976,7 +976,7 @@
Test shelve --delete
$ hg shelve --list
- default (*s ago) changes to: create conflict (glob)
+ default (*s ago) * changes to: create conflict (glob)
$ hg shelve --delete doesnotexist
abort: shelved change 'doesnotexist' not found
[10]
@@ -1209,7 +1209,7 @@
$ hg add e
$ hg ci -m e
$ hg shelve --patch
- default (*s ago) changes to: b (glob)
+ default (*s ago) * changes to: b (glob)
diff --git a/c b/c
new file mode 100644
@@ -1258,7 +1258,7 @@
e
-- shelve should not contain `c` now
$ hg shelve --patch
- default (*s ago) changes to: b (glob)
+ default (*s ago) * changes to: b (glob)
diff --git a/d b/d
new file mode 100644
@@ -1357,7 +1357,7 @@
A
B
$ hg shelve --patch
- default (*s ago) changes to: add B to foo (glob)
+ default (*s ago) * changes to: add B to foo (glob)
diff --git a/foo b/foo
--- a/foo
--- a/tests/test-simplekeyvaluefile.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-simplekeyvaluefile.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import unittest
import silenttestrunner
@@ -9,7 +7,7 @@
)
-class mockfile(object):
+class mockfile:
def __init__(self, name, fs):
self.name = name
self.fs = fs
@@ -27,7 +25,7 @@
return self.fs.contents[self.name]
-class mockvfs(object):
+class mockvfs:
def __init__(self):
self.contents = {}
--- a/tests/test-simplemerge.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-simplemerge.py Fri Mar 25 11:33:12 2022 -0400
@@ -13,7 +13,6 @@
# You should have received a copy of the GNU General Public License
# along with this program; if not, see <http://www.gnu.org/licenses/>.
-from __future__ import absolute_import
import unittest
from mercurial import (
--- a/tests/test-ssh-proto-unbundle.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-ssh-proto-unbundle.t Fri Mar 25 11:33:12 2022 -0400
@@ -99,7 +99,6 @@
Test pushing to a server that has a pretxnchangegroup Python hook that fails
$ cat > $TESTTMP/failhook << EOF
- > from __future__ import print_function
> import sys
> def hook1line(ui, repo, **kwargs):
> ui.write(b'ui.write 1 line\n')
--- a/tests/test-ssh.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-ssh.t Fri Mar 25 11:33:12 2022 -0400
@@ -326,7 +326,6 @@
remote: added 1 changesets with 1 changes to 1 files (py3 !)
remote: KABOOM
remote: KABOOM IN PROCESS
- remote: added 1 changesets with 1 changes to 1 files (no-py3 !)
#endif
--- a/tests/test-sshserver.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-sshserver.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import io
import unittest
@@ -40,12 +38,12 @@
return wireprotoserver.sshserver(ui, repo)
-class mockrepo(object):
+class mockrepo:
def __init__(self, ui):
self.ui = ui
-class mockui(object):
+class mockui:
def __init__(self, inbytes):
self.fin = io.BytesIO(inbytes)
self.fout = io.BytesIO()
--- a/tests/test-status-inprocess.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-status-inprocess.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
#!/usr/bin/env python
-from __future__ import absolute_import, print_function
import sys
--- a/tests/test-status.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-status.t Fri Mar 25 11:33:12 2022 -0400
@@ -315,9 +315,8 @@
]
$ hg status -A -Tpickle > pickle
- >>> from __future__ import print_function
+ >>> import pickle
>>> from mercurial import util
- >>> pickle = util.pickle
>>> data = sorted((x[b'status'].decode(), x[b'path'].decode()) for x in pickle.load(open("pickle", r"rb")))
>>> for s, p in data: print("%s %s" % (s, p))
! deleted
--- a/tests/test-stdio.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-stdio.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,11 +2,11 @@
"""
Tests the buffering behavior of stdio streams in `mercurial.utils.procutil`.
"""
-from __future__ import absolute_import
import contextlib
import errno
import os
+import pickle
import signal
import subprocess
import sys
@@ -336,7 +336,7 @@
proc.stdin.close()
def post_child_check():
- err = util.pickle.load(err_f)
+ err = pickle.load(err_f)
self.assertEqual(err.errno, errno.EPIPE)
self.assertEqual(err.strerror, "Broken pipe")
--- a/tests/test-storage.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-storage.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
# This test verifies the conformance of various classes to various
# storage interfaces.
-from __future__ import absolute_import
import silenttestrunner
--- a/tests/test-strip.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-strip.t Fri Mar 25 11:33:12 2022 -0400
@@ -1290,7 +1290,6 @@
2 files updated, 0 files merged, 0 files removed, 0 files unresolved
$ echo 3 >> I
$ cat > $TESTTMP/delayedstrip.py <<EOF
- > from __future__ import absolute_import
> from mercurial import commands, registrar, repair
> cmdtable = {}
> command = registrar.command(cmdtable)
--- a/tests/test-subrepo-git.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-subrepo-git.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,20 +1,5 @@
#require git
-# XXX-CHG When running with python2 + chg this test tend to get stuck and end up
-# as a time-out error. My effort to reproduce this outside of the CI failed. The
-# test itself seems to pass fine, but never "complete". Debugging it is slow and
-# tedious. This as a bad impact on the development process as most CI run end up
-# wasting abotu 1h until that one fails.
-#
-# Pierre-Yves David, Augie Fackler and Raphaël Gomès all agreed to disable this
-# case in that specific case until we figure this out (or we drop python2 o:-) )
-
-#if no-py3 chg
- $ echo 'skipped: this test get stuck on the CI with python2 + chg. investigation needed'
- $ exit 80
-#endif
-
-
make git commits repeatable
$ cat >> $HGRCPATH <<EOF
--- a/tests/test-subrepo-svn.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-subrepo-svn.t Fri Mar 25 11:33:12 2022 -0400
@@ -249,7 +249,7 @@
verify subrepo is contained within the repo directory
- $ "$PYTHON" -c "from __future__ import print_function; import os.path; print(os.path.exists('s'))"
+ $ "$PYTHON" -c "import os.path; print(os.path.exists('s'))"
True
update to nullrev (must delete the subrepo)
--- a/tests/test-symlink-os-yes-fs-no.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-symlink-os-yes-fs-no.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import os
import sys
import time
--- a/tests/test-template-functions.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-template-functions.t Fri Mar 25 11:33:12 2022 -0400
@@ -192,7 +192,6 @@
$ cd unstable-hash
$ hg log --template '{date|age}\n' > /dev/null || exit 1
- >>> from __future__ import absolute_import
>>> import datetime
>>> fp = open('a', 'wb')
>>> n = datetime.datetime.now() + datetime.timedelta(366 * 7)
@@ -1572,7 +1571,6 @@
Test cbor filter:
$ cat <<'EOF' > "$TESTTMP/decodecbor.py"
- > from __future__ import absolute_import
> from mercurial import (
> dispatch,
> )
--- a/tests/test-template-map.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-template-map.t Fri Mar 25 11:33:12 2022 -0400
@@ -722,7 +722,6 @@
test CBOR style:
$ cat <<'EOF' > "$TESTTMP/decodecborarray.py"
- > from __future__ import absolute_import
> from mercurial import (
> dispatch,
> )
--- a/tests/test-trusted.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-trusted.py Fri Mar 25 11:33:12 2022 -0400
@@ -2,7 +2,6 @@
# with files from different users/groups, we cheat a bit by
# monkey-patching some functions in the util module
-from __future__ import absolute_import, print_function
import os
import sys
--- a/tests/test-ui-color.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-ui-color.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import os
from mercurial import (
dispatch,
--- a/tests/test-ui-config.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-ui-config.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,4 +1,3 @@
-from __future__ import absolute_import, print_function
from mercurial import (
dispatch,
error,
--- a/tests/test-ui-verbosity.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-ui-verbosity.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import os
from mercurial import (
pycompat,
--- a/tests/test-unified-test.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-unified-test.t Fri Mar 25 11:33:12 2022 -0400
@@ -26,7 +26,6 @@
Doctest commands:
- >>> from __future__ import print_function
>>> print('foo')
foo
$ echo interleaved
--- a/tests/test-update-atomic.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-update-atomic.t Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
Checking that experimental.atomic-file works.
$ cat > $TESTTMP/show_mode.py <<EOF
- > from __future__ import print_function
> import os
> import stat
> import sys
@@ -20,7 +19,6 @@
$ cd repo
$ cat > .hg/showwrites.py <<EOF
- > from __future__ import print_function
> from mercurial import pycompat
> from mercurial.utils import stringutil
> def uisetup(ui):
--- a/tests/test-upgrade-repo.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-upgrade-repo.t Fri Mar 25 11:33:12 2022 -0400
@@ -734,7 +734,6 @@
$ touch FooBarDirectory.d/f1
$ hg -q commit -A -m 'add f1'
$ hg -q up -r 0
- >>> from __future__ import absolute_import, print_function
>>> import random
>>> random.seed(0) # have a reproducible content
>>> with open("f2", "wb") as f:
@@ -958,7 +957,6 @@
Check that the repo still works fine
$ hg log -G --stat
- @ changeset: 2:76d4395f5413 (no-py3 !)
@ changeset: 2:fca376863211 (py3 !)
| tag: tip
| parent: 0:ba592bf28da2
--- a/tests/test-url.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-url.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
# coding=utf-8
-from __future__ import absolute_import, print_function
import doctest
import os
--- a/tests/test-util.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-util.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,7 @@
# unit tests for mercuril.util utilities
-from __future__ import absolute_import
import contextlib
+import io
import itertools
import unittest
@@ -55,7 +55,7 @@
@contextlib.contextmanager
def capturestderr():
- """Replace utils.procutil.stderr with a pycompat.bytesio instance
+ """Replace utils.procutil.stderr with an io.BytesIO instance
The instance is made available as the return value of __enter__.
@@ -63,7 +63,7 @@
"""
orig = utils.procutil.stderr
- utils.procutil.stderr = pycompat.bytesio()
+ utils.procutil.stderr = io.BytesIO()
try:
yield utils.procutil.stderr
finally:
--- a/tests/test-verify-repo-operations.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-verify-repo-operations.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import print_function, absolute_import
-
"""Fuzz testing for operations against a Mercurial repository
This uses Hypothesis's stateful testing to generate random repository
--- a/tests/test-verify.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-verify.t Fri Mar 25 11:33:12 2022 -0400
@@ -338,7 +338,6 @@
checked 1 changesets with 1 changes to 1 files
$ cat >> $TESTTMP/break-base64.py <<EOF
- > from __future__ import absolute_import
> import base64
> base64.b64decode=lambda x: x
> EOF
--- a/tests/test-walk.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-walk.t Fri Mar 25 11:33:12 2022 -0400
@@ -640,7 +640,6 @@
$ cd t
$ echo fennel > overflow.list
$ cat >> printnum.py <<EOF
- > from __future__ import print_function
> for i in range(20000 // 100):
> print('x' * 100)
> EOF
--- a/tests/test-walkrepo.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-walkrepo.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import os
from mercurial import (
--- a/tests/test-wireproto-clientreactor.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-wireproto-clientreactor.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
import sys
import unittest
import zlib
--- a/tests/test-wireproto-framing.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-wireproto-framing.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import unittest
from mercurial import (
--- a/tests/test-wireproto-serverreactor.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-wireproto-serverreactor.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import unittest
from mercurial import (
--- a/tests/test-wireproto.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-wireproto.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import sys
from mercurial import (
@@ -16,7 +14,7 @@
stringio = util.stringio
-class proto(object):
+class proto:
def __init__(self, args):
self.args = args
self.name = 'dummyproto'
@@ -78,7 +76,7 @@
return {b'name': mangle(name)}, unmangle
-class serverrepo(object):
+class serverrepo:
def __init__(self, ui):
self.ui = ui
--- a/tests/test-worker.t Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-worker.t Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,6 @@
Test UI worker interaction
$ cat > t.py <<EOF
- > from __future__ import absolute_import, print_function
> import sys
> import time
> from mercurial import (
@@ -88,9 +87,7 @@
> test 100000.0 abort --traceback 2>&1 | egrep '(WorkerError|Abort)'
raise error.Abort(b'known exception')
mercurial.error.Abort: known exception (py3 !)
- Abort: known exception (no-py3 !)
raise error.WorkerError(status)
- WorkerError: 255 (no-py3 !)
mercurial.error.WorkerError: 255 (py3 !)
Traceback must be printed for unknown exceptions
@@ -102,7 +99,6 @@
Workers should not do cleanups in all cases
$ cat > $TESTTMP/detectcleanup.py <<EOF
- > from __future__ import absolute_import
> import atexit
> import os
> import sys
@@ -136,7 +132,6 @@
Do not crash on partially read result
$ cat > $TESTTMP/detecttruncated.py <<EOF
- > from __future__ import absolute_import
> import os
> import sys
> import time
--- a/tests/test-wsgirequest.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/test-wsgirequest.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import unittest
from mercurial.hgweb import request as requestmod
--- a/tests/testlib/badserverext.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/badserverext.py Fri Mar 25 11:33:12 2022 -0400
@@ -44,7 +44,6 @@
request)
"""
-from __future__ import absolute_import
import re
import socket
@@ -91,7 +90,7 @@
)
-class ConditionTracker(object):
+class ConditionTracker:
def __init__(
self,
close_after_recv_bytes,
@@ -257,7 +256,7 @@
# We can't adjust __class__ on a socket instance. So we define a proxy type.
-class socketproxy(object):
+class socketproxy:
__slots__ = ('_orig', '_logfp', '_cond')
def __init__(self, obj, logfp, condition_tracked):
@@ -301,7 +300,7 @@
# We can't adjust __class__ on socket._fileobject, so define a proxy.
-class fileobjectproxy(object):
+class fileobjectproxy:
__slots__ = ('_orig', '_logfp', '_cond')
def __init__(self, obj, logfp, condition_tracked):
--- a/tests/testlib/crash_transaction_late.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/crash_transaction_late.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial import (
error,
--- a/tests/testlib/ext-phase-report.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/ext-phase-report.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,7 +1,5 @@
# tiny extension to report phase changes during transaction
-from __future__ import absolute_import
-
def reposetup(ui, repo):
def reportphasemove(tr):
--- a/tests/testlib/ext-sidedata-2.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/ext-sidedata-2.py Fri Mar 25 11:33:12 2022 -0400
@@ -8,7 +8,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import hashlib
import struct
--- a/tests/testlib/ext-sidedata-3.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/ext-sidedata-3.py Fri Mar 25 11:33:12 2022 -0400
@@ -9,7 +9,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import hashlib
import struct
--- a/tests/testlib/ext-sidedata-4.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/ext-sidedata-4.py Fri Mar 25 11:33:12 2022 -0400
@@ -9,7 +9,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
from mercurial.revlogutils import sidedata
--- a/tests/testlib/ext-sidedata-5.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/ext-sidedata-5.py Fri Mar 25 11:33:12 2022 -0400
@@ -9,7 +9,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import hashlib
import struct
--- a/tests/testlib/ext-sidedata.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/ext-sidedata.py Fri Mar 25 11:33:12 2022 -0400
@@ -5,7 +5,6 @@
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
-from __future__ import absolute_import
import hashlib
import struct
--- a/tests/testlib/ext-stream-clone-steps.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/ext-stream-clone-steps.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import
-
from mercurial import (
encoding,
extensions,
--- a/tests/testlib/persistent-nodemap-race-ext.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/persistent-nodemap-race-ext.py Fri Mar 25 11:33:12 2022 -0400
@@ -35,7 +35,6 @@
/!\ valid.
"""
-from __future__ import print_function
import os
--- a/tests/testlib/sigpipe-remote.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/sigpipe-remote.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,4 @@
#!/usr/bin/env python3
-from __future__ import print_function
import io
import os
@@ -7,14 +6,6 @@
import sys
import time
-# we cannot use mercurial.testing as long as python2 is not dropped as the test
-# will only install the mercurial module for python2 in python2 run
-if sys.version_info[0] < 3:
- ver = '.'.join(str(x) for x in sys.version_info)
- exe = sys.executable
- print('SIGPIPE-HELPER: script should run with Python 3', file=sys.stderr)
- print('SIGPIPE-HELPER: %s is running %s' % (exe, ver), file=sys.stderr)
- sys.exit(255)
if isinstance(sys.stdout.buffer, io.BufferedWriter):
print('SIGPIPE-HELPER: script need unbuffered output', file=sys.stderr)
--- a/tests/testlib/sigpipe-worker.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/testlib/sigpipe-worker.py Fri Mar 25 11:33:12 2022 -0400
@@ -3,7 +3,6 @@
# This is literally `cat` but in python, one char at a time.
#
# see sigpipe-remote.py for details.
-from __future__ import print_function
import io
import os
--- a/tests/tinyproxy.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/tinyproxy.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,6 +1,5 @@
#!/usr/bin/env python
-from __future__ import absolute_import, print_function
__doc__ = """Tiny HTTP Proxy.
--- a/tests/unwrap-message-id.py Tue Mar 22 03:19:01 2022 +0100
+++ b/tests/unwrap-message-id.py Fri Mar 25 11:33:12 2022 -0400
@@ -1,5 +1,3 @@
-from __future__ import absolute_import, print_function
-
import sys
for line in sys.stdin: