• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / BTrees / 3742775428

pending completion
3742775428

push

github

Michael Howitz
Drop support for Python 2.7 up to 3.6.

1683 of 1786 branches covered (94.23%)

Branch coverage included in aggregate %.

129 of 130 new or added lines in 13 files covered. (99.23%)

7737 of 8241 relevant lines covered (93.88%)

5.62 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

94.2
/src/BTrees/_compat.py
1
##############################################################################
2
#
3
# Copyright (c) 2001-2012 Zope Foundation and Contributors.
4
# All Rights Reserved.
5
#
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE
12
#
13
##############################################################################
14
import os
6✔
15
import sys
6✔
16

17
PYPY = hasattr(sys, 'pypy_version_info')
6✔
18

19
def compare(x, y):
6✔
20
    if x is None:
6✔
21
        if y is None:
6!
NEW
22
            return 0
×
23
        else:
24
            return -1
6✔
25
    elif y is None:
6✔
26
        return 1
6✔
27
    else:
28
        return (x > y) - (y > x)
6✔
29

30
def _ascii(x):
6✔
31
    return bytes(x, 'ascii')
6✔
32

33
def _c_optimizations_required():
6✔
34
    """
35
    Return a true value if the C optimizations are required.
36

37
    This uses the ``PURE_PYTHON`` variable as documented in `import_c_extension`.
38
    """
39
    pure_env = os.environ.get('PURE_PYTHON')
5✔
40
    require_c = pure_env == "0"
5✔
41
    return require_c
5✔
42

43

44
def _c_optimizations_available(module_name):
6✔
45
    """
46
    Return the C optimization module, if available, otherwise
47
    a false value.
48

49
    If the optimizations are required but not available, this
50
    raises the ImportError.
51

52
    This does not say whether they should be used or not.
53
    """
54
    import importlib
5✔
55
    catch = () if _c_optimizations_required() else (ImportError,)
5✔
56
    try:
5✔
57
        return importlib.import_module('BTrees._' + module_name)
5✔
58
    except catch: # pragma: no cover
59
        return False
60

61

62
def _c_optimizations_ignored():
6✔
63
    """
64
    The opposite of `_c_optimizations_required`.
65
    """
66
    pure_env = os.environ.get('PURE_PYTHON')
6✔
67
    return pure_env != "0" if pure_env is not None else PYPY
6✔
68

69

70
def _should_attempt_c_optimizations():
6✔
71
    """
72
    Return a true value if we should attempt to use the C optimizations.
73

74
    This takes into account whether we're on PyPy and the value of the
75
    ``PURE_PYTHON`` environment variable, as defined in `import_c_extension`.
76
    """
77
    if PYPY:
6✔
78
        return False
1✔
79

80
    if _c_optimizations_required():
5!
81
        return True
×
82
    return not _c_optimizations_ignored()
5✔
83

84

85
def import_c_extension(mod_globals):
6✔
86
    """
87
    Call this function with the globals of a module that implements
88
    Python versions of a BTree family to find the C optimizations.
89

90
    If the ``PURE_PYTHON`` environment variable is set to any value
91
    other than ``"0"``, or we're on PyPy, ignore the C implementation.
92
    If the C implementation cannot be imported, return the Python
93
    version. If ``PURE_PYTHON`` is set to ``"0"``, *require* the C
94
    implementation (let the ImportError propagate); the exception again
95
    is PyPy, where we never use the C extension (although it builds here, the
96
    ``persistent`` library doesn't provide native extensions for PyPy).
97

98
    """
99
    c_module = None
6✔
100
    module_name = mod_globals['__name__']
6✔
101
    assert module_name.startswith('BTrees.')
6✔
102
    module_name = module_name.split('.')[1]
6✔
103
    if _should_attempt_c_optimizations():
6✔
104
        c_module = _c_optimizations_available(module_name)
5✔
105

106
    if c_module:
6✔
107
        new_values = dict(c_module.__dict__)
5✔
108
        new_values.pop("__name__", None)
5✔
109
        new_values.pop('__file__', None)
5✔
110
        new_values.pop('__doc__', None)
5✔
111
        mod_globals.update(new_values)
5✔
112
    else:
113
        # No C extension, make the Py versions available without that
114
        # extension. The list comprehension both filters and prevents
115
        # concurrent modification errors.
116
        for py in [k for k in mod_globals if k.endswith('Py')]:
6✔
117
            mod_globals[py[:-2]] = mod_globals[py]
6✔
118

119
    # Assign the global aliases
120
    prefix = module_name[:2]
6✔
121
    for name in ('Bucket', 'Set', 'BTree', 'TreeSet'):
6✔
122
        mod_globals[name] = mod_globals[prefix + name]
6✔
123

124
    # Cleanup
125
    mod_globals.pop('import_c_extension', None)
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc