##// END OF EJS Templates
amend: prevent '\n' in the note string...
amend: prevent '\n' in the note string This comes from the evolve function. I'm not sure why this check was missing in core, since it was present when the length check was added to evolve. I didn't flag this as BC because 530b7361e3a9 mentioned this argument wasn't added to the release notes due to no display capability, and that hasn't changed AFAIK. Differential Revision: https://phab.mercurial-scm.org/D6854

File last commit:

r42644:f7385ed7 default
r43203:7e999704 default
Show More
policy.py
146 lines | 4.8 KiB | text/x-python | PythonLexer
timeless
debuginstall: expose modulepolicy...
r29266 # policy.py - module policy logic for Mercurial.
#
# Copyright 2015 Gregory Szorc <gregory.szorc@gmail.com>
#
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
import os
import sys
# Rules for how modules can be loaded. Values are:
#
# c - require C extensions
Georges Racinet
rust: module policy with importrust...
r42651 # rust+c - require Rust and C extensions
# rust+c-allow - allow Rust and C extensions with fallback to pure Python
# for each
timeless
debuginstall: expose modulepolicy...
r29266 # allow - allow pure Python implementation when C loading fails
Maciej Fijalkowski
policy: add cffi policy for PyPy...
r29490 # cffi - required cffi versions (implemented within pure module)
# cffi-allow - allow pure Python implementation if cffi version is missing
timeless
debuginstall: expose modulepolicy...
r29266 # py - only load pure Python modules
#
Yuya Nishihara
policy: relax the default for in-place build...
r32251 # By default, fall back to the pure modules so the in-place build can
# run without recompiling the C extensions. This will be overridden by
# __modulepolicy__ generated by setup.py.
policy = b'allow'
Yuya Nishihara
policy: add helper to import cext/pure module...
r32366 _packageprefs = {
# policy: (versioned package, pure package)
b'c': (r'cext', None),
b'allow': (r'cext', r'pure'),
Yuya Nishihara
cffi: split modules from pure...
r32512 b'cffi': (r'cffi', None),
b'cffi-allow': (r'cffi', r'pure'),
Yuya Nishihara
policy: add helper to import cext/pure module...
r32366 b'py': (None, r'pure'),
Georges Racinet
rust: module policy with importrust...
r42651 # For now, rust policies impact importrust only
b'rust+c': (r'cext', None),
b'rust+c-allow': (r'cext', r'pure'),
Yuya Nishihara
policy: add helper to import cext/pure module...
r32366 }
Maciej Fijalkowski
policy: add cffi policy for PyPy...
r29490
timeless
debuginstall: expose modulepolicy...
r29266 try:
from . import __modulepolicy__
policy = __modulepolicy__.modulepolicy
except ImportError:
pass
# PyPy doesn't load C extensions.
#
# The canonical way to do this is to test platform.python_implementation().
# But we don't import platform and don't bloat for it here.
Yuya Nishihara
policy: mark all string literals as sysstr or bytes...
r32205 if r'__pypy__' in sys.builtin_module_names:
policy = b'cffi'
timeless
debuginstall: expose modulepolicy...
r29266
# Environment variable can always force settings.
FUJIWARA Katsunori
py3: add "b" prefix to string literals related to module policy...
r31361 if sys.version_info[0] >= 3:
Yuya Nishihara
policy: mark all string literals as sysstr or bytes...
r32205 if r'HGMODULEPOLICY' in os.environ:
policy = os.environ[r'HGMODULEPOLICY'].encode(r'utf-8')
FUJIWARA Katsunori
py3: add "b" prefix to string literals related to module policy...
r31361 else:
Yuya Nishihara
policy: mark all string literals as sysstr or bytes...
r32205 policy = os.environ.get(r'HGMODULEPOLICY', policy)
Yuya Nishihara
policy: add helper to import cext/pure module...
r32366
def _importfrom(pkgname, modname):
# from .<pkgname> import <modname> (where . is looked through this module)
fakelocals = {}
pkg = __import__(pkgname, globals(), fakelocals, [modname], level=1)
try:
fakelocals[modname] = mod = getattr(pkg, modname)
except AttributeError:
raise ImportError(r'cannot import name %s' % modname)
# force import; fakelocals[modname] may be replaced with the real module
getattr(mod, r'__doc__', None)
return fakelocals[modname]
Jun Wu
policy: define C module versions individually...
r32428 # keep in sync with "version" in C modules
_cextversions = {
Yuya Nishihara
policy: extend API version checks for cffi...
r32511 (r'cext', r'base85'): 1,
Jun Wu
bdiff: add a xdiffblocks method...
r36693 (r'cext', r'bdiff'): 3,
Yuya Nishihara
policy: extend API version checks for cffi...
r32511 (r'cext', r'mpatch'): 1,
Augie Fackler
osutil: implement minimal __getitem__ compatibility on our custom listdir type...
r36798 (r'cext', r'osutil'): 4,
Martin von Zweigbergk
util: make util.dirs() and util.finddirs() include root directory (API)...
r42530 (r'cext', r'parsers'): 13,
Jun Wu
policy: define C module versions individually...
r32428 }
Yuya Nishihara
policy: reroute proxy modules internally...
r33755 # map import request to other package or module
_modredirects = {
Yuya Nishihara
encoding: drop circular import by proxying through '<policy>.charencode'...
r33756 (r'cext', r'charencode'): (r'cext', r'parsers'),
Yuya Nishihara
policy: reroute proxy modules internally...
r33755 (r'cffi', r'base85'): (r'pure', r'base85'),
Yuya Nishihara
encoding: drop circular import by proxying through '<policy>.charencode'...
r33756 (r'cffi', r'charencode'): (r'pure', r'charencode'),
Yuya Nishihara
policy: reroute proxy modules internally...
r33755 (r'cffi', r'parsers'): (r'pure', r'parsers'),
}
Yuya Nishihara
policy: add helper to import cext/pure module...
r32366 def _checkmod(pkgname, modname, mod):
Yuya Nishihara
policy: extend API version checks for cffi...
r32511 expected = _cextversions.get((pkgname, modname))
Yuya Nishihara
policy: add helper to import cext/pure module...
r32366 actual = getattr(mod, r'version', None)
if actual != expected:
raise ImportError(r'cannot import module %s.%s '
r'(expected version: %d, actual: %r)'
% (pkgname, modname, expected, actual))
def importmod(modname):
"""Import module according to policy and check API version"""
try:
verpkg, purepkg = _packageprefs[policy]
except KeyError:
raise ImportError(r'invalid HGMODULEPOLICY %r' % policy)
assert verpkg or purepkg
if verpkg:
Yuya Nishihara
policy: reroute proxy modules internally...
r33755 pn, mn = _modredirects.get((verpkg, modname), (verpkg, modname))
Yuya Nishihara
policy: add helper to import cext/pure module...
r32366 try:
Yuya Nishihara
policy: reroute proxy modules internally...
r33755 mod = _importfrom(pn, mn)
if pn == verpkg:
_checkmod(pn, mn, mod)
Yuya Nishihara
policy: add helper to import cext/pure module...
r32366 return mod
except ImportError:
if not purepkg:
raise
Yuya Nishihara
policy: reroute proxy modules internally...
r33755 pn, mn = _modredirects.get((purepkg, modname), (purepkg, modname))
return _importfrom(pn, mn)
Georges Racinet
rust: module policy with importrust...
r42651
def _isrustpermissive():
"""Assuming the policy is a Rust one, tell if it's permissive."""
return policy.endswith(b'-allow')
def importrust(modname, member=None, default=None):
"""Import Rust module according to policy and availability.
If policy isn't a Rust one, this returns `default`.
If either the module or its member is not available, this returns `default`
if policy is permissive and raises `ImportError` if not.
"""
if not policy.startswith(b'rust'):
return default
try:
mod = _importfrom(r'rustext', modname)
except ImportError:
if _isrustpermissive():
return default
raise
if member is None:
return mod
try:
return getattr(mod, member)
except AttributeError:
if _isrustpermissive():
return default
raise ImportError(r"Cannot import name %s" % member)