Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.8/site-packages/zmq/__init__.py: 57%

68 statements  

« prev     ^ index     » next       coverage.py v7.2.7, created at 2023-06-03 06:10 +0000

1"""Python bindings for 0MQ.""" 

2 

3# Copyright (C) PyZMQ Developers 

4# Distributed under the terms of the Modified BSD License. 

5 

6# load bundled libzmq, if there is one: 

7 

8import os 

9import sys 

10from contextlib import contextmanager 

11 

12 

13def _load_libzmq(): 

14 """load bundled libzmq if there is one""" 

15 import platform 

16 

17 dlopen = hasattr(sys, 'getdlopenflags') # unix-only 

18 # RTLD flags are added to os in Python 3 

19 # get values from os because ctypes values are WRONG on pypy 

20 PYPY = platform.python_implementation().lower() == 'pypy' 

21 

22 if dlopen: 

23 import ctypes 

24 

25 dlflags = sys.getdlopenflags() 

26 # set RTLD_GLOBAL, unset RTLD_LOCAL 

27 flags = ctypes.RTLD_GLOBAL | dlflags 

28 # ctypes.RTLD_LOCAL is 0 on pypy, which is *wrong* 

29 flags &= ~getattr(os, 'RTLD_LOCAL', 4) 

30 # pypy on darwin needs RTLD_LAZY for some reason 

31 if PYPY and sys.platform == 'darwin': 

32 flags |= getattr(os, 'RTLD_LAZY', 1) 

33 flags &= ~getattr(os, 'RTLD_NOW', 2) 

34 sys.setdlopenflags(flags) 

35 try: 

36 from . import libzmq 

37 except ImportError: 

38 # raise on failure to load if libzmq is present 

39 from importlib.util import find_spec 

40 

41 if find_spec(".libzmq", "zmq"): 

42 # found libzmq, but failed to load it! 

43 # raise instead of silently moving on 

44 raise 

45 else: 

46 # store libzmq as zmq._libzmq for backward-compat 

47 globals()['_libzmq'] = libzmq 

48 if PYPY: 

49 # should already have been imported above, so reimporting is as cheap as checking 

50 import ctypes 

51 

52 # some versions of pypy (5.3 < ? < 5.8) needs explicit CDLL load for some reason, 

53 # otherwise symbols won't be globally available 

54 # do this unconditionally because it should be harmless (?) 

55 ctypes.CDLL(libzmq.__file__, ctypes.RTLD_GLOBAL) 

56 finally: 

57 if dlopen: 

58 sys.setdlopenflags(dlflags) 

59 

60 

61_load_libzmq() 

62 

63 

64@contextmanager 

65def _libs_on_path(): 

66 """context manager for libs directory on $PATH 

67 

68 Works around mysterious issue where os.add_dll_directory 

69 does not resolve imports (conda-forge Python >= 3.8) 

70 """ 

71 

72 if not sys.platform.startswith("win"): 

73 yield 

74 return 

75 

76 libs_dir = os.path.abspath( 

77 os.path.join( 

78 os.path.dirname(__file__), 

79 os.pardir, 

80 "pyzmq.libs", 

81 ) 

82 ) 

83 if not os.path.exists(libs_dir): 

84 # no bundled libs 

85 yield 

86 return 

87 

88 path_before = os.environ.get("PATH") 

89 try: 

90 os.environ["PATH"] = os.pathsep.join([path_before or "", libs_dir]) 

91 yield 

92 finally: 

93 if path_before is None: 

94 os.environ.pop("PATH") 

95 else: 

96 os.environ["PATH"] = path_before 

97 

98 

99# zmq top-level imports 

100 

101# workaround for Windows 

102with _libs_on_path(): 

103 from zmq import backend 

104 

105from . import constants # noqa 

106from .constants import * # noqa 

107from zmq.backend import * # noqa 

108from zmq import sugar 

109from zmq.sugar import * # noqa 

110 

111 

112def get_includes(): 

113 """Return a list of directories to include for linking against pyzmq with cython.""" 

114 from os.path import abspath, dirname, exists, join, pardir 

115 

116 base = dirname(__file__) 

117 parent = abspath(join(base, pardir)) 

118 includes = [parent] + [join(parent, base, subdir) for subdir in ('utils',)] 

119 if exists(join(parent, base, 'include')): 

120 includes.append(join(parent, base, 'include')) 

121 return includes 

122 

123 

124def get_library_dirs(): 

125 """Return a list of directories used to link against pyzmq's bundled libzmq.""" 

126 from os.path import abspath, dirname, join, pardir 

127 

128 base = dirname(__file__) 

129 parent = abspath(join(base, pardir)) 

130 return [join(parent, base)] 

131 

132 

133COPY_THRESHOLD = 65536 

134DRAFT_API = backend.has("draft") 

135 

136__all__ = ( 

137 [ 

138 'get_includes', 

139 'COPY_THRESHOLD', 

140 'DRAFT_API', 

141 ] 

142 + constants.__all__ 

143 + sugar.__all__ 

144 + backend.__all__ 

145)