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

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

74 statements  

1# SPDX-License-Identifier: GPL-2.0-only 

2# This file is part of Scapy 

3# See https://scapy.net/ for more information 

4# Copyright (C) Philippe Biondi <phil@secdev.org> 

5 

6""" 

7Scapy: create, send, sniff, dissect and manipulate network packets. 

8 

9Usable either from an interactive console or as a Python library. 

10https://scapy.net 

11""" 

12 

13import datetime 

14import os 

15import re 

16import subprocess 

17 

18__all__ = [ 

19 "VERSION", 

20 "__version__", 

21] 

22 

23_SCAPY_PKG_DIR = os.path.dirname(__file__) 

24 

25 

26def _parse_tag(tag): 

27 # type: (str) -> str 

28 """ 

29 Parse a tag from ``git describe`` into a version. 

30 

31 Example:: 

32 

33 v2.3.2-346-g164a52c075c8 -> '2.3.2.dev346' 

34 """ 

35 match = re.match('^v?(.+?)-(\\d+)-g[a-f0-9]+$', tag) 

36 if match: 

37 # remove the 'v' prefix and add a '.devN' suffix 

38 return '%s.dev%s' % (match.group(1), match.group(2)) 

39 else: 

40 raise ValueError('tag has invalid format') 

41 

42 

43def _version_from_git_archive(): 

44 # type: () -> str 

45 """ 

46 Rely on git archive "export-subst" git attribute. 

47 See 'man gitattributes' for more details. 

48 Note: describe is only supported with git >= 2.32.0, 

49 and the `tags=true` option with git >= 2.35.0 but we 

50 use it to workaround GH#3121. 

51 """ 

52 git_archive_id = '$Format:%ct %(describe:tags=true)$'.split() 

53 tstamp = git_archive_id[0] 

54 if len(git_archive_id) > 1: 

55 tag = git_archive_id[1] 

56 else: 

57 # project is run in CI and has another %(describe) 

58 tag = "" 

59 

60 if "Format" in tstamp: 

61 raise ValueError('not a git archive') 

62 

63 if "describe" in tag: 

64 # git is too old! 

65 tag = "" 

66 if tag: 

67 # archived revision is tagged, use the tag 

68 return _parse_tag(tag) 

69 elif tstamp: 

70 # archived revision is not tagged, use the commit date 

71 d = datetime.datetime.utcfromtimestamp(int(tstamp)) 

72 return d.strftime('%Y.%m.%d') 

73 

74 raise ValueError("invalid git archive format") 

75 

76 

77def _version_from_git_describe(): 

78 # type: () -> str 

79 """ 

80 Read the version from ``git describe``. It returns the latest tag with an 

81 optional suffix if the current directory is not exactly on the tag. 

82 

83 Example:: 

84 

85 $ git describe --always 

86 v2.3.2-346-g164a52c075c8 

87 

88 The tag prefix (``v``) and the git commit sha1 (``-g164a52c075c8``) are 

89 removed if present. 

90 

91 If the current directory is not exactly on the tag, a ``.devN`` suffix is 

92 appended where N is the number of commits made after the last tag. 

93 

94 Example:: 

95 

96 >>> _version_from_git_describe() 

97 '2.3.2.dev346' 

98 

99 :raises CalledProcessError: if git is unavailable 

100 :return: Scapy's latest tag 

101 """ 

102 if not os.path.isdir(os.path.join(os.path.dirname(_SCAPY_PKG_DIR), '.git')): # noqa: E501 

103 raise ValueError('not in scapy git repo') 

104 

105 def _git(cmd): 

106 # type: (str) -> str 

107 process = subprocess.Popen( 

108 cmd.split(), 

109 cwd=_SCAPY_PKG_DIR, 

110 stdout=subprocess.PIPE, 

111 stderr=subprocess.PIPE 

112 ) 

113 out, err = process.communicate() 

114 if process.returncode == 0: 

115 return out.decode().strip() 

116 else: 

117 raise subprocess.CalledProcessError(process.returncode, err) 

118 

119 tag = _git("git describe --tags --always --long") 

120 if not tag.startswith("v"): 

121 # Upstream was not fetched 

122 commit = _git("git rev-list --tags --max-count=1") 

123 tag = _git("git describe --tags --always --long %s" % commit) 

124 return _parse_tag(tag) 

125 

126 

127def _version(): 

128 # type: () -> str 

129 """Returns the Scapy version from multiple methods 

130 

131 :return: the Scapy version 

132 """ 

133 # Method 0: from external packaging 

134 try: 

135 # possibly forced by external packaging 

136 return os.environ['SCAPY_VERSION'] 

137 except KeyError: 

138 pass 

139 

140 # Method 1: from the VERSION file, included in sdist and wheels 

141 version_file = os.path.join(_SCAPY_PKG_DIR, 'VERSION') 

142 try: 

143 # file generated when running sdist 

144 with open(version_file, 'r') as fdsec: 

145 tag = fdsec.read() 

146 return tag 

147 except (FileNotFoundError, NotADirectoryError): 

148 pass 

149 

150 # Method 2: from the archive tag, exported when using git archives 

151 try: 

152 return _version_from_git_archive() 

153 except ValueError: 

154 pass 

155 

156 # Method 3: from git itself, used when Scapy was cloned 

157 try: 

158 return _version_from_git_describe() 

159 except Exception: 

160 pass 

161 

162 # Fallback 

163 try: 

164 # last resort, use the modification date of __init__.py 

165 d = datetime.datetime.utcfromtimestamp(os.path.getmtime(__file__)) 

166 return d.strftime('%Y.%m.%d') 

167 except Exception: 

168 pass 

169 

170 # all hope is lost 

171 return '0.0.0' 

172 

173 

174VERSION = __version__ = _version() 

175 

176_tmp = re.search(r"([0-9]|\.[0-9])+", VERSION) 

177VERSION_MAIN = _tmp.group() if _tmp is not None else VERSION 

178 

179if __name__ == "__main__": 

180 from scapy.main import interact 

181 interact()