##// END OF EJS Templates
rust: replace most "operation" structs with functions...
rust: replace most "operation" structs with functions The hg-core crate has a partially-formed concept of "operation", represented as structs with constructors and a `run` method. Each struct’s contructor takes different parameters, and each `run` has a different return type. Constructors typically don’t do much more than store parameters for `run` to access them. There was a comment about adding an `Operation` trait when the language supports expressing something so general, but it’s hard to imagine how operations with such different APIs could be used in a generic context. This commit starts removing the concept of "operation", since those are pretty much just functions. Differential Revision: https://phab.mercurial-scm.org/D9595

File last commit:

r46661:f105c49e default
r46751:dca9cb99 default
Show More
setup.py
1828 lines | 59.5 KiB | text/x-python | PythonLexer
mpm@selenic.com
More whitespace cleanups...
r575 #
# This is the mercurial setup script.
mpm@selenic.com
Add back links from file revisions to changeset revisions...
r0 #
Christian Ebert
setup.py not executable: change instructions at beginning of file
r4816 # 'python setup.py install', or
# 'python setup.py --help' for more options
Augie Fackler
setup: fix mistake that prevented Python 3 from being excluded...
r33592 import os
Ian Moody
setup: allow py3 install without env vars...
r43666 # 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
supportedpy = ','.join(
[
Manuel Jacob
setup: raise minimum Python version to 2.7.4...
r45378 '>=2.7.4',
Ian Moody
setup: allow py3 install without env vars...
r43666 '!=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',
]
)
Augie Fackler
setup: explicitly declare supported Python versions...
r33588
Zachary Gramana
setup.py: workaround for missing bz2 module in IronPython...
r14295 import sys, platform
Georges Racinet
rust-cpython: management of shared libray suffix...
r42657 import sysconfig
Augie Fackler
formatting: blacken the codebase...
r43346
Renato Cunha
setup.py: Adjustments to make setup.py run in py3k....
r11532 if sys.version_info[0] >= 3:
Augie Fackler
setup: handle more invalid python3 syntax...
r20696 printf = eval('print')
libdir_escape = 'unicode_escape'
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
setup: convert version strings to unicode on Python 3...
r35246 def sysstr(s):
return s.decode('latin-1')
Augie Fackler
formatting: blacken the codebase...
r43346
Renato Cunha
setup.py: Adjustments to make setup.py run in py3k....
r11532 else:
Augie Fackler
setup: handle more invalid python3 syntax...
r20696 libdir_escape = 'string_escape'
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
setup: handle more invalid python3 syntax...
r20696 def printf(*args, **kwargs):
f = kwargs.get('file', sys.stdout)
end = kwargs.get('end', '\n')
Gregory Szorc
setup.py: use bytes literals...
r27348 f.write(b' '.join(args) + end)
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
setup: convert version strings to unicode on Python 3...
r35246 def sysstr(s):
return s
Renato Cunha
setup.py: Adjustments to make setup.py run in py3k....
r11532
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
setup: add extra logic to try and recommend a new pip on bad Python...
r33589 # 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.
Manuel Jacob
setup: raise minimum Python version to 2.7.4...
r45378 if sys.version_info < (2, 7, 4, 'final'):
Augie Fackler
formatting: blacken the codebase...
r43346 pip_message = (
'This may be due to an out of date pip. '
'Make sure you have pip >= 9.0.1.'
)
Augie Fackler
setup: add extra logic to try and recommend a new pip on bad Python...
r33589 try:
import pip
Augie Fackler
formatting: blacken the codebase...
r43346
Augie Fackler
setup: add extra logic to try and recommend a new pip on bad Python...
r33589 pip_version = tuple([int(x) for x in pip.__version__.split('.')[:3]])
Augie Fackler
formatting: blacken the codebase...
r43346 if pip_version < (9, 0, 1):
Augie Fackler
setup: add extra logic to try and recommend a new pip on bad Python...
r33589 pip_message = (
'Your pip version is out of date, please install '
Augie Fackler
formatting: blacken the codebase...
r43346 'pip >= 9.0.1. pip {} detected.'.format(pip.__version__)
)
Augie Fackler
setup: add extra logic to try and recommend a new pip on bad Python...
r33589 else:
# pip is new enough - it must be something else
pip_message = ''
except Exception:
pass
error = """
Manuel Jacob
setup: raise minimum Python version to 2.7.4...
r45378 Mercurial does not support Python older than 2.7.4.
Augie Fackler
setup: add extra logic to try and recommend a new pip on bad Python...
r33589 Python {py} detected.
{pip}
Augie Fackler
formatting: blacken the codebase...
r43346 """.format(
py=sys.version_info, pip=pip_message
)
Augie Fackler
setup: add extra logic to try and recommend a new pip on bad Python...
r33589 printf(error, file=sys.stderr)
sys.exit(1)
Manuel Jacob
setup: require a Python version with modern SSL features...
r45410 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)
Manuel Jacob
setup: require that Python has TLS 1.1 or TLS 1.2...
r45429 # 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
# were defined only if compiled against a OpenSSL version with TLS 1.1 / 1.2
# support. At the mentioned commit, they were unconditionally defined.
_notset = object()
has_tlsv1_1 = getattr(ssl, 'HAS_TLSv1_1', _notset)
if has_tlsv1_1 is _notset:
has_tlsv1_1 = getattr(ssl, 'PROTOCOL_TLSv1_1', _notset) is not _notset
has_tlsv1_2 = getattr(ssl, 'HAS_TLSv1_2', _notset)
if has_tlsv1_2 is _notset:
has_tlsv1_2 = getattr(ssl, 'PROTOCOL_TLSv1_2', _notset) is not _notset
if not (has_tlsv1_1 or has_tlsv1_2):
error = """
The `ssl` module does not advertise support for TLS 1.1 or TLS 1.2.
Please make sure that your Python installation was compiled against an OpenSSL
version enabling these features (likely this requires the OpenSSL version to
be at least 1.0.1).
"""
printf(error, file=sys.stderr)
sys.exit(1)
Georges Racinet
rust-cpython: management of shared libray suffix...
r42657 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']
Matt Mackall
setup: warn about missing standard Python components
r7558 # Solaris Python packaging brain damage
try:
import hashlib
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
setup: warn about missing standard Python components
r7558 sha = hashlib.sha1()
Brodie Rao
cleanup: replace naked excepts with more specific ones
r16688 except ImportError:
Matt Mackall
setup: warn about missing standard Python components
r7558 try:
import sha
Augie Fackler
formatting: blacken the codebase...
r43346
sha.sha # silence unused import warning
Brodie Rao
cleanup: replace naked excepts with more specific ones
r16688 except ImportError:
Matt Mackall
setup: warn about missing standard Python components
r7558 raise SystemExit(
Augie Fackler
formatting: blacken the codebase...
r43346 "Couldn't import standard hashlib (incomplete Python install)."
)
Matt Mackall
setup: warn about missing standard Python components
r7558
try:
import zlib
Augie Fackler
formatting: blacken the codebase...
r43346
zlib.compressobj # silence unused import warning
Brodie Rao
cleanup: replace naked excepts with more specific ones
r16688 except ImportError:
Matt Mackall
setup: warn about missing standard Python components
r7558 raise SystemExit(
Augie Fackler
formatting: blacken the codebase...
r43346 "Couldn't import standard zlib (incomplete Python install)."
)
Matt Mackall
setup: warn about missing standard Python components
r7558
Zachary Gramana
setup.py: workaround for missing bz2 module in IronPython...
r14295 # The base IronPython distribution (as of 2.7.1) doesn't support bz2
isironpython = False
Dirkjan Ochtman
setup: fail if bz2 is not available
r10761 try:
Augie Fackler
formatting: blacken the codebase...
r43346 isironpython = (
platform.python_implementation().lower().find("ironpython") != -1
)
Brodie Rao
cleanup: replace naked excepts with more specific ones
r16688 except AttributeError:
Zachary Gramana
setup.py: workaround for missing bz2 module in IronPython...
r14295 pass
if isironpython:
Simon Heimberg
setup: make script executable with python3...
r15492 sys.stderr.write("warning: IronPython detected (no bz2 support)\n")
Zachary Gramana
setup.py: workaround for missing bz2 module in IronPython...
r14295 else:
try:
import bz2
Augie Fackler
formatting: blacken the codebase...
r43346
bz2.BZ2Compressor # silence unused import warning
Brodie Rao
cleanup: replace naked excepts with more specific ones
r16688 except ImportError:
Zachary Gramana
setup.py: workaround for missing bz2 module in IronPython...
r14295 raise SystemExit(
Augie Fackler
formatting: blacken the codebase...
r43346 "Couldn't import standard bz2 (incomplete Python install)."
)
Dirkjan Ochtman
setup: fail if bz2 is not available
r10761
Joan Massich
setup.py: do not install c extensions on pypy...
r24192 ispypy = "PyPy" in sys.version
Gregory Szorc
setup: detect Python DLL filename from loaded DLL...
r29020 import ctypes
Georges Racinet
rust: better treatment of cargo/rustc errors...
r41002 import errno
Augie Fackler
setup: fix mistake that prevented Python 3 from being excluded...
r33592 import stat, subprocess, time
Kent Frazier
setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
r21038 import re
Alexis S. L. Carvalho
setup.py: use a simplified custom version of CCompiler.has_function...
r6251 import shutil
import tempfile
Christian Boos
setup: ignore failures to build optional inotify extension
r11468 from distutils import log
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
setup: use setuptools on Windows (issue5400)...
r31289 # We have issues with setuptools on some platforms and builders. Until
# those are resolved, setuptools is opt-in except for platforms where
# we don't have issues.
Augie Fackler
formatting: blacken the codebase...
r43346 issetuptools = os.name == 'nt' or 'FORCE_SETUPTOOLS' in os.environ
Yuya Nishihara
setup: silence warning of unknown option python_requires on distutils...
r33601 if issetuptools:
Nathan Goldbaum
setup: import setup from setuptools if FORCE_SETUPTOOLS is set...
r26600 from setuptools import setup
else:
from distutils.core import setup
Jun Wu
setup: test setproctitle before building osutil...
r30408 from distutils.ccompiler import new_compiler
Nathan Goldbaum
setup: import setup from setuptools if FORCE_SETUPTOOLS is set...
r26600 from distutils.core import Command, Extension
Martin Geisler
add --pure flag to setup.py...
r7722 from distutils.dist import Distribution
Martin Geisler
i18n: new build_mo command for setup.py...
r7649 from distutils.command.build import build
Christian Boos
setup: ignore failures to build optional inotify extension
r11468 from distutils.command.build_ext import build_ext
Martin Geisler
add --pure flag to setup.py...
r7722 from distutils.command.build_py import build_py
Gregory Szorc
setup.py: attempt to build and install hg.exe on Windows...
r27268 from distutils.command.build_scripts import build_scripts
Matt Harbison
setup: prevent setuptools from laying an egg...
r32647 from distutils.command.install import install
Kyle Lippincott
setup: set mode 644 or 755 on installed files
r22640 from distutils.command.install_lib import install_lib
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661 from distutils.command.install_scripts import install_scripts
Martin Geisler
i18n: new build_mo command for setup.py...
r7649 from distutils.spawn import spawn, find_executable
Ludovic Chabant
setup: don't fail when Python doesn't have the cygwinccompiler package...
r23677 from distutils import file_util
Gregory Szorc
setup.py: attempt to build and install hg.exe on Windows...
r27268 from distutils.errors import (
CCompilerError,
DistutilsError,
DistutilsExecError,
)
Kent Frazier
setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
r21038 from distutils.sysconfig import get_python_inc, get_config_var
Dirkjan Ochtman
setup.py: use StrictVersion instead of manual comparison
r13594 from distutils.version import StrictVersion
mpm@selenic.com
Install the templates where they can be found by hgweb.py...
r157
"Paul Morelle "
setup: explain to distutils how we write rc versions...
r40485 # Explain to distutils.StrictVersion how our release candidates are versionned
StrictVersion.version_re = re.compile(r'^(\d+)\.(\d+)(\.(\d+))?-?(rc(\d+))?$')
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
setup: only write some autogenerated files if they change...
r35229 def write_if_changed(path, content):
"""Write content to a file iff the content hasn't changed."""
if os.path.exists(path):
with open(path, 'rb') as fh:
current = fh.read()
else:
current = b''
if current != content:
with open(path, 'wb') as fh:
fh.write(content)
Augie Fackler
formatting: blacken the codebase...
r43346
Paul Moore
Add a batch file driver for Windows
r6513 scripts = ['hg']
if os.name == 'nt':
Gregory Szorc
setup.py: attempt to build and install hg.exe on Windows...
r27268 # We remove hg.bat if we are able to build hg.exe.
Paul Moore
Add a batch file driver for Windows
r6513 scripts.append('contrib/win32/hg.bat')
Matt Mackall
Fix setup.py warning
r3893
Augie Fackler
formatting: blacken the codebase...
r43346
Jun Wu
setup: split "hasfunction" to test arbitrary code...
r31559 def cancompile(cc, code):
Alexis S. L. Carvalho
setup.py: use a simplified custom version of CCompiler.has_function...
r6251 tmpdir = tempfile.mkdtemp(prefix='hg-install-')
Alexis S. L. Carvalho
setup.py: hide compiler error messages while searching for inotify
r6373 devnull = oldstderr = None
Alexis S. L. Carvalho
setup.py: use a simplified custom version of CCompiler.has_function...
r6251 try:
Jun Wu
setup: split "hasfunction" to test arbitrary code...
r31559 fname = os.path.join(tmpdir, 'testcomp.c')
Matt Mackall
setup: use try/except/finally...
r25089 f = open(fname, 'w')
Jun Wu
setup: split "hasfunction" to test arbitrary code...
r31559 f.write(code)
Matt Mackall
setup: use try/except/finally...
r25089 f.close()
# Redirect stderr to /dev/null to hide any error messages
# from the compiler.
# This will have to be changed if we ever have to check
# for a function on Windows.
devnull = open('/dev/null', 'w')
oldstderr = os.dup(sys.stderr.fileno())
os.dup2(devnull.fileno(), sys.stderr.fileno())
objects = cc.compile([fname], output_dir=tmpdir)
cc.link_executable(objects, os.path.join(tmpdir, "a.out"))
Alexis S. L. Carvalho
setup.py: use a simplified custom version of CCompiler.has_function...
r6251 return True
Matt Mackall
setup: use try/except/finally...
r25089 except Exception:
return False
Alexis S. L. Carvalho
setup.py: use a simplified custom version of CCompiler.has_function...
r6251 finally:
Alexis S. L. Carvalho
setup.py: hide compiler error messages while searching for inotify
r6373 if oldstderr is not None:
os.dup2(oldstderr, sys.stderr.fileno())
if devnull is not None:
devnull.close()
Alexis S. L. Carvalho
setup.py: use a simplified custom version of CCompiler.has_function...
r6251 shutil.rmtree(tmpdir)
Augie Fackler
formatting: blacken the codebase...
r43346
Jun Wu
setup: split "hasfunction" to test arbitrary code...
r31559 # simplified version of distutils.ccompiler.CCompiler.has_function
# that actually removes its temporary files.
def hasfunction(cc, funcname):
code = 'int main(void) { %s(); }\n' % funcname
return cancompile(cc, code)
Augie Fackler
formatting: blacken the codebase...
r43346
Jun Wu
setup: add a function to test header files
r31560 def hasheader(cc, headername):
code = '#include <%s>\nint main(void) { return 0; }\n' % headername
return cancompile(cc, code)
Augie Fackler
formatting: blacken the codebase...
r43346
Volker.Kleinfeld@gmx.de
Support for the distutils extention 'py2exe' added....
r1283 # py2exe needs to be installed to work
try:
Bryan O'Sullivan
Clean up whitespace damage.
r1294 import py2exe
Augie Fackler
formatting: blacken the codebase...
r43346
py2exe.Distribution # silence unused import warning
Adrian Buehlmann
setup.py: fixing version info for Windows hg.exe (py2exe)...
r10400 py2exeloaded = True
Pascal Quantin
setup: fix py2exe generation broken by c3a6ec304055 (issue3116)...
r15527 # import py2exe's patched Distribution class
from distutils.core import Distribution
Bryan O'Sullivan
Fix Volker's modifications to setup.py for non-Windows systems.
r1284 except ImportError:
Adrian Buehlmann
setup.py: fixing version info for Windows hg.exe (py2exe)...
r10400 py2exeloaded = False
Volker.Kleinfeld@gmx.de
Support for the distutils extention 'py2exe' added....
r1283
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
setup: define build_doc command...
r42016 def runcmd(cmd, env, cwd=None):
Augie Fackler
formatting: blacken the codebase...
r43346 p = subprocess.Popen(
cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, cwd=cwd
)
Matt Harbison
plan9: drop py26 hacks
r32886 out, err = p.communicate()
Adam Simpkins
setup: update runcmd() to also return the exit status...
r33111 return p.returncode, out, err
Jon M. Dugan
setup: fix mac build broken by e42d18538e1d...
r13636
Augie Fackler
formatting: blacken the codebase...
r43346
Adam Simpkins
setup: replace runhg() with an hgcommand helper class...
r33113 class hgcommand(object):
Adam Simpkins
setup: prefer using the system hg to interact with the local repository...
r33114 def __init__(self, cmd, env):
self.cmd = cmd
self.env = env
Gilles Moris
setup: refactor the version string to a subset of tag+tagdist-hash+date...
r9615
Adam Simpkins
setup: replace runhg() with an hgcommand helper class...
r33113 def run(self, args):
cmd = self.cmd + args
returncode, out, err = runcmd(cmd, self.env)
Yuya Nishihara
setup: do not select hg executable that prints unexpected warnings...
r33599 err = filterhgerr(err)
Adam Simpkins
setup: replace runhg() with an hgcommand helper class...
r33113 if err or returncode != 0:
printf("stderr from '%s':" % (' '.join(cmd)), file=sys.stderr)
Yuya Nishihara
setup: do not select hg executable that prints unexpected warnings...
r33599 printf(err, file=sys.stderr)
Martin von Zweigbergk
py3: make setup.py's hgcommand() consistently return bytes...
r45094 return b''
Adam Simpkins
setup: replace runhg() with an hgcommand helper class...
r33113 return out
Jeremy Whitlock
setup: read .hg_archival.txt for version info (issue1670)...
r8548
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
setup: do not select hg executable that prints unexpected warnings...
r33599 def filterhgerr(err):
# If root is executing setup.py, but the repository is owned by
# another user (as in "sudo python setup.py install") we will get
# trust warnings since the .hg/hgrc file is untrusted. That is
# fine, we don't want to load it anyway. Python may warn about
# a missing __init__.py in mercurial/locale, we also ignore that.
Augie Fackler
formatting: blacken the codebase...
r43346 err = [
e
for e in err.splitlines()
if (
not e.startswith(b'not trusting file')
and not e.startswith(b'warning: Not importing')
and not e.startswith(b'obsolete feature not enabled')
and not e.startswith(b'*** failed to import extension')
and not e.startswith(b'devel-warn:')
and not (
e.startswith(b'(third party extension')
and e.endswith(b'or newer of Mercurial; disabling)')
)
)
]
Yuya Nishihara
setup: do not select hg executable that prints unexpected warnings...
r33599 return b'\n'.join(b' ' + e for e in err)
Augie Fackler
formatting: blacken the codebase...
r43346
Adam Simpkins
setup: prefer using the system hg to interact with the local repository...
r33114 def findhg():
"""Try to figure out how we should invoke hg for examining the local
repository contents.
Returns an hgcommand object."""
# By default, prefer the "hg" command in the user's path. This was
# presumably the hg command that the user used to create this repository.
#
# This repository may require extensions or other settings that would not
# be enabled by running the hg script directly from this local repository.
hgenv = os.environ.copy()
# Use HGPLAIN to disable hgrc settings that would change output formatting,
# and disable localization for the same reasons.
hgenv['HGPLAIN'] = '1'
hgenv['LANGUAGE'] = 'C'
hgcmd = ['hg']
# Run a simple "hg log" command just to see if using hg from the user's
Matt Harbison
setup: avoid attempting to invoke the system-wide hg.exe on Windows...
r41016 # path works and can successfully interact with this repository. Windows
# gives precedence to hg.exe in the current directory, so fall back to the
# python invocation of local hg, where pythonXY.dll can always be found.
Adam Simpkins
setup: prefer using the system hg to interact with the local repository...
r33114 check_cmd = ['log', '-r.', '-Ttest']
Matt Harbison
setup: don't skip the search for global hg.exe if there is no local instance...
r44684 if os.name != 'nt' or not os.path.exists("hg.exe"):
Matt Harbison
setup: avoid attempting to invoke the system-wide hg.exe on Windows...
r41016 try:
retcode, out, err = runcmd(hgcmd + check_cmd, hgenv)
except EnvironmentError:
retcode = -1
if retcode == 0 and not filterhgerr(err):
return hgcommand(hgcmd, hgenv)
Adam Simpkins
setup: prefer using the system hg to interact with the local repository...
r33114
# Fall back to trying the local hg installation.
hgenv = localhgenv()
hgcmd = [sys.executable, 'hg']
try:
retcode, out, err = runcmd(hgcmd + check_cmd, hgenv)
except EnvironmentError:
retcode = -1
Yuya Nishihara
setup: do not select hg executable that prints unexpected warnings...
r33599 if retcode == 0 and not filterhgerr(err):
Adam Simpkins
setup: prefer using the system hg to interact with the local repository...
r33114 return hgcommand(hgcmd, hgenv)
Augie Fackler
formatting: blacken the codebase...
r43346 raise SystemExit(
'Unable to find a working hg binary to extract the '
'version from the repository tags'
)
Adam Simpkins
setup: prefer using the system hg to interact with the local repository...
r33114
def localhgenv():
"""Get an environment dictionary to use for invoking or importing
mercurial from the local repository."""
Adam Simpkins
setup: move environment computation into a helper function...
r33112 # Execute hg out of this directory with a custom environment which takes
# care to not use any hgrc files and do no localization.
Augie Fackler
formatting: blacken the codebase...
r43346 env = {
'HGMODULEPOLICY': 'py',
'HGRCPATH': '',
'LANGUAGE': 'C',
'PATH': '',
} # make pypi modules that use os.environ['PATH'] happy
Adam Simpkins
setup: move environment computation into a helper function...
r33112 if 'LD_LIBRARY_PATH' in os.environ:
env['LD_LIBRARY_PATH'] = os.environ['LD_LIBRARY_PATH']
if 'SystemRoot' in os.environ:
# SystemRoot is required by Windows to load various DLLs. See:
# https://bugs.python.org/issue13524#msg148850
env['SystemRoot'] = os.environ['SystemRoot']
Jun Wu
setup: fix localhgenv...
r33117 return env
Adam Simpkins
setup: move environment computation into a helper function...
r33112
Augie Fackler
formatting: blacken the codebase...
r43346
Adam Simpkins
setup: move environment computation into a helper function...
r33112 version = ''
Matt Mackall
setup: set env global earlier (3073)
r15367
Christian Ebert
setup.py: subprocess instead of os.popen, sys.stderr.write instead of print...
r8547 if os.path.isdir('.hg'):
Adam Simpkins
setup: prefer using the system hg to interact with the local repository...
r33114 hg = findhg()
Adam Simpkins
setup: replace runhg() with an hgcommand helper class...
r33113 cmd = ['log', '-r', '.', '--template', '{tags}\n']
Yuya Nishihara
setup: convert version strings to unicode on Python 3...
r35246 numerictags = [t for t in sysstr(hg.run(cmd)).split() if t[0:1].isdigit()]
hgid = sysstr(hg.run(['id', '-i'])).strip()
Adam Simpkins
setup: fail if we cannot determine the version number...
r33110 if not hgid:
# Bail out if hg is having problems interacting with this repository,
# rather than falling through and producing a bogus version number.
# Continuing with an invalid version number will break extensions
# that define minimumhgversion.
raise SystemExit('Unable to determine hg version from local repository')
Augie Fackler
formatting: blacken the codebase...
r43346 if numerictags: # tag(s) found
Bryan O'Sullivan
setup: calculate version more correctly...
r17709 version = numerictags[-1]
Augie Fackler
formatting: blacken the codebase...
r43346 if hgid.endswith('+'): # propagate the dirty status to the tag
Gilles Moris
setup: refactor the version string to a subset of tag+tagdist-hash+date...
r9615 version += '+'
Augie Fackler
formatting: blacken the codebase...
r43346 else: # no tag found
Adam Simpkins
setup: replace runhg() with an hgcommand helper class...
r33113 ltagcmd = ['parents', '--template', '{latesttag}']
Yuya Nishihara
setup: convert version strings to unicode on Python 3...
r35246 ltag = sysstr(hg.run(ltagcmd))
Adam Simpkins
setup: replace runhg() with an hgcommand helper class...
r33113 changessincecmd = ['log', '-T', 'x\n', '-r', "only(.,'%s')" % ltag]
changessince = len(hg.run(changessincecmd).splitlines())
Siddharth Agarwal
setup: use changes since latest tag instead of just distance...
r23647 version = '%s+%s-%s' % (ltag, changessince, hgid)
Gilles Moris
setup: refactor the version string to a subset of tag+tagdist-hash+date...
r9615 if version.endswith('+'):
version += time.strftime('%Y%m%d')
elif os.path.exists('.hg_archival.txt'):
Augie Fackler
formatting: blacken the codebase...
r43346 kw = dict(
[[t.strip() for t in l.split(':', 1)] for l in open('.hg_archival.txt')]
)
Gilles Moris
setup: refactor the version string to a subset of tag+tagdist-hash+date...
r9615 if 'tag' in kw:
timeless
cleanup: remove superfluous space after space after equals (python)
r27637 version = kw['tag']
Gilles Moris
setup: refactor the version string to a subset of tag+tagdist-hash+date...
r9615 elif 'latesttag' in kw:
Siddharth Agarwal
setup: use changessincelatesttag from archive if present...
r23646 if 'changessincelatesttag' in kw:
version = '%(latesttag)s+%(changessincelatesttag)s-%(node).12s' % kw
else:
version = '%(latesttag)s+%(latesttagdistance)s-%(node).12s' % kw
Christian Ebert
setup.py: subprocess instead of os.popen, sys.stderr.write instead of print...
r8547 else:
Gilles Moris
setup: refactor the version string to a subset of tag+tagdist-hash+date...
r9615 version = kw.get('node', '')[:12]
Matt Mackall
refactor version code...
r7632
Jeremy Whitlock
setup: read .hg_archival.txt for version info (issue1670)...
r8548 if version:
Gregory Szorc
setup: only write some autogenerated files if they change...
r35229 versionb = version
if not isinstance(versionb, bytes):
versionb = versionb.encode('ascii')
Augie Fackler
formatting: blacken the codebase...
r43346 write_if_changed(
'mercurial/__version__.py',
b''.join(
[
b'# this file is autogenerated by setup.py\n'
b'version = b"%s"\n' % versionb,
]
),
)
Jeremy Whitlock
Fix how setup.py identifies the Mercurial version....
r8493
try:
timeless
setup: show how to set the module policy for imports...
r28431 oldpolicy = os.environ.get('HGMODULEPOLICY', None)
os.environ['HGMODULEPOLICY'] = 'py'
Jeremy Whitlock
Fix how setup.py identifies the Mercurial version....
r8493 from mercurial import __version__
Augie Fackler
formatting: blacken the codebase...
r43346
Jeremy Whitlock
Fix how setup.py identifies the Mercurial version....
r8493 version = __version__.version
except ImportError:
Mike Hommey
setup: allow to run setup.py with python 3 without a mercurial checkout...
r38744 version = b'unknown'
timeless
setup: show how to set the module policy for imports...
r28431 finally:
if oldpolicy is None:
del os.environ['HGMODULEPOLICY']
else:
os.environ['HGMODULEPOLICY'] = oldpolicy
Matt Mackall
refactor version code...
r7632
Augie Fackler
formatting: blacken the codebase...
r43346
Simon Heimberg
setup: subclass build command
r15460 class hgbuild(build):
# Insert hgbuildmo first so that files in mercurial/locale/ are found
# when build_py is run next.
Gregory Szorc
setup: remove support for 2to3...
r28398 sub_commands = [('build_mo', None)] + build.sub_commands
Simon Heimberg
setup: subclass build command
r15460
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
setup: backout 8504699d1aa6...
r15523 class hgbuildmo(build):
Martin Geisler
i18n: new build_mo command for setup.py...
r7649
description = "build translations (.mo files)"
def run(self):
if not find_executable('msgfmt'):
Augie Fackler
formatting: blacken the codebase...
r43346 self.warn(
"could not find msgfmt executable, no translations "
"will be built"
)
Martin Geisler
i18n: new build_mo command for setup.py...
r7649 return
podir = 'i18n'
if not os.path.isdir(podir):
self.warn("could not find %s/ directory" % podir)
return
join = os.path.join
for po in os.listdir(podir):
if not po.endswith('.po'):
continue
pofile = join(podir, po)
modir = join('locale', po[:-3], 'LC_MESSAGES')
mofile = join(modir, 'hg.mo')
Dan Villiom Podlaski Christiansen
setup: install translation files as package data...
r9999 mobuildfile = join('mercurial', mofile)
cmd = ['msgfmt', '-v', '-o', mobuildfile, pofile]
Martin Geisler
setup: do not use -c with msgfmt on Solaris (issue1489)
r7720 if sys.platform != 'sunos5':
# msgfmt on Solaris does not know about -c
cmd.append('-c')
Dan Villiom Podlaski Christiansen
setup: install translation files as package data...
r9999 self.mkpath(join('mercurial', modir))
self.make_file([pofile], mobuildfile, spawn, (cmd,))
Martin Geisler
i18n: new build_mo command for setup.py...
r7649
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661
Simon Heimberg
setup: subclass distribution instead of overwriting original
r15458 class hgdist(Distribution):
Maciej Fijalkowski
setup: prepare for future cffi modules by adding placeholder in setup
r29505 pure = False
setup-rust: add a --no-rust flag...
r44971 rust = False
no_rust = False
Maciej Fijalkowski
setup: prepare for future cffi modules by adding placeholder in setup
r29505 cffi = ispypy
Simon Heimberg
setup: subclass distribution instead of overwriting original
r15458
Augie Fackler
cleanup: use () to wrap long lines instead of \...
r41925 global_options = Distribution.global_options + [
('pure', None, "use pure (slow) Python code instead of C extensions"),
Georges Racinet
rust: new rust options in setup.py...
r42653 ('rust', None, "use Rust extensions additionally to C extensions"),
setup-rust: add a --no-rust flag...
r44971 (
'no-rust',
None,
"do not use Rust extensions additionally to C extensions",
),
Augie Fackler
cleanup: use () to wrap long lines instead of \...
r41925 ]
Martin Geisler
add --pure flag to setup.py...
r7722
setup-rust: add a --no-rust flag...
r44971 negative_opt = Distribution.negative_opt.copy()
boolean_options = ['pure', 'rust', 'no-rust']
negative_opt['no-rust'] = 'rust'
def _set_command_options(self, command_obj, option_dict=None):
Augie Fackler
setup: work around old versions of distutils breaking setup.py...
r45120 # Not all distutils versions in the wild have boolean_options.
# This should be cleaned up when we're Python 3 only.
command_obj.boolean_options = (
getattr(command_obj, 'boolean_options', []) + self.boolean_options
)
setup-rust: add a --no-rust flag...
r44971 return Distribution._set_command_options(
self, command_obj, option_dict=option_dict
)
def parse_command_line(self):
ret = Distribution.parse_command_line(self)
if not (self.rust or self.no_rust):
hgrustext = os.environ.get('HGWITHRUSTEXT')
# TODO record it for proper rebuild upon changes
# (see mercurial/__modulepolicy__.py)
if hgrustext != 'cpython' and hgrustext is not None:
if hgrustext:
msg = 'unkown HGWITHRUSTEXT value: %s' % hgrustext
printf(msg, file=sys.stderr)
hgrustext = None
self.rust = hgrustext is not None
self.no_rust = not self.rust
return ret
Simon Heimberg
setup: has_ext_modules always returns false when pure is specified...
r15459 def has_ext_modules(self):
# self.ext_modules is emptied in hgbuildpy.finalize_options which is
# too late for some cases
return not self.pure and Distribution.has_ext_modules(self)
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450 # This is ugly as a one-liner. So use a variable.
buildextnegops = dict(getattr(build_ext, 'negative_options', {}))
buildextnegops['no-zstd'] = 'zstd'
Georges Racinet
rust: new rust options in setup.py...
r42653 buildextnegops['no-rust'] = 'rust'
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450
Augie Fackler
formatting: blacken the codebase...
r43346
Christian Boos
setup: ignore failures to build optional inotify extension
r11468 class hgbuildext(build_ext):
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450 user_options = build_ext.user_options + [
('zstd', None, 'compile zstd bindings [default]'),
('no-zstd', None, 'do not compile zstd bindings'),
Augie Fackler
formatting: blacken the codebase...
r43346 (
'rust',
None,
'compile Rust extensions if they are in use '
'(requires Cargo) [default]',
),
Georges Racinet
rust: new rust options in setup.py...
r42653 ('no-rust', None, 'do not compile Rust extensions'),
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450 ]
Georges Racinet
rust: new rust options in setup.py...
r42653 boolean_options = build_ext.boolean_options + ['zstd', 'rust']
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450 negative_opt = buildextnegops
def initialize_options(self):
self.zstd = True
Georges Racinet
rust: new rust options in setup.py...
r42653 self.rust = True
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450 return build_ext.initialize_options(self)
Gregory Szorc
setup: build extensions in parallel by default...
r43314 def finalize_options(self):
# Unless overridden by the end user, build extensions in parallel.
# Only influences behavior on Python 3.5+.
if getattr(self, 'parallel', None) is None:
self.parallel = True
return build_ext.finalize_options(self)
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450 def build_extensions(self):
Augie Fackler
formatting: blacken the codebase...
r43346 ruststandalones = [
e for e in self.extensions if isinstance(e, RustStandaloneExtension)
]
self.extensions = [
e for e in self.extensions if e not in ruststandalones
]
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450 # Filter out zstd if disabled via argument.
if not self.zstd:
Augie Fackler
formatting: blacken the codebase...
r43346 self.extensions = [
e for e in self.extensions if e.name != 'mercurial.zstd'
]
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450
Georges Racinet
rust: new rust options in setup.py...
r42653 # Build Rust standalon extensions if it'll be used
# and its build is not explictely disabled (for external build
# as Linux distributions would do)
setup-rust: remove the legacy 'direct-ffi' variant...
r44956 if self.distribution.rust and self.rust:
Georges Racinet
rust: new rust options in setup.py...
r42653 for rustext in ruststandalones:
rustext.build('' if self.inplace else self.build_lib)
Georges Racinet
rust-cpython: build via HGWITHRUSTEXT=cpython...
r41003
Gregory Szorc
setup: add flag to build_ext to control building zstd...
r30450 return build_ext.build_extensions(self)
Christian Boos
setup: ignore failures to build optional inotify extension
r11468
def build_extension(self, ext):
Augie Fackler
formatting: blacken the codebase...
r43346 if (
self.distribution.rust
and self.rust
and isinstance(ext, RustExtension)
):
ext.rustbuild()
Christian Boos
setup: ignore failures to build optional inotify extension
r11468 try:
build_ext.build_extension(self, ext)
except CCompilerError:
Martin Geisler
setup: slight simplification
r12501 if not getattr(ext, 'optional', False):
Christian Boos
setup: ignore failures to build optional inotify extension
r11468 raise
Augie Fackler
formatting: blacken the codebase...
r43346 log.warn(
"Failed to build optional extension '%s' (skipping)", ext.name
)
Christian Boos
setup: ignore failures to build optional inotify extension
r11468
Gregory Szorc
setup.py: attempt to build and install hg.exe on Windows...
r27268 class hgbuildscripts(build_scripts):
def run(self):
FUJIWARA Katsunori
setup: avoid procedure related to hg.exe at setup.py --pure...
r28041 if os.name != 'nt' or self.distribution.pure:
Gregory Szorc
setup.py: attempt to build and install hg.exe on Windows...
r27268 return build_scripts.run(self)
exebuilt = False
try:
self.run_command('build_hgexe')
exebuilt = True
except (DistutilsError, CCompilerError):
log.warn('failed to build optional hg.exe')
if exebuilt:
# Copying hg.exe to the scripts build directory ensures it is
# installed by the install_scripts command.
hgexecommand = self.get_finalized_command('build_hgexe')
dest = os.path.join(self.build_dir, 'hg.exe')
self.mkpath(self.build_dir)
self.copy_file(hgexecommand.hgexepath, dest)
# Remove hg.bat because it is redundant with hg.exe.
self.scripts.remove('contrib/win32/hg.bat')
return build_scripts.run(self)
Augie Fackler
formatting: blacken the codebase...
r43346
Martin Geisler
setup: cleanup coding style
r10000 class hgbuildpy(build_py):
Martin Geisler
add --pure flag to setup.py...
r7722 def finalize_options(self):
build_py.finalize_options(self)
if self.distribution.pure:
self.distribution.ext_modules = []
Maciej Fijalkowski
setup: prepare for future cffi modules by adding placeholder in setup
r29505 elif self.distribution.cffi:
Jun Wu
setup: move cffi stuff to mercurial/cffi...
r30346 from mercurial.cffi import (
Yuya Nishihara
cffi: rename build scripts...
r32505 bdiffbuild,
mpatchbuild,
Jun Wu
setup: move cffi stuff to mercurial/cffi...
r30346 )
Augie Fackler
formatting: blacken the codebase...
r43346
exts = [
mpatchbuild.ffi.distutils_extension(),
bdiffbuild.ffi.distutils_extension(),
]
Maciej Fijalkowski
setup: prepare for future cffi modules by adding placeholder in setup
r29505 # cffi modules go here
Maciej Fijalkowski
osutil: add darwin-only version of os.listdir using cffi
r29600 if sys.platform == 'darwin':
Yuya Nishihara
cffi: rename build scripts...
r32505 from mercurial.cffi import osutilbuild
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
cffi: rename build scripts...
r32505 exts.append(osutilbuild.ffi.distutils_extension())
Maciej Fijalkowski
setup: prepare for future cffi modules by adding placeholder in setup
r29505 self.distribution.ext_modules = exts
Nicolas Dumazet
setup: user-friendly error message if Python headers are missing
r12649 else:
Mads Kiilerich
setup: make error message for missing Python headers more helpful
r18905 h = os.path.join(get_python_inc(), 'Python.h')
if not os.path.exists(h):
Augie Fackler
formatting: blacken the codebase...
r43346 raise SystemExit(
'Python headers are required to build '
'Mercurial but weren\'t found in %s' % h
)
Martin Geisler
add --pure flag to setup.py...
r7722
timeless
setup: create a module for the modulepolicy...
r28430 def run(self):
Yuya Nishihara
setup: do not overwrite local __modulepolicy__.py on out-of-source build...
r32653 basepath = os.path.join(self.build_lib, 'mercurial')
self.mkpath(basepath)
Georges Racinet
rust: new rust options in setup.py...
r42653 rust = self.distribution.rust
timeless
setup: create a module for the modulepolicy...
r28430 if self.distribution.pure:
modulepolicy = 'py'
Yuya Nishihara
policy: relax the default for in-place build...
r32251 elif self.build_lib == '.':
Georges Racinet
rust: new rust options in setup.py...
r42653 # in-place build should run without rebuilding and Rust extensions
modulepolicy = 'rust+c-allow' if rust else 'allow'
timeless
setup: create a module for the modulepolicy...
r28430 else:
Georges Racinet
rust: new rust options in setup.py...
r42653 modulepolicy = 'rust+c' if rust else 'c'
Gregory Szorc
setup: only write some autogenerated files if they change...
r35229
Augie Fackler
formatting: blacken the codebase...
r43346 content = b''.join(
[
b'# this file is autogenerated by setup.py\n',
b'modulepolicy = b"%s"\n' % modulepolicy.encode('ascii'),
]
)
write_if_changed(os.path.join(basepath, '__modulepolicy__.py'), content)
Gregory Szorc
setup: refactor handling of modules with C/Python implementations...
r27222
timeless
setup: create a module for the modulepolicy...
r28430 build_py.run(self)
Martin Geisler
add --pure flag to setup.py...
r7722
Augie Fackler
formatting: blacken the codebase...
r43346
Yuya Nishihara
setup: add command to generate index of extensions...
r14538 class buildhgextindex(Command):
description = 'generate prebuilt index of hgext (for frozen package)'
user_options = []
_indexfilename = 'hgext/__index__.py'
def initialize_options(self):
pass
def finalize_options(self):
pass
def run(self):
if os.path.exists(self._indexfilename):
timeless
setup: switch to with open as...
r28418 with open(self._indexfilename, 'w') as f:
f.write('# empty\n')
Yuya Nishihara
setup: add command to generate index of extensions...
r14538
# here no extension enabled, disabled() lists up everything
Augie Fackler
formatting: blacken the codebase...
r43346 code = (
'import pprint; from mercurial import extensions; '
Matt Harbison
setup: exclude the __index__ module from itself when generating...
r44862 'ext = extensions.disabled();'
'ext.pop("__index__", None);'
'pprint.pprint(ext)'
Augie Fackler
formatting: blacken the codebase...
r43346 )
returncode, out, err = runcmd(
[sys.executable, '-c', code], localhgenv()
)
Adam Simpkins
setup: update runcmd() to also return the exit status...
r33111 if err or returncode != 0:
Yuya Nishihara
setup: add command to generate index of extensions...
r14538 raise DistutilsExecError(err)
Matt Harbison
py3: write out hgextindex as bytes in setup.py...
r42244 with open(self._indexfilename, 'wb') as f:
f.write(b'# this file is autogenerated by setup.py\n')
f.write(b'docs = ')
timeless
setup: switch to with open as...
r28418 f.write(out)
Yuya Nishihara
setup: add command to generate index of extensions...
r14538
Augie Fackler
formatting: blacken the codebase...
r43346
Adrian Buehlmann
setup: compile hg.exe...
r17061 class buildhgexe(build_ext):
description = 'compile hg.exe from mercurial/exewrapper.c'
Kostia Balytskyi
windows: add an experimental option for long paths support...
r34531 user_options = build_ext.user_options + [
Augie Fackler
formatting: blacken the codebase...
r43346 (
'long-paths-support',
None,
'enable support for long paths on '
'Windows (off by default and '
'experimental)',
),
Kostia Balytskyi
windows: add an experimental option for long paths support...
r34531 ]
LONG_PATHS_MANIFEST = """
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<application>
<windowsSettings
xmlns:ws2="http://schemas.microsoft.com/SMI/2016/WindowsSettings">
<ws2:longPathAware>true</ws2:longPathAware>
</windowsSettings>
</application>
</assembly>"""
def initialize_options(self):
build_ext.initialize_options(self)
self.long_paths_support = False
Adrian Buehlmann
setup: compile hg.exe...
r17061
def build_extensions(self):
if os.name != 'nt':
return
Adrian Buehlmann
setup: fix build_hgexe for mingw32 compiler...
r17246 if isinstance(self.compiler, HackedMingw32CCompiler):
Augie Fackler
formatting: blacken the codebase...
r43346 self.compiler.compiler_so = self.compiler.compiler # no -mdll
self.compiler.dll_libraries = [] # no -lmsrvc90
Gregory Szorc
setup: detect Python DLL filename from loaded DLL...
r29020
Matt Harbison
setup: conditionalize access to `sys.dllhandle` when building extensions...
r44073 pythonlib = None
Gregory Szorc
setup: detect Python DLL filename from loaded DLL...
r29020
Matt Harbison
setup: copy pythonXY.dll next to the hg.exe wrapper when building...
r46545 dir = os.path.dirname(self.get_ext_fullpath('dummy'))
self.hgtarget = os.path.join(dir, 'hg')
Matt Harbison
setup: conditionalize access to `sys.dllhandle` when building extensions...
r44073 if getattr(sys, 'dllhandle', None):
# Different Python installs can have different Python library
# names. e.g. the official CPython distribution uses pythonXY.dll
# and MinGW uses libpythonX.Y.dll.
_kernel32 = ctypes.windll.kernel32
_kernel32.GetModuleFileNameA.argtypes = [
ctypes.c_void_p,
ctypes.c_void_p,
ctypes.c_ulong,
]
_kernel32.GetModuleFileNameA.restype = ctypes.c_ulong
size = 1000
buf = ctypes.create_string_buffer(size + 1)
filelen = _kernel32.GetModuleFileNameA(
sys.dllhandle, ctypes.byref(buf), size
)
if filelen > 0 and filelen != size:
dllbasename = os.path.basename(buf.value)
if not dllbasename.lower().endswith(b'.dll'):
raise SystemExit(
'Python DLL does not end with .dll: %s' % dllbasename
)
pythonlib = dllbasename[:-4]
Matt Harbison
setup: copy pythonXY.dll next to the hg.exe wrapper when building...
r46545 # 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(
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 os.path.dirname(self.hgtarget),
fsdecode(dllbasename),
Matt Harbison
setup: copy pythonXY.dll next to the hg.exe wrapper when building...
r46545 )
if not os.path.exists(dest):
shutil.copy(buf.value, dest)
Matt Harbison
setup: conditionalize access to `sys.dllhandle` when building extensions...
r44073 if not pythonlib:
Augie Fackler
formatting: blacken the codebase...
r43346 log.warn(
Matt Harbison
setup: combine two contiguous string literals...
r44071 'could not determine Python DLL filename; assuming pythonXY'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
setup: detect Python DLL filename from loaded DLL...
r29020
hv = sys.hexversion
Matt Harbison
setup: use bytes for assumed python version...
r44072 pythonlib = b'python%d%d' % (hv >> 24, (hv >> 16) & 0xFF)
Gregory Szorc
setup: detect Python DLL filename from loaded DLL...
r29020
log.info('using %s as Python library name' % pythonlib)
timeless
setup: switch to with open as...
r28418 with open('mercurial/hgpythonlib.h', 'wb') as f:
Matt Harbison
py3: add b'' to some setup.py strings for Windows...
r39644 f.write(b'/* this file is autogenerated by setup.py */\n')
f.write(b'#define HGPYTHONLIB "%s"\n' % pythonlib)
Matt Harbison
setup: build exewrapper with Unicode support on py3...
r40433
macros = None
if sys.version_info[0] >= 3:
macros = [('_UNICODE', None), ('UNICODE', None)]
Augie Fackler
formatting: blacken the codebase...
r43346 objects = self.compiler.compile(
['mercurial/exewrapper.c'],
output_dir=self.build_temp,
macros=macros,
)
self.compiler.link_executable(
objects, self.hgtarget, libraries=[], output_dir=self.build_temp
)
Kostia Balytskyi
windows: add an experimental option for long paths support...
r34531 if self.long_paths_support:
self.addlongpathsmanifest()
def addlongpathsmanifest(self):
Gregory Szorc
global: make some docstrings raw strings...
r41674 r"""Add manifest pieces so that hg.exe understands long paths
Kostia Balytskyi
windows: add an experimental option for long paths support...
r34531
This is an EXPERIMENTAL feature, use with care.
To enable long paths support, one needs to do two things:
- build Mercurial with --long-paths-support option
- change HKLM\SYSTEM\CurrentControlSet\Control\FileSystem\
LongPathsEnabled to have value 1.
Please ignore 'warning 81010002: Unrecognized Element "longPathAware"';
it happens because Mercurial uses mt.exe circa 2008, which is not
yet aware of long paths support in the manifest (I think so at least).
This does not stop mt.exe from embedding/merging the XML properly.
Why resource #1 should be used for .exe manifests? I don't know and
wasn't able to find an explanation for mortals. But it seems to work.
"""
exefname = self.compiler.executable_filename(self.hgtarget)
fdauto, manfname = tempfile.mkstemp(suffix='.hg.exe.manifest')
os.close(fdauto)
with open(manfname, 'w') as f:
f.write(self.LONG_PATHS_MANIFEST)
log.info("long paths manifest is written to '%s'" % manfname)
inputresource = '-inputresource:%s;#1' % exefname
outputresource = '-outputresource:%s;#1' % exefname
log.info("running mt.exe to update hg.exe's manifest in-place")
# supplying both -manifest and -inputresource to mt.exe makes
# it merge the embedded and supplied manifests in the -outputresource
Augie Fackler
formatting: blacken the codebase...
r43346 self.spawn(
[
'mt.exe',
'-nologo',
'-manifest',
manfname,
inputresource,
outputresource,
]
)
Kostia Balytskyi
windows: add an experimental option for long paths support...
r34531 log.info("done updating hg.exe's manifest")
os.remove(manfname)
Adrian Buehlmann
setup: compile hg.exe...
r17061
Gregory Szorc
setup.py: attempt to build and install hg.exe on Windows...
r27268 @property
def hgexepath(self):
dir = os.path.dirname(self.get_ext_fullpath('dummy'))
return os.path.join(self.build_temp, dir, 'hg.exe')
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
setup: define build_doc command...
r42016 class hgbuilddoc(Command):
description = 'build documentation'
user_options = [
('man', None, 'generate man pages'),
('html', None, 'generate html pages'),
]
def initialize_options(self):
self.man = None
self.html = None
def finalize_options(self):
# If --man or --html are set, only generate what we're told to.
# Otherwise generate everything.
have_subset = self.man is not None or self.html is not None
if have_subset:
self.man = True if self.man else False
self.html = True if self.html else False
else:
self.man = True
self.html = True
def run(self):
def normalizecrlf(p):
with open(p, 'rb') as fh:
orig = fh.read()
if b'\r\n' not in orig:
return
log.info('normalizing %s to LF line endings' % p)
with open(p, 'wb') as fh:
fh.write(orig.replace(b'\r\n', b'\n'))
def gentxt(root):
txt = 'doc/%s.txt' % root
log.info('generating %s' % txt)
res, out, err = runcmd(
Augie Fackler
formatting: blacken the codebase...
r43346 [sys.executable, 'gendoc.py', root], os.environ, cwd='doc'
)
Gregory Szorc
setup: define build_doc command...
r42016 if res:
Augie Fackler
formatting: blacken the codebase...
r43346 raise SystemExit(
Gregory Szorc
setup: use sysstr() on process output...
r45244 'error running gendoc.py: %s'
% '\n'.join([sysstr(out), sysstr(err)])
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
setup: define build_doc command...
r42016
with open(txt, 'wb') as fh:
fh.write(out)
def gengendoc(root):
gendoc = 'doc/%s.gendoc.txt' % root
log.info('generating %s' % gendoc)
res, out, err = runcmd(
[sys.executable, 'gendoc.py', '%s.gendoc' % root],
os.environ,
Augie Fackler
formatting: blacken the codebase...
r43346 cwd='doc',
)
Gregory Szorc
setup: define build_doc command...
r42016 if res:
Augie Fackler
formatting: blacken the codebase...
r43346 raise SystemExit(
Gregory Szorc
setup: use sysstr() on process output...
r45244 'error running gendoc: %s'
% '\n'.join([sysstr(out), sysstr(err)])
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
setup: define build_doc command...
r42016
with open(gendoc, 'wb') as fh:
fh.write(out)
def genman(root):
log.info('generating doc/%s' % root)
res, out, err = runcmd(
Augie Fackler
formatting: blacken the codebase...
r43346 [
sys.executable,
'runrst',
'hgmanpage',
'--halt',
'warning',
'--strip-elements-with-class',
'htmlonly',
'%s.txt' % root,
root,
],
Gregory Szorc
setup: define build_doc command...
r42016 os.environ,
Augie Fackler
formatting: blacken the codebase...
r43346 cwd='doc',
)
Gregory Szorc
setup: define build_doc command...
r42016 if res:
Augie Fackler
formatting: blacken the codebase...
r43346 raise SystemExit(
Gregory Szorc
setup: use sysstr() on process output...
r45244 'error running runrst: %s'
% '\n'.join([sysstr(out), sysstr(err)])
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
setup: define build_doc command...
r42016
normalizecrlf('doc/%s' % root)
def genhtml(root):
log.info('generating doc/%s.html' % root)
res, out, err = runcmd(
Augie Fackler
formatting: blacken the codebase...
r43346 [
sys.executable,
'runrst',
'html',
'--halt',
'warning',
'--link-stylesheet',
'--stylesheet-path',
'style.css',
'%s.txt' % root,
'%s.html' % root,
],
Gregory Szorc
setup: define build_doc command...
r42016 os.environ,
Augie Fackler
formatting: blacken the codebase...
r43346 cwd='doc',
)
Gregory Szorc
setup: define build_doc command...
r42016 if res:
Augie Fackler
formatting: blacken the codebase...
r43346 raise SystemExit(
Gregory Szorc
setup: use sysstr() on process output...
r45244 'error running runrst: %s'
% '\n'.join([sysstr(out), sysstr(err)])
Augie Fackler
formatting: blacken the codebase...
r43346 )
Gregory Szorc
setup: define build_doc command...
r42016
normalizecrlf('doc/%s.html' % root)
# This logic is duplicated in doc/Makefile.
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 sources = {
Augie Fackler
formatting: blacken the codebase...
r43346 f
Augie Fackler
windows: further build fixes for the WiX installer...
r44188 for f in os.listdir('mercurial/helptext')
Augie Fackler
formatting: blacken the codebase...
r43346 if re.search(r'[0-9]\.txt$', f)
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 }
Gregory Szorc
setup: define build_doc command...
r42016
# common.txt is a one-off.
gentxt('common')
for source in sorted(sources):
assert source[-4:] == '.txt'
root = source[:-4]
gentxt(root)
gengendoc(root)
if self.man:
genman(root)
if self.html:
genhtml(root)
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
setup: prevent setuptools from laying an egg...
r32647 class hginstall(install):
Augie Fackler
setup: introduce dummy copies of setuptools flags...
r32725
user_options = install.user_options + [
Augie Fackler
formatting: blacken the codebase...
r43346 (
'old-and-unmanageable',
None,
'noop, present for eggless setuptools compat',
),
(
'single-version-externally-managed',
None,
'noop, present for eggless setuptools compat',
),
Augie Fackler
setup: introduce dummy copies of setuptools flags...
r32725 ]
# Also helps setuptools not be sad while we refuse to create eggs.
single_version_externally_managed = True
Matt Harbison
setup: prevent setuptools from laying an egg...
r32647 def get_sub_commands(self):
# Screen out egg related commands to prevent egg generation. But allow
# mercurial.egg-info generation, since that is part of modern
# packaging.
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 excl = {'bdist_egg'}
Matt Harbison
setup: prevent setuptools from laying an egg...
r32647 return filter(lambda x: x not in excl, install.get_sub_commands(self))
Augie Fackler
formatting: blacken the codebase...
r43346
Kyle Lippincott
setup: set mode 644 or 755 on installed files
r22640 class hginstalllib(install_lib):
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Kyle Lippincott
setup: set mode 644 or 755 on installed files
r22640 This is a specialization of install_lib that replaces the copy_file used
there so that it supports setting the mode of files after copying them,
instead of just preserving the mode that the files originally had. If your
system has a umask of something like 027, preserving the permissions when
copying will lead to a broken install.
Note that just passing keep_permissions=False to copy_file would be
insufficient, as it might still be applying a umask.
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Kyle Lippincott
setup: set mode 644 or 755 on installed files
r22640
def run(self):
realcopyfile = file_util.copy_file
Augie Fackler
formatting: blacken the codebase...
r43346
Kyle Lippincott
setup: set mode 644 or 755 on installed files
r22640 def copyfileandsetmode(*args, **kwargs):
src, dst = args[0], args[1]
dst, copied = realcopyfile(*args, **kwargs)
if copied:
st = os.stat(src)
# Persist executable bit (apply it to group and other if user
# has it)
if st[stat.ST_MODE] & stat.S_IXUSR:
Augie Fackler
setup: hide octal literals inside strings so they're portable (issue4554)
r24941 setmode = int('0755', 8)
Kyle Lippincott
setup: set mode 644 or 755 on installed files
r22640 else:
Augie Fackler
setup: hide octal literals inside strings so they're portable (issue4554)
r24941 setmode = int('0644', 8)
m = stat.S_IMODE(st[stat.ST_MODE])
m = (m & ~int('0777', 8)) | setmode
os.chmod(dst, m)
Augie Fackler
formatting: blacken the codebase...
r43346
Kyle Lippincott
setup: set mode 644 or 755 on installed files
r22640 file_util.copy_file = copyfileandsetmode
try:
install_lib.run(self)
finally:
file_util.copy_file = realcopyfile
Augie Fackler
formatting: blacken the codebase...
r43346
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661 class hginstallscripts(install_scripts):
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661 This is a specialization of install_scripts that replaces the @LIBDIR@ with
the configured directory for modules. If possible, the path is made relative
to the directory for scripts.
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661
def initialize_options(self):
install_scripts.initialize_options(self)
self.install_lib = None
def finalize_options(self):
install_scripts.finalize_options(self)
Augie Fackler
formatting: blacken the codebase...
r43346 self.set_undefined_options('install', ('install_lib', 'install_lib'))
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661
def run(self):
install_scripts.run(self)
Gregory Szorc
setup.py: don't rewrite @LIBDIR@ when creating wheels...
r27269 # It only makes sense to replace @LIBDIR@ with the install path if
# the install path is known. For wheels, the logic below calculates
# the libdir to be "../..". This is because the internal layout of a
# wheel archive looks like:
#
# mercurial-3.6.1.data/scripts/hg
# mercurial/__init__.py
#
# When installing wheels, the subdirectories of the "<pkg>.data"
# directory are translated to system local paths and files therein
# are copied in place. The mercurial/* files are installed into the
# site-packages directory. However, the site-packages directory
# isn't known until wheel install time. This means we have no clue
# at wheel generation time what the installed site-packages directory
# will be. And, wheels don't appear to provide the ability to register
# custom code to run during wheel installation. This all means that
# we can't reliably set the libdir in wheels: the default behavior
# of looking in sys.path must do.
Augie Fackler
formatting: blacken the codebase...
r43346 if (
os.path.splitdrive(self.install_dir)[0]
!= os.path.splitdrive(self.install_lib)[0]
):
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661 # can't make relative paths from one drive to another, so use an
# absolute path instead
libdir = self.install_lib
else:
Martin von Zweigbergk
packaging: leverage os.path.relpath() in setup.py...
r44539 libdir = os.path.relpath(self.install_lib, self.install_dir)
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661
for outfile in self.outfiles:
timeless
setup: switch to with open as...
r28418 with open(outfile, 'rb') as fp:
data = fp.read()
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661
# skip binary files
Gregory Szorc
setup.py: use bytes literals...
r27348 if b'\0' in data:
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661 continue
Gregory Szorc
setup.py: don't rewrite @LIBDIR@ when creating wheels...
r27269 # During local installs, the shebang will be rewritten to the final
# install path. During wheel packaging, the shebang has a special
# value.
if data.startswith(b'#!python'):
Augie Fackler
formatting: blacken the codebase...
r43346 log.info(
'not rewriting @LIBDIR@ in %s because install path '
'not known' % outfile
)
Gregory Szorc
setup.py: don't rewrite @LIBDIR@ when creating wheels...
r27269 continue
Gregory Szorc
setup.py: use bytes literals...
r27348 data = data.replace(b'@LIBDIR@', libdir.encode(libdir_escape))
timeless
setup: switch to with open as...
r28418 with open(outfile, 'wb') as fp:
fp.write(data)
Dan Villiom Podlaski Christiansen
setup/hg: always load Mercurial from where it was installed....
r12661
Augie Fackler
formatting: blacken the codebase...
r43346
Gregory Szorc
setup: properly package distutils in py2exe virtualenv builds...
r42360 # virtualenv installs custom distutils/__init__.py and
# distutils/distutils.cfg files which essentially proxy back to the
# "real" distutils in the main Python install. The presence of this
# directory causes py2exe to pick up the "hacked" distutils package
# from the virtualenv and "import distutils" will fail from the py2exe
# build because the "real" distutils files can't be located.
#
# We work around this by monkeypatching the py2exe code finding Python
# modules to replace the found virtualenv distutils modules with the
# original versions via filesystem scanning. This is a bit hacky. But
# it allows us to use virtualenvs for py2exe packaging, which is more
# deterministic and reproducible.
#
# It's worth noting that the common StackOverflow suggestions for this
# problem involve copying the original distutils files into the
# virtualenv or into the staging directory after setup() is invoked.
# The former is very brittle and can easily break setup(). Our hacking
# of the found modules routine has a similar result as copying the files
# manually. But it makes fewer assumptions about how py2exe works and
# is less brittle.
# This only catches virtualenvs made with virtualenv (as opposed to
# venv, which is likely what Python 3 uses).
py2exehacked = py2exeloaded and getattr(sys, 'real_prefix', None) is not None
if py2exehacked:
from distutils.command.py2exe import py2exe as buildpy2exe
from py2exe.mf import Module as py2exemodule
class hgbuildpy2exe(buildpy2exe):
def find_needed_modules(self, mf, files, modules):
res = buildpy2exe.find_needed_modules(self, mf, files, modules)
# Replace virtualenv's distutils modules with the real ones.
Gregory Szorc
setup: remove set and dict comprehensions...
r42365 modules = {}
for k, v in res.modules.items():
if k != 'distutils' and not k.startswith('distutils.'):
modules[k] = v
res.modules = modules
Gregory Szorc
setup: properly package distutils in py2exe virtualenv builds...
r42360
import opcode
Augie Fackler
formatting: blacken the codebase...
r43346
distutilsreal = os.path.join(
os.path.dirname(opcode.__file__), 'distutils'
)
Gregory Szorc
setup: properly package distutils in py2exe virtualenv builds...
r42360
for root, dirs, files in os.walk(distutilsreal):
for f in sorted(files):
if not f.endswith('.py'):
continue
full = os.path.join(root, f)
parents = ['distutils']
if root != distutilsreal:
rel = os.path.relpath(root, distutilsreal)
parents.extend(p for p in rel.split(os.sep))
modname = '%s.%s' % ('.'.join(parents), f[:-3])
if modname.startswith('distutils.tests.'):
continue
if modname.endswith('.__init__'):
Augie Fackler
formatting: blacken the codebase...
r43346 modname = modname[: -len('.__init__')]
Gregory Szorc
setup: properly package distutils in py2exe virtualenv builds...
r42360 path = os.path.dirname(full)
else:
path = None
Augie Fackler
formatting: blacken the codebase...
r43346 res.modules[modname] = py2exemodule(
modname, full, path=path
)
Gregory Szorc
setup: properly package distutils in py2exe virtualenv builds...
r42360
if 'distutils' not in res.modules:
raise SystemExit('could not find distutils modules')
return res
Augie Fackler
formatting: blacken the codebase...
r43346
cmdclass = {
'build': hgbuild,
'build_doc': hgbuilddoc,
'build_mo': hgbuildmo,
'build_ext': hgbuildext,
'build_py': hgbuildpy,
'build_scripts': hgbuildscripts,
'build_hgextindex': buildhgextindex,
'install': hginstall,
'install_lib': hginstalllib,
'install_scripts': hginstallscripts,
'build_hgexe': buildhgexe,
}
Thomas Arendsen Hein
Applied coding style to setup.py
r3238
Gregory Szorc
setup: properly package distutils in py2exe virtualenv builds...
r42360 if py2exehacked:
cmdclass['py2exe'] = hgbuildpy2exe
Augie Fackler
formatting: blacken the codebase...
r43346 packages = [
'mercurial',
'mercurial.cext',
'mercurial.cffi',
Matt Harbison
setup: include `defaultrc` in the package list...
r44478 'mercurial.defaultrc',
Matt Harbison
help: create packages for the help text...
r44031 'mercurial.helptext',
'mercurial.helptext.internals',
Augie Fackler
formatting: blacken the codebase...
r43346 'mercurial.hgweb',
'mercurial.interfaces',
'mercurial.pure',
Martin von Zweigbergk
packaging: mark mercurial.templates and subdirs as packages...
r45864 'mercurial.templates',
Augie Fackler
formatting: blacken the codebase...
r43346 'mercurial.thirdparty',
'mercurial.thirdparty.attr',
'mercurial.thirdparty.zope',
'mercurial.thirdparty.zope.interface',
upgrade: split actual upgrade code away from the main module...
r46661 'mercurial.upgrade_utils',
Augie Fackler
formatting: blacken the codebase...
r43346 'mercurial.utils',
'mercurial.revlogutils',
'mercurial.testing',
'hgext',
'hgext.convert',
'hgext.fsmonitor',
'hgext.fastannotate',
'hgext.fsmonitor.pywatchman',
Augie Fackler
git: skeleton of a new extension to _directly_ operate on git repos...
r44961 'hgext.git',
Augie Fackler
formatting: blacken the codebase...
r43346 'hgext.highlight',
Joerg Sonnenberger
hgext: start building a library for simple hooks...
r44897 'hgext.hooklib',
Augie Fackler
formatting: blacken the codebase...
r43346 'hgext.infinitepush',
'hgext.largefiles',
'hgext.lfs',
'hgext.narrow',
'hgext.remotefilelog',
'hgext.zeroconf',
'hgext3rd',
'hgdemandimport',
]
Martin von Zweigbergk
packaging: mark mercurial.templates and subdirs as packages...
r45864
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)
Yuya Nishihara
setup: exclude vendored futures package on Python 3...
r39649 if sys.version_info[0] == 2:
Augie Fackler
formatting: blacken the codebase...
r43346 packages.extend(
[
'mercurial.thirdparty.concurrent',
'mercurial.thirdparty.concurrent.futures',
]
)
Benoit Boissinot
Do not use osutil.c with python 2.4 and Windows (issue1364)...
r10521
Augie Fackler
py2exe: add workaround to allow bundling of hgext3rd.* extensions...
r42221 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
# image here. This is gross, but you gotta do what you gotta do.
packages.extend(os.environ['HG_PY2EXE_EXTRA_INSTALL_PACKAGES'].split(' '))
Augie Fackler
formatting: blacken the codebase...
r43346 common_depends = [
'mercurial/bitmanipulation.h',
'mercurial/compat.h',
'mercurial/cext/util.h',
]
Yuya Nishihara
policy: add "cext" package which will host CPython extension modules...
r32206 common_include_dirs = ['mercurial']
Wei, Elson
setup: check if mercurial/util.h has been modified...
r19724
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 common_cflags = []
Augie Fackler
setup: relax -Werror for declaration-after-statement on Python 3.9...
r45096 # MSVC 2008 still needs declarations at the top of the scope, but Python 3.9
# makes declarations not at the top of a scope in the headers.
if os.name != 'nt' and sys.version_info[1] < 9:
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 common_cflags = ['-Werror=declaration-after-statement']
Jun Wu
setup: test setproctitle before building osutil...
r30408 osutil_cflags = []
Adrian Buehlmann
setup: move osutil_ldflags logic to before extmodules definition
r25073 osutil_ldflags = []
Jun Wu
setup: detect statfs...
r31561 # platform specific macros
Jun Wu
statfs: change Linux feature detection...
r31622 for plat, func in [('bsd', 'setproctitle')]:
Jun Wu
setup: detect statfs...
r31561 if re.search(plat, sys.platform) and hasfunction(new_compiler(), func):
Jun Wu
setup: test setproctitle before building osutil...
r30408 osutil_cflags.append('-DHAVE_%s' % func.upper())
Jun Wu
setup: use a more strict way to test BSD or OSX's statfs...
r31596 for plat, macro, code in [
Augie Fackler
formatting: blacken the codebase...
r43346 (
'bsd|darwin',
'BSD_STATFS',
'''
Jun Wu
setup: use a more strict way to test BSD or OSX's statfs...
r31596 #include <sys/param.h>
#include <sys/mount.h>
int main() { struct statfs s; return sizeof(s.f_fstypename); }
Augie Fackler
formatting: blacken the codebase...
r43346 ''',
),
(
'linux',
'LINUX_STATFS',
'''
Jun Wu
statfs: change Linux feature detection...
r31622 #include <linux/magic.h>
#include <sys/vfs.h>
int main() { struct statfs s; return sizeof(s.f_type); }
Augie Fackler
formatting: blacken the codebase...
r43346 ''',
),
Jun Wu
setup: use a more strict way to test BSD or OSX's statfs...
r31596 ]:
if re.search(plat, sys.platform) and cancompile(new_compiler(), code):
osutil_cflags.append('-DHAVE_%s' % macro)
Adrian Buehlmann
setup: move osutil_ldflags logic to before extmodules definition
r25073 if sys.platform == 'darwin':
osutil_ldflags += ['-framework', 'ApplicationServices']
Alexander Pyhalov
setup: link osutil.so to libsocket on Solaris/illumos (issue6299)
r45199 if sys.platform == 'sunos5':
osutil_ldflags += ['-lsocket']
Jun Wu
bdiff: add a xdiffblocks method...
r36693 xdiff_srcs = [
'mercurial/thirdparty/xdiff/xdiffi.c',
'mercurial/thirdparty/xdiff/xprepare.c',
'mercurial/thirdparty/xdiff/xutils.c',
]
xdiff_headers = [
'mercurial/thirdparty/xdiff/xdiff.h',
'mercurial/thirdparty/xdiff/xdiffi.h',
'mercurial/thirdparty/xdiff/xinclude.h',
'mercurial/thirdparty/xdiff/xmacros.h',
'mercurial/thirdparty/xdiff/xprepare.h',
'mercurial/thirdparty/xdiff/xtypes.h',
'mercurial/thirdparty/xdiff/xutils.h',
]
Augie Fackler
formatting: blacken the codebase...
r43346
Georges Racinet
rust: better treatment of cargo/rustc errors...
r41002 class RustCompilationError(CCompilerError):
"""Exception class for Rust compilation errors."""
Augie Fackler
formatting: blacken the codebase...
r43346
Georges Racinet
rust: exposing in parsers module...
r40309 class RustExtension(Extension):
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 """Base classes for concrete Rust Extension classes."""
Georges Racinet
rust: exposing in parsers module...
r40309
rusttargetdir = os.path.join('rust', 'target', 'release')
Augie Fackler
formatting: blacken the codebase...
r43346 def __init__(
self, mpath, sources, rustlibname, subcrate, py3_features=None, **kw
):
Georges Racinet
rust: exposing in parsers module...
r40309 Extension.__init__(self, mpath, sources, **kw)
srcdir = self.rustsrcdir = os.path.join('rust', subcrate)
Georges Racinet
rust-cpython: build and support for Python3...
r41021 self.py3_features = py3_features
Georges Racinet
rust: exposing in parsers module...
r40309
# adding Rust source and control files to depends so that the extension
# gets rebuilt if they've changed
self.depends.append(os.path.join(srcdir, 'Cargo.toml'))
cargo_lock = os.path.join(srcdir, 'Cargo.lock')
if os.path.exists(cargo_lock):
self.depends.append(cargo_lock)
for dirpath, subdir, fnames in os.walk(os.path.join(srcdir, 'src')):
Augie Fackler
formatting: blacken the codebase...
r43346 self.depends.extend(
os.path.join(dirpath, fname)
for fname in fnames
if os.path.splitext(fname)[1] == '.rs'
)
Georges Racinet
rust: exposing in parsers module...
r40309
Georges Racinet
rust-cpython: management of shared libray suffix...
r42657 @staticmethod
def rustdylibsuffix():
"""Return the suffix for shared libraries produced by rustc.
See also: https://doc.rust-lang.org/reference/linkage.html
"""
if sys.platform == 'darwin':
return '.dylib'
elif os.name == 'nt':
return '.dll'
else:
return '.so'
Georges Racinet
rust: exposing in parsers module...
r40309 def rustbuild(self):
env = os.environ.copy()
if 'HGTEST_RESTOREENV' in env:
# Mercurial tests change HOME to a temporary directory,
# but, if installed with rustup, the Rust toolchain needs
# HOME to be correct (otherwise the 'no default toolchain'
# error message is issued and the build fails).
# This happens currently with test-hghave.t, which does
# invoke this build.
# Unix only fix (os.path.expanduser not really reliable if
# HOME is shadowed like this)
import pwd
Augie Fackler
formatting: blacken the codebase...
r43346
Georges Racinet
rust: exposing in parsers module...
r40309 env['HOME'] = pwd.getpwuid(os.getuid()).pw_dir
Valentin Gatien-Baron
setup: stop asking cargo to spam...
r45365 cargocmd = ['cargo', 'rustc', '--release']
Raphaël Gomès
rust-re2: add wrapper for calling Re2 from Rust...
r44786
feature_flags = []
Georges Racinet
rust-cpython: build and support for Python3...
r41021 if sys.version_info[0] == 3 and self.py3_features is not None:
Raphaël Gomès
rust-re2: add wrapper for calling Re2 from Rust...
r44786 feature_flags.append(self.py3_features)
cargocmd.append('--no-default-features')
rust_features = env.get("HG_RUST_FEATURES")
if rust_features:
feature_flags.append(rust_features)
cargocmd.extend(('--features', " ".join(feature_flags)))
Georges Racinet
rust: switched to 'cargo rustc' in setup.py...
r42659 cargocmd.append('--')
Georges Racinet
rust-cpython: fix build for MacOSX...
r42658 if sys.platform == 'darwin':
Augie Fackler
formatting: blacken the codebase...
r43346 cargocmd.extend(
("-C", "link-arg=-undefined", "-C", "link-arg=dynamic_lookup")
)
Georges Racinet
rust: better treatment of cargo/rustc errors...
r41002 try:
subprocess.check_call(cargocmd, env=env, cwd=self.rustsrcdir)
except OSError as exc:
if exc.errno == errno.ENOENT:
raise RustCompilationError("Cargo not found")
elif exc.errno == errno.EACCES:
raise RustCompilationError(
Augie Fackler
formatting: blacken the codebase...
r43346 "Cargo found, but permisssion to execute it is denied"
)
Georges Racinet
rust: better treatment of cargo/rustc errors...
r41002 else:
raise
except subprocess.CalledProcessError:
raise RustCompilationError(
"Cargo failed. Working directory: %r, "
Philippe Pepiot
setup: fix a possible NameError on rust build...
r42243 "command: %r, environment: %r"
Augie Fackler
formatting: blacken the codebase...
r43346 % (self.rustsrcdir, cargocmd, env)
)
Georges Racinet
rust: exposing in parsers module...
r40309
Georges Racinet
rust-cpython: build via HGWITHRUSTEXT=cpython...
r41003 class RustStandaloneExtension(RustExtension):
def __init__(self, pydottedname, rustcrate, dylibname, **kw):
Augie Fackler
formatting: blacken the codebase...
r43346 RustExtension.__init__(
self, pydottedname, [], dylibname, rustcrate, **kw
)
Georges Racinet
rust-cpython: build via HGWITHRUSTEXT=cpython...
r41003 self.dylibname = dylibname
def build(self, target_dir):
self.rustbuild()
target = [target_dir]
target.extend(self.name.split('.'))
Georges Racinet
rust-cpython: management of shared libray suffix...
r42657 target[-1] += DYLIB_SUFFIX
Augie Fackler
formatting: blacken the codebase...
r43346 shutil.copy2(
os.path.join(
self.rusttargetdir, self.dylibname + self.rustdylibsuffix()
),
os.path.join(*target),
)
Georges Racinet
rust-cpython: build via HGWITHRUSTEXT=cpython...
r41003
Martin Geisler
setup: cleanup coding style
r10000 extmodules = [
Augie Fackler
formatting: blacken the codebase...
r43346 Extension(
'mercurial.cext.base85',
['mercurial/cext/base85.c'],
include_dirs=common_include_dirs,
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 extra_compile_args=common_cflags,
Augie Fackler
formatting: blacken the codebase...
r43346 depends=common_depends,
),
Extension(
'mercurial.cext.bdiff',
['mercurial/bdiff.c', 'mercurial/cext/bdiff.c'] + xdiff_srcs,
include_dirs=common_include_dirs,
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 extra_compile_args=common_cflags,
Augie Fackler
formatting: blacken the codebase...
r43346 depends=common_depends + ['mercurial/bdiff.h'] + xdiff_headers,
),
Extension(
'mercurial.cext.mpatch',
['mercurial/mpatch.c', 'mercurial/cext/mpatch.c'],
include_dirs=common_include_dirs,
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 extra_compile_args=common_cflags,
Augie Fackler
formatting: blacken the codebase...
r43346 depends=common_depends,
),
setup-rust: remove the legacy 'direct-ffi' variant...
r44956 Extension(
Augie Fackler
formatting: blacken the codebase...
r43346 'mercurial.cext.parsers',
[
'mercurial/cext/charencode.c',
'mercurial/cext/dirs.c',
'mercurial/cext/manifest.c',
'mercurial/cext/parsers.c',
'mercurial/cext/pathencode.c',
'mercurial/cext/revlog.c',
],
Georges Racinet
rust-cpython: build via HGWITHRUSTEXT=cpython...
r41003 include_dirs=common_include_dirs,
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 extra_compile_args=common_cflags,
Augie Fackler
formatting: blacken the codebase...
r43346 depends=common_depends
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 + [
'mercurial/cext/charencode.h',
'mercurial/cext/revlog.h',
],
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Gregory Szorc
setup: register zope.interface packages and compile C extension...
r37197 Extension(
Augie Fackler
formatting: blacken the codebase...
r43346 'mercurial.cext.osutil',
['mercurial/cext/osutil.c'],
include_dirs=common_include_dirs,
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 extra_compile_args=common_cflags + osutil_cflags,
Augie Fackler
formatting: blacken the codebase...
r43346 extra_link_args=osutil_ldflags,
depends=common_depends,
),
Extension(
'mercurial.thirdparty.zope.interface._zope_interface_coptimizations',
[
'mercurial/thirdparty/zope/interface/_zope_interface_coptimizations.c',
],
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 extra_compile_args=common_cflags,
Augie Fackler
formatting: blacken the codebase...
r43346 ),
Extension(
Augie Fackler
sha1dc: initial implementation of Python extension...
r44510 'mercurial.thirdparty.sha1dc',
[
'mercurial/thirdparty/sha1dc/cext.c',
'mercurial/thirdparty/sha1dc/lib/sha1.c',
'mercurial/thirdparty/sha1dc/lib/ubc_check.c',
],
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 extra_compile_args=common_cflags,
Augie Fackler
sha1dc: initial implementation of Python extension...
r44510 ),
Extension(
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 'hgext.fsmonitor.pywatchman.bser',
['hgext/fsmonitor/pywatchman/bser.c'],
extra_compile_args=common_cflags,
Augie Fackler
formatting: blacken the codebase...
r43346 ),
RustStandaloneExtension(
'mercurial.rustext', 'hg-cpython', 'librusthg', py3_features='python3'
),
]
Bryan O'Sullivan
Add osutil module, containing a listdir function....
r5396
Georges Racinet
rust-cpython: build via HGWITHRUSTEXT=cpython...
r41003
Gregory Szorc
setup: compile zstd C extension...
r30436 sys.path.insert(0, 'contrib/python-zstandard')
import setup_zstd
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 zstd = setup_zstd.get_c_extension(
name='mercurial.zstd', root=os.path.abspath(os.path.dirname(__file__))
Augie Fackler
formatting: blacken the codebase...
r43346 )
Matt Harbison
setup: build C extensions with -Werror=declaration-after-statement...
r45079 zstd.extra_compile_args += common_cflags
extmodules.append(zstd)
Gregory Szorc
setup: compile zstd C extension...
r30436
Ludovic Chabant
setup: don't fail when Python doesn't have the cygwinccompiler package...
r23677 try:
from distutils import cygwinccompiler
# the -mno-cygwin option has been deprecated for years
Mike Hommey
setup: fix installing in a mingw environment...
r33780 mingw32compilerclass = cygwinccompiler.Mingw32CCompiler
Bryan O'Sullivan
setup: disable -mno-cygwin if building under mingw32...
r17121
Ludovic Chabant
setup: don't fail when Python doesn't have the cygwinccompiler package...
r23677 class HackedMingw32CCompiler(cygwinccompiler.Mingw32CCompiler):
def __init__(self, *args, **kwargs):
Mike Hommey
setup: fix installing in a mingw environment...
r33780 mingw32compilerclass.__init__(self, *args, **kwargs)
Ludovic Chabant
setup: don't fail when Python doesn't have the cygwinccompiler package...
r23677 for i in 'compiler compiler_so linker_exe linker_so'.split():
try:
getattr(self, i).remove('-mno-cygwin')
except ValueError:
pass
Bryan O'Sullivan
setup: disable -mno-cygwin if building under mingw32...
r17121
Ludovic Chabant
setup: don't fail when Python doesn't have the cygwinccompiler package...
r23677 cygwinccompiler.Mingw32CCompiler = HackedMingw32CCompiler
except ImportError:
# the cygwinccompiler package is not available on some Python
# distributions like the ones from the optware project for Synology
# DiskStation boxes
class HackedMingw32CCompiler(object):
pass
Bryan O'Sullivan
setup: disable -mno-cygwin if building under mingw32...
r17121
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Harbison
setup: avoid linker warnings on Windows about multiple export specifications...
r32782 if os.name == 'nt':
# Allow compiler/linker flags to be added to Visual Studio builds. Passing
# extra_link_args to distutils.extensions.Extension() doesn't have any
# effect.
from distutils import msvccompiler
Mike Hommey
setup: fix installing in a mingw environment...
r33780 msvccompilerclass = msvccompiler.MSVCCompiler
Matt Harbison
setup: avoid linker warnings on Windows about multiple export specifications...
r32782
class HackedMSVCCompiler(msvccompiler.MSVCCompiler):
def initialize(self):
Mike Hommey
setup: fix installing in a mingw environment...
r33780 msvccompilerclass.initialize(self)
Matt Harbison
setup: avoid linker warnings on Windows about multiple export specifications...
r32782 # "warning LNK4197: export 'func' specified multiple times"
self.ldflags_shared.append('/ignore:4197')
self.ldflags_shared_debug.append('/ignore:4197')
msvccompiler.MSVCCompiler = HackedMSVCCompiler
Augie Fackler
formatting: blacken the codebase...
r43346 packagedata = {
Augie Fackler
formating: upgrade to black 20.8b1...
r46554 'mercurial': [
'locale/*/LC_MESSAGES/hg.mo',
'dummycert.pem',
],
'mercurial.defaultrc': [
'*.rc',
],
'mercurial.helptext': [
'*.txt',
],
'mercurial.helptext.internals': [
'*.txt',
],
Augie Fackler
formatting: blacken the codebase...
r43346 }
Dan Villiom Podlaski Christiansen
setup: install translation files as package data...
r9999
def ordinarypath(p):
return p and p[0] != '.' and p[-1] != '~'
Augie Fackler
formatting: blacken the codebase...
r43346
Matt Mackall
many, many trivial check-code fixups
r10282 for root in ('templates',):
Dan Villiom Podlaski Christiansen
setup: install translation files as package data...
r9999 for curdir, dirs, files in os.walk(os.path.join('mercurial', root)):
Martin von Zweigbergk
packaging: include templates with their package as key in package_data...
r45865 packagename = curdir.replace(os.sep, '.')
packagedata[packagename] = list(filter(ordinarypath, files))
Dan Villiom Podlaski Christiansen
setup: install translation files as package data...
r9999
Martin Geisler
i18n: let Makefile generate i18n/hg.pot...
r7648 datafiles = []
Gregory Szorc
setup: convert setupversion to unicode...
r31316
# distutils expects version to be str/unicode. Converting it to
# unicode on Python 2 still works because it won't contain any
# non-ascii bytes and will be implicitly converted back to bytes
# when operated on.
assert isinstance(version, bytes)
setupversion = version.decode('ascii')
Adrian Buehlmann
setup.py: fixing version info for Windows hg.exe (py2exe)...
r10400 extra = {}
Gregory Szorc
setup: include additional packages in py2exe distribution...
r42017 py2exepackages = [
'hgdemandimport',
Gregory Szorc
setup: include hgext3rd package in py2exe builds...
r42084 'hgext3rd',
Gregory Szorc
setup: include additional packages in py2exe distribution...
r42017 'hgext',
'email',
# implicitly imported per module policy
# (cffi wouldn't be used as a frozen exe)
'mercurial.cext',
#'mercurial.cffi',
'mercurial.pure',
]
Gregory Szorc
setup: configure py2exe config via environment variables...
r42082 py2exeexcludes = []
Gregory Szorc
setup: exclude crypt32.dll in py2exe builds...
r42120 py2exedllexcludes = ['crypt32.dll']
Gregory Szorc
setup: configure py2exe config via environment variables...
r42082
Yuya Nishihara
setup: silence warning of unknown option python_requires on distutils...
r33601 if issetuptools:
extra['python_requires'] = supportedpy
Gregory Szorc
setup: include additional packages in py2exe distribution...
r42017
Adrian Buehlmann
setup.py: fixing version info for Windows hg.exe (py2exe)...
r10400 if py2exeloaded:
extra['console'] = [
Augie Fackler
formatting: blacken the codebase...
r43346 {
'script': 'hg',
Matt Harbison
copyright: update to 2020...
r44631 'copyright': 'Copyright (C) 2005-2020 Matt Mackall and others',
Augie Fackler
formatting: blacken the codebase...
r43346 'product_version': version,
}
]
Gregory Szorc
setup: properly install build_hgextindex for py2exe builds...
r42083 # Sub command of 'build' because 'py2exe' does not handle sub_commands.
# Need to override hgbuild because it has a private copy of
# build.sub_commands.
hgbuild.sub_commands.insert(0, ('build_hgextindex', None))
Steve Borho
wix: move library.zip and all *.pyd into a lib/ folder...
r25409 # put dlls in sub directory so that they won't pollute PATH
extra['zipfile'] = 'lib/library.zip'
Adrian Buehlmann
setup.py: fixing version info for Windows hg.exe (py2exe)...
r10400
Gregory Szorc
setup: configure py2exe config via environment variables...
r42082 # We allow some configuration to be supplemented via environment
# variables. This is better than setup.cfg files because it allows
# supplementing configs instead of replacing them.
extrapackages = os.environ.get('HG_PY2EXE_EXTRA_PACKAGES')
if extrapackages:
py2exepackages.extend(extrapackages.split(' '))
Gregory Szorc
setup: include additional packages in py2exe distribution...
r42017
Gregory Szorc
setup: configure py2exe config via environment variables...
r42082 excludes = os.environ.get('HG_PY2EXE_EXTRA_EXCLUDES')
if excludes:
py2exeexcludes.extend(excludes.split(' '))
Gregory Szorc
setup: include additional packages in py2exe distribution...
r42017
Gregory Szorc
setup: configure py2exe config via environment variables...
r42082 dllexcludes = os.environ.get('HG_PY2EXE_EXTRA_DLL_EXCLUDES')
if dllexcludes:
py2exedllexcludes.extend(dllexcludes.split(' '))
Gregory Szorc
setup: include additional packages in py2exe distribution...
r42017
Martin von Zweigbergk
extensions: make `hg help extensions` list disabled extensions with PyOxidizer...
r45692 if os.environ.get('PYOXIDIZER'):
hgbuild.sub_commands.insert(0, ('build_hgextindex', None))
Adrian Buehlmann
setup.py: fixing version info for Windows hg.exe (py2exe)...
r10400 if os.name == 'nt':
# Windows binary file versions for exe/dll files must have the
# form W.X.Y.Z, where W,X,Y,Z are numbers in the range 0..65535
Matt Harbison
py3: stringify setupversion on Windows...
r40419 setupversion = setupversion.split(r'+', 1)[0]
Martin Geisler
i18n: let Makefile generate i18n/hg.pot...
r7648
Alexander Solovyov
fix compiling of extensions for OS X and XCode 4.0
r13583 if sys.platform == 'darwin' and os.path.exists('/usr/bin/xcodebuild'):
Adam Simpkins
setup: fix runcmd() usage on darwin...
r33119 version = runcmd(['/usr/bin/xcodebuild', '-version'], {})[1].splitlines()
Greg Ward
setup: handle output from Apple's Xcode 4.3 better (issue3277)...
r16187 if version:
Brendan Cully
setup.py: don't call splitlines twice on the output of xcodebuild (issue3277)
r16209 version = version[0]
Augie Fackler
setup: decode xcode version number on python3
r25043 if sys.version_info[0] == 3:
version = version.decode('utf-8')
Augie Fackler
formatting: blacken the codebase...
r43346 xcode4 = version.startswith('Xcode') and StrictVersion(
version.split()[1]
) >= StrictVersion('4.0')
Matt Mackall
setup: make Xcode 5.1 check less specific...
r21558 xcode51 = re.match(r'^Xcode\s+5\.1', version) is not None
Greg Ward
setup: handle output from Apple's Xcode 4.3 better (issue3277)...
r16187 else:
# xcodebuild returns empty on OS X Lion with XCode 4.3 not
# installed, but instead with only command-line tools. Assume
# that only happens on >= Lion, thus no PPC support.
xcode4 = True
Kent Frazier
setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
r21038 xcode51 = False
Greg Ward
setup: handle output from Apple's Xcode 4.3 better (issue3277)...
r16187
Kent Frazier
setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
r21038 # XCode 4.0 dropped support for ppc architecture, which is hardcoded in
# distutils.sysconfig
Greg Ward
setup: handle output from Apple's Xcode 4.3 better (issue3277)...
r16187 if xcode4:
Brendan Cully
Hardcoding ARCHFLAGS breaks the build against fink's python...
r14324 os.environ['ARCHFLAGS'] = ''
Alexander Solovyov
fix compiling of extensions for OS X and XCode 4.0
r13583
Kent Frazier
setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
r21038 # XCode 5.1 changes clang such that it now fails to compile if the
# -mno-fused-madd flag is passed, but the version of Python shipped with
# OS X 10.9 Mavericks includes this flag. This causes problems in all
# C extension modules, and a bug has been filed upstream at
# http://bugs.python.org/issue21244. We also need to patch this here
# so Mercurial can continue to compile in the meantime.
if xcode51:
cflags = get_config_var('CFLAGS')
Alex Gaynor
setup: fixed for Pythons which don't have a CFLAGS...
r21839 if cflags and re.search(r'-mno-fused-madd\b', cflags) is not None:
Kent Frazier
setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
r21038 os.environ['CFLAGS'] = (
Augie Fackler
formatting: blacken the codebase...
r43346 os.environ.get('CFLAGS', '') + ' -Qunused-arguments'
)
Kent Frazier
setup.py: fix C extension compilation issue with OS X 10.9 and Xcode 5.1
r21038
Augie Fackler
formatting: blacken the codebase...
r43346 setup(
name='mercurial',
version=setupversion,
author='Matt Mackall and many others',
author_email='mercurial@mercurial-scm.org',
url='https://mercurial-scm.org/',
download_url='https://mercurial-scm.org/release/',
description=(
'Fast scalable distributed SCM (revision control, version '
'control) system'
),
long_description=(
'Mercurial is a distributed SCM tool written in Python.'
' It is used by a number of large projects that require'
' fast, reliable distributed revision control, such as '
'Mozilla.'
),
license='GNU GPLv2 or any later version',
classifiers=[
'Development Status :: 6 - Mature',
'Environment :: Console',
'Intended Audience :: Developers',
'Intended Audience :: System Administrators',
'License :: OSI Approved :: GNU General Public License (GPL)',
'Natural Language :: Danish',
'Natural Language :: English',
'Natural Language :: German',
'Natural Language :: Italian',
'Natural Language :: Japanese',
'Natural Language :: Portuguese (Brazilian)',
'Operating System :: Microsoft :: Windows',
'Operating System :: OS Independent',
'Operating System :: POSIX',
'Programming Language :: C',
'Programming Language :: Python',
'Topic :: Software Development :: Version Control',
],
scripts=scripts,
packages=packages,
ext_modules=extmodules,
data_files=datafiles,
package_data=packagedata,
cmdclass=cmdclass,
distclass=hgdist,
options={
'py2exe': {
'bundle_files': 3,
'dll_excludes': py2exedllexcludes,
'excludes': py2exeexcludes,
'packages': py2exepackages,
},
'bdist_mpkg': {
'zipdist': False,
'license': 'COPYING',
'readme': 'contrib/packaging/macosx/Readme.html',
'welcome': 'contrib/packaging/macosx/Welcome.html',
},
},
**extra
)