Funktionierender Prototyp des Serious Games zur Vermittlung von Wissen zu Software-Engineering-Arbeitsmodellen.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

_compat.py 4.3KB

1 year ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135
  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. """
  15. Support functions for dealing with differences in platforms, including Python
  16. versions and implementations.
  17. This file should have no imports from the rest of zope.interface because it is
  18. used during early bootstrapping.
  19. """
  20. import os
  21. import sys
  22. def _normalize_name(name):
  23. if isinstance(name, bytes):
  24. name = str(name, 'ascii')
  25. if isinstance(name, str):
  26. return name
  27. raise TypeError("name must be a string or ASCII-only bytes")
  28. PYPY = hasattr(sys, 'pypy_version_info')
  29. def _c_optimizations_required():
  30. """
  31. Return a true value if the C optimizations are required.
  32. This uses the ``PURE_PYTHON`` variable as documented in `_use_c_impl`.
  33. """
  34. pure_env = os.environ.get('PURE_PYTHON')
  35. require_c = pure_env == "0"
  36. return require_c
  37. def _c_optimizations_available():
  38. """
  39. Return the C optimization module, if available, otherwise
  40. a false value.
  41. If the optimizations are required but not available, this
  42. raises the ImportError.
  43. This does not say whether they should be used or not.
  44. """
  45. catch = () if _c_optimizations_required() else (ImportError,)
  46. try:
  47. from zope.interface import _zope_interface_coptimizations as c_opt
  48. return c_opt
  49. except catch: # pragma: no cover (only Jython doesn't build extensions)
  50. return False
  51. def _c_optimizations_ignored():
  52. """
  53. The opposite of `_c_optimizations_required`.
  54. """
  55. pure_env = os.environ.get('PURE_PYTHON')
  56. return pure_env is not None and pure_env != "0"
  57. def _should_attempt_c_optimizations():
  58. """
  59. Return a true value if we should attempt to use the C optimizations.
  60. This takes into account whether we're on PyPy and the value of the
  61. ``PURE_PYTHON`` environment variable, as defined in `_use_c_impl`.
  62. """
  63. is_pypy = hasattr(sys, 'pypy_version_info')
  64. if _c_optimizations_required():
  65. return True
  66. if is_pypy:
  67. return False
  68. return not _c_optimizations_ignored()
  69. def _use_c_impl(py_impl, name=None, globs=None):
  70. """
  71. Decorator. Given an object implemented in Python, with a name like
  72. ``Foo``, import the corresponding C implementation from
  73. ``zope.interface._zope_interface_coptimizations`` with the name
  74. ``Foo`` and use it instead.
  75. If the ``PURE_PYTHON`` environment variable is set to any value
  76. other than ``"0"``, or we're on PyPy, ignore the C implementation
  77. and return the Python version. If the C implementation cannot be
  78. imported, return the Python version. If ``PURE_PYTHON`` is set to
  79. 0, *require* the C implementation (let the ImportError propagate);
  80. note that PyPy can import the C implementation in this case (and all
  81. tests pass).
  82. In all cases, the Python version is kept available. in the module
  83. globals with the name ``FooPy`` and the name ``FooFallback`` (both
  84. conventions have been used; the C implementation of some functions
  85. looks for the ``Fallback`` version, as do some of the Sphinx
  86. documents).
  87. Example::
  88. @_use_c_impl
  89. class Foo(object):
  90. ...
  91. """
  92. name = name or py_impl.__name__
  93. globs = globs or sys._getframe(1).f_globals
  94. def find_impl():
  95. if not _should_attempt_c_optimizations():
  96. return py_impl
  97. c_opt = _c_optimizations_available()
  98. if not c_opt: # pragma: no cover (only Jython doesn't build extensions)
  99. return py_impl
  100. __traceback_info__ = c_opt
  101. return getattr(c_opt, name)
  102. c_impl = find_impl()
  103. # Always make available by the FooPy name and FooFallback
  104. # name (for testing and documentation)
  105. globs[name + 'Py'] = py_impl
  106. globs[name + 'Fallback'] = py_impl
  107. return c_impl