Coverage for /home/martinb/.local/share/virtualenvs/camcops/lib/python3.6/site-packages/zope/interface/_compat.py : 72%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1##############################################################################
2#
3# Copyright (c) 2006 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"""
15Support functions for dealing with differences in platforms, including Python
16versions and implementations.
18This file should have no imports from the rest of zope.interface because it is
19used during early bootstrapping.
20"""
21import os
22import sys
23import types
25if sys.version_info[0] < 3:
27 def _normalize_name(name):
28 if isinstance(name, basestring):
29 return unicode(name)
30 raise TypeError("name must be a regular or unicode string")
32 CLASS_TYPES = (type, types.ClassType)
33 STRING_TYPES = (basestring,)
35 _BUILTINS = '__builtin__'
37 PYTHON3 = False
38 PYTHON2 = True
40else:
42 def _normalize_name(name):
43 if isinstance(name, bytes):
44 name = str(name, 'ascii')
45 if isinstance(name, str):
46 return name
47 raise TypeError("name must be a string or ASCII-only bytes")
49 CLASS_TYPES = (type,)
50 STRING_TYPES = (str,)
52 _BUILTINS = 'builtins'
54 PYTHON3 = True
55 PYTHON2 = False
57PYPY = hasattr(sys, 'pypy_version_info')
58PYPY2 = PYTHON2 and PYPY
60def _skip_under_py3k(test_method):
61 import unittest
62 return unittest.skipIf(sys.version_info[0] >= 3, "Only on Python 2")(test_method)
65def _skip_under_py2(test_method):
66 import unittest
67 return unittest.skipIf(sys.version_info[0] < 3, "Only on Python 3")(test_method)
70def _c_optimizations_required():
71 """
72 Return a true value if the C optimizations are required.
74 This uses the ``PURE_PYTHON`` variable as documented in `_use_c_impl`.
75 """
76 pure_env = os.environ.get('PURE_PYTHON')
77 require_c = pure_env == "0"
78 return require_c
81def _c_optimizations_available():
82 """
83 Return the C optimization module, if available, otherwise
84 a false value.
86 If the optimizations are required but not available, this
87 raises the ImportError.
89 This does not say whether they should be used or not.
90 """
91 catch = () if _c_optimizations_required() else (ImportError,)
92 try:
93 from zope.interface import _zope_interface_coptimizations as c_opt
94 return c_opt
95 except catch: # pragma: no cover (only Jython doesn't build extensions)
96 return False
99def _c_optimizations_ignored():
100 """
101 The opposite of `_c_optimizations_required`.
102 """
103 pure_env = os.environ.get('PURE_PYTHON')
104 return pure_env is not None and pure_env != "0"
107def _should_attempt_c_optimizations():
108 """
109 Return a true value if we should attempt to use the C optimizations.
111 This takes into account whether we're on PyPy and the value of the
112 ``PURE_PYTHON`` environment variable, as defined in `_use_c_impl`.
113 """
114 is_pypy = hasattr(sys, 'pypy_version_info')
116 if _c_optimizations_required():
117 return True
118 if is_pypy:
119 return False
120 return not _c_optimizations_ignored()
123def _use_c_impl(py_impl, name=None, globs=None):
124 """
125 Decorator. Given an object implemented in Python, with a name like
126 ``Foo``, import the corresponding C implementation from
127 ``zope.interface._zope_interface_coptimizations`` with the name
128 ``Foo`` and use it instead.
130 If the ``PURE_PYTHON`` environment variable is set to any value
131 other than ``"0"``, or we're on PyPy, ignore the C implementation
132 and return the Python version. If the C implementation cannot be
133 imported, return the Python version. If ``PURE_PYTHON`` is set to
134 0, *require* the C implementation (let the ImportError propagate);
135 note that PyPy can import the C implementation in this case (and all
136 tests pass).
138 In all cases, the Python version is kept available. in the module
139 globals with the name ``FooPy`` and the name ``FooFallback`` (both
140 conventions have been used; the C implementation of some functions
141 looks for the ``Fallback`` version, as do some of the Sphinx
142 documents).
144 Example::
146 @_use_c_impl
147 class Foo(object):
148 ...
149 """
150 name = name or py_impl.__name__
151 globs = globs or sys._getframe(1).f_globals
153 def find_impl():
154 if not _should_attempt_c_optimizations():
155 return py_impl
157 c_opt = _c_optimizations_available()
158 if not c_opt: # pragma: no cover (only Jython doesn't build extensions)
159 return py_impl
161 __traceback_info__ = c_opt
162 return getattr(c_opt, name)
164 c_impl = find_impl()
165 # Always make available by the FooPy name and FooFallback
166 # name (for testing and documentation)
167 globs[name + 'Py'] = py_impl
168 globs[name + 'Fallback'] = py_impl
170 return c_impl