diff options
Diffstat (limited to 'venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile')
6 files changed, 920 insertions, 0 deletions
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py new file mode 100644 index 0000000..228e051 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/__init__.py | |||
@@ -0,0 +1,347 @@ | |||
1 | # -*- coding: utf-8 -*- | ||
2 | |||
3 | """ | ||
4 | lockfile.py - Platform-independent advisory file locks. | ||
5 | |||
6 | Requires Python 2.5 unless you apply 2.4.diff | ||
7 | Locking is done on a per-thread basis instead of a per-process basis. | ||
8 | |||
9 | Usage: | ||
10 | |||
11 | >>> lock = LockFile('somefile') | ||
12 | >>> try: | ||
13 | ... lock.acquire() | ||
14 | ... except AlreadyLocked: | ||
15 | ... print 'somefile', 'is locked already.' | ||
16 | ... except LockFailed: | ||
17 | ... print 'somefile', 'can\\'t be locked.' | ||
18 | ... else: | ||
19 | ... print 'got lock' | ||
20 | got lock | ||
21 | >>> print lock.is_locked() | ||
22 | True | ||
23 | >>> lock.release() | ||
24 | |||
25 | >>> lock = LockFile('somefile') | ||
26 | >>> print lock.is_locked() | ||
27 | False | ||
28 | >>> with lock: | ||
29 | ... print lock.is_locked() | ||
30 | True | ||
31 | >>> print lock.is_locked() | ||
32 | False | ||
33 | |||
34 | >>> lock = LockFile('somefile') | ||
35 | >>> # It is okay to lock twice from the same thread... | ||
36 | >>> with lock: | ||
37 | ... lock.acquire() | ||
38 | ... | ||
39 | >>> # Though no counter is kept, so you can't unlock multiple times... | ||
40 | >>> print lock.is_locked() | ||
41 | False | ||
42 | |||
43 | Exceptions: | ||
44 | |||
45 | Error - base class for other exceptions | ||
46 | LockError - base class for all locking exceptions | ||
47 | AlreadyLocked - Another thread or process already holds the lock | ||
48 | LockFailed - Lock failed for some other reason | ||
49 | UnlockError - base class for all unlocking exceptions | ||
50 | AlreadyUnlocked - File was not locked. | ||
51 | NotMyLock - File was locked but not by the current thread/process | ||
52 | """ | ||
53 | |||
54 | from __future__ import absolute_import | ||
55 | |||
56 | import functools | ||
57 | import os | ||
58 | import socket | ||
59 | import threading | ||
60 | import warnings | ||
61 | |||
62 | # Work with PEP8 and non-PEP8 versions of threading module. | ||
63 | if not hasattr(threading, "current_thread"): | ||
64 | threading.current_thread = threading.currentThread | ||
65 | if not hasattr(threading.Thread, "get_name"): | ||
66 | threading.Thread.get_name = threading.Thread.getName | ||
67 | |||
68 | __all__ = ['Error', 'LockError', 'LockTimeout', 'AlreadyLocked', | ||
69 | 'LockFailed', 'UnlockError', 'NotLocked', 'NotMyLock', | ||
70 | 'LinkFileLock', 'MkdirFileLock', 'SQLiteFileLock', | ||
71 | 'LockBase', 'locked'] | ||
72 | |||
73 | |||
74 | class Error(Exception): | ||
75 | """ | ||
76 | Base class for other exceptions. | ||
77 | |||
78 | >>> try: | ||
79 | ... raise Error | ||
80 | ... except Exception: | ||
81 | ... pass | ||
82 | """ | ||
83 | pass | ||
84 | |||
85 | |||
86 | class LockError(Error): | ||
87 | """ | ||
88 | Base class for error arising from attempts to acquire the lock. | ||
89 | |||
90 | >>> try: | ||
91 | ... raise LockError | ||
92 | ... except Error: | ||
93 | ... pass | ||
94 | """ | ||
95 | pass | ||
96 | |||
97 | |||
98 | class LockTimeout(LockError): | ||
99 | """Raised when lock creation fails within a user-defined period of time. | ||
100 | |||
101 | >>> try: | ||
102 | ... raise LockTimeout | ||
103 | ... except LockError: | ||
104 | ... pass | ||
105 | """ | ||
106 | pass | ||
107 | |||
108 | |||
109 | class AlreadyLocked(LockError): | ||
110 | """Some other thread/process is locking the file. | ||
111 | |||
112 | >>> try: | ||
113 | ... raise AlreadyLocked | ||
114 | ... except LockError: | ||
115 | ... pass | ||
116 | """ | ||
117 | pass | ||
118 | |||
119 | |||
120 | class LockFailed(LockError): | ||
121 | """Lock file creation failed for some other reason. | ||
122 | |||
123 | >>> try: | ||
124 | ... raise LockFailed | ||
125 | ... except LockError: | ||
126 | ... pass | ||
127 | """ | ||
128 | pass | ||
129 | |||
130 | |||
131 | class UnlockError(Error): | ||
132 | """ | ||
133 | Base class for errors arising from attempts to release the lock. | ||
134 | |||
135 | >>> try: | ||
136 | ... raise UnlockError | ||
137 | ... except Error: | ||
138 | ... pass | ||
139 | """ | ||
140 | pass | ||
141 | |||
142 | |||
143 | class NotLocked(UnlockError): | ||
144 | """Raised when an attempt is made to unlock an unlocked file. | ||
145 | |||
146 | >>> try: | ||
147 | ... raise NotLocked | ||
148 | ... except UnlockError: | ||
149 | ... pass | ||
150 | """ | ||
151 | pass | ||
152 | |||
153 | |||
154 | class NotMyLock(UnlockError): | ||
155 | """Raised when an attempt is made to unlock a file someone else locked. | ||
156 | |||
157 | >>> try: | ||
158 | ... raise NotMyLock | ||
159 | ... except UnlockError: | ||
160 | ... pass | ||
161 | """ | ||
162 | pass | ||
163 | |||
164 | |||
165 | class _SharedBase(object): | ||
166 | def __init__(self, path): | ||
167 | self.path = path | ||
168 | |||
169 | def acquire(self, timeout=None): | ||
170 | """ | ||
171 | Acquire the lock. | ||
172 | |||
173 | * If timeout is omitted (or None), wait forever trying to lock the | ||
174 | file. | ||
175 | |||
176 | * If timeout > 0, try to acquire the lock for that many seconds. If | ||
177 | the lock period expires and the file is still locked, raise | ||
178 | LockTimeout. | ||
179 | |||
180 | * If timeout <= 0, raise AlreadyLocked immediately if the file is | ||
181 | already locked. | ||
182 | """ | ||
183 | raise NotImplemented("implement in subclass") | ||
184 | |||
185 | def release(self): | ||
186 | """ | ||
187 | Release the lock. | ||
188 | |||
189 | If the file is not locked, raise NotLocked. | ||
190 | """ | ||
191 | raise NotImplemented("implement in subclass") | ||
192 | |||
193 | def __enter__(self): | ||
194 | """ | ||
195 | Context manager support. | ||
196 | """ | ||
197 | self.acquire() | ||
198 | return self | ||
199 | |||
200 | def __exit__(self, *_exc): | ||
201 | """ | ||
202 | Context manager support. | ||
203 | """ | ||
204 | self.release() | ||
205 | |||
206 | def __repr__(self): | ||
207 | return "<%s: %r>" % (self.__class__.__name__, self.path) | ||
208 | |||
209 | |||
210 | class LockBase(_SharedBase): | ||
211 | """Base class for platform-specific lock classes.""" | ||
212 | def __init__(self, path, threaded=True, timeout=None): | ||
213 | """ | ||
214 | >>> lock = LockBase('somefile') | ||
215 | >>> lock = LockBase('somefile', threaded=False) | ||
216 | """ | ||
217 | super(LockBase, self).__init__(path) | ||
218 | self.lock_file = os.path.abspath(path) + ".lock" | ||
219 | self.hostname = socket.gethostname() | ||
220 | self.pid = os.getpid() | ||
221 | if threaded: | ||
222 | t = threading.current_thread() | ||
223 | # Thread objects in Python 2.4 and earlier do not have ident | ||
224 | # attrs. Worm around that. | ||
225 | ident = getattr(t, "ident", hash(t)) | ||
226 | self.tname = "-%x" % (ident & 0xffffffff) | ||
227 | else: | ||
228 | self.tname = "" | ||
229 | dirname = os.path.dirname(self.lock_file) | ||
230 | |||
231 | # unique name is mostly about the current process, but must | ||
232 | # also contain the path -- otherwise, two adjacent locked | ||
233 | # files conflict (one file gets locked, creating lock-file and | ||
234 | # unique file, the other one gets locked, creating lock-file | ||
235 | # and overwriting the already existing lock-file, then one | ||
236 | # gets unlocked, deleting both lock-file and unique file, | ||
237 | # finally the last lock errors out upon releasing. | ||
238 | self.unique_name = os.path.join(dirname, | ||
239 | "%s%s.%s%s" % (self.hostname, | ||
240 | self.tname, | ||
241 | self.pid, | ||
242 | hash(self.path))) | ||
243 | self.timeout = timeout | ||
244 | |||
245 | def is_locked(self): | ||
246 | """ | ||
247 | Tell whether or not the file is locked. | ||
248 | """ | ||
249 | raise NotImplemented("implement in subclass") | ||
250 | |||
251 | def i_am_locking(self): | ||
252 | """ | ||
253 | Return True if this object is locking the file. | ||
254 | """ | ||
255 | raise NotImplemented("implement in subclass") | ||
256 | |||
257 | def break_lock(self): | ||
258 | """ | ||
259 | Remove a lock. Useful if a locking thread failed to unlock. | ||
260 | """ | ||
261 | raise NotImplemented("implement in subclass") | ||
262 | |||
263 | def __repr__(self): | ||
264 | return "<%s: %r -- %r>" % (self.__class__.__name__, self.unique_name, | ||
265 | self.path) | ||
266 | |||
267 | |||
268 | def _fl_helper(cls, mod, *args, **kwds): | ||
269 | warnings.warn("Import from %s module instead of lockfile package" % mod, | ||
270 | DeprecationWarning, stacklevel=2) | ||
271 | # This is a bit funky, but it's only for awhile. The way the unit tests | ||
272 | # are constructed this function winds up as an unbound method, so it | ||
273 | # actually takes three args, not two. We want to toss out self. | ||
274 | if not isinstance(args[0], str): | ||
275 | # We are testing, avoid the first arg | ||
276 | args = args[1:] | ||
277 | if len(args) == 1 and not kwds: | ||
278 | kwds["threaded"] = True | ||
279 | return cls(*args, **kwds) | ||
280 | |||
281 | |||
282 | def LinkFileLock(*args, **kwds): | ||
283 | """Factory function provided for backwards compatibility. | ||
284 | |||
285 | Do not use in new code. Instead, import LinkLockFile from the | ||
286 | lockfile.linklockfile module. | ||
287 | """ | ||
288 | from . import linklockfile | ||
289 | return _fl_helper(linklockfile.LinkLockFile, "lockfile.linklockfile", | ||
290 | *args, **kwds) | ||
291 | |||
292 | |||
293 | def MkdirFileLock(*args, **kwds): | ||
294 | """Factory function provided for backwards compatibility. | ||
295 | |||
296 | Do not use in new code. Instead, import MkdirLockFile from the | ||
297 | lockfile.mkdirlockfile module. | ||
298 | """ | ||
299 | from . import mkdirlockfile | ||
300 | return _fl_helper(mkdirlockfile.MkdirLockFile, "lockfile.mkdirlockfile", | ||
301 | *args, **kwds) | ||
302 | |||
303 | |||
304 | def SQLiteFileLock(*args, **kwds): | ||
305 | """Factory function provided for backwards compatibility. | ||
306 | |||
307 | Do not use in new code. Instead, import SQLiteLockFile from the | ||
308 | lockfile.mkdirlockfile module. | ||
309 | """ | ||
310 | from . import sqlitelockfile | ||
311 | return _fl_helper(sqlitelockfile.SQLiteLockFile, "lockfile.sqlitelockfile", | ||
312 | *args, **kwds) | ||
313 | |||
314 | |||
315 | def locked(path, timeout=None): | ||
316 | """Decorator which enables locks for decorated function. | ||
317 | |||
318 | Arguments: | ||
319 | - path: path for lockfile. | ||
320 | - timeout (optional): Timeout for acquiring lock. | ||
321 | |||
322 | Usage: | ||
323 | @locked('/var/run/myname', timeout=0) | ||
324 | def myname(...): | ||
325 | ... | ||
326 | """ | ||
327 | def decor(func): | ||
328 | @functools.wraps(func) | ||
329 | def wrapper(*args, **kwargs): | ||
330 | lock = FileLock(path, timeout=timeout) | ||
331 | lock.acquire() | ||
332 | try: | ||
333 | return func(*args, **kwargs) | ||
334 | finally: | ||
335 | lock.release() | ||
336 | return wrapper | ||
337 | return decor | ||
338 | |||
339 | |||
340 | if hasattr(os, "link"): | ||
341 | from . import linklockfile as _llf | ||
342 | LockFile = _llf.LinkLockFile | ||
343 | else: | ||
344 | from . import mkdirlockfile as _mlf | ||
345 | LockFile = _mlf.MkdirLockFile | ||
346 | |||
347 | FileLock = LockFile | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py new file mode 100644 index 0000000..11af0f3 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/linklockfile.py | |||
@@ -0,0 +1,73 @@ | |||
1 | from __future__ import absolute_import | ||
2 | |||
3 | import time | ||
4 | import os | ||
5 | |||
6 | from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, | ||
7 | AlreadyLocked) | ||
8 | |||
9 | |||
10 | class LinkLockFile(LockBase): | ||
11 | """Lock access to a file using atomic property of link(2). | ||
12 | |||
13 | >>> lock = LinkLockFile('somefile') | ||
14 | >>> lock = LinkLockFile('somefile', threaded=False) | ||
15 | """ | ||
16 | |||
17 | def acquire(self, timeout=None): | ||
18 | try: | ||
19 | open(self.unique_name, "wb").close() | ||
20 | except IOError: | ||
21 | raise LockFailed("failed to create %s" % self.unique_name) | ||
22 | |||
23 | timeout = timeout if timeout is not None else self.timeout | ||
24 | end_time = time.time() | ||
25 | if timeout is not None and timeout > 0: | ||
26 | end_time += timeout | ||
27 | |||
28 | while True: | ||
29 | # Try and create a hard link to it. | ||
30 | try: | ||
31 | os.link(self.unique_name, self.lock_file) | ||
32 | except OSError: | ||
33 | # Link creation failed. Maybe we've double-locked? | ||
34 | nlinks = os.stat(self.unique_name).st_nlink | ||
35 | if nlinks == 2: | ||
36 | # The original link plus the one I created == 2. We're | ||
37 | # good to go. | ||
38 | return | ||
39 | else: | ||
40 | # Otherwise the lock creation failed. | ||
41 | if timeout is not None and time.time() > end_time: | ||
42 | os.unlink(self.unique_name) | ||
43 | if timeout > 0: | ||
44 | raise LockTimeout("Timeout waiting to acquire" | ||
45 | " lock for %s" % | ||
46 | self.path) | ||
47 | else: | ||
48 | raise AlreadyLocked("%s is already locked" % | ||
49 | self.path) | ||
50 | time.sleep(timeout is not None and timeout / 10 or 0.1) | ||
51 | else: | ||
52 | # Link creation succeeded. We're good to go. | ||
53 | return | ||
54 | |||
55 | def release(self): | ||
56 | if not self.is_locked(): | ||
57 | raise NotLocked("%s is not locked" % self.path) | ||
58 | elif not os.path.exists(self.unique_name): | ||
59 | raise NotMyLock("%s is locked, but not by me" % self.path) | ||
60 | os.unlink(self.unique_name) | ||
61 | os.unlink(self.lock_file) | ||
62 | |||
63 | def is_locked(self): | ||
64 | return os.path.exists(self.lock_file) | ||
65 | |||
66 | def i_am_locking(self): | ||
67 | return (self.is_locked() and | ||
68 | os.path.exists(self.unique_name) and | ||
69 | os.stat(self.unique_name).st_nlink == 2) | ||
70 | |||
71 | def break_lock(self): | ||
72 | if os.path.exists(self.lock_file): | ||
73 | os.unlink(self.lock_file) | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py new file mode 100644 index 0000000..bd5a51e --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/mkdirlockfile.py | |||
@@ -0,0 +1,84 @@ | |||
1 | from __future__ import absolute_import, division | ||
2 | |||
3 | import time | ||
4 | import os | ||
5 | import sys | ||
6 | import errno | ||
7 | |||
8 | from . import (LockBase, LockFailed, NotLocked, NotMyLock, LockTimeout, | ||
9 | AlreadyLocked) | ||
10 | |||
11 | |||
12 | class MkdirLockFile(LockBase): | ||
13 | """Lock file by creating a directory.""" | ||
14 | def __init__(self, path, threaded=True, timeout=None): | ||
15 | """ | ||
16 | >>> lock = MkdirLockFile('somefile') | ||
17 | >>> lock = MkdirLockFile('somefile', threaded=False) | ||
18 | """ | ||
19 | LockBase.__init__(self, path, threaded, timeout) | ||
20 | # Lock file itself is a directory. Place the unique file name into | ||
21 | # it. | ||
22 | self.unique_name = os.path.join(self.lock_file, | ||
23 | "%s.%s%s" % (self.hostname, | ||
24 | self.tname, | ||
25 | self.pid)) | ||
26 | |||
27 | def acquire(self, timeout=None): | ||
28 | timeout = timeout if timeout is not None else self.timeout | ||
29 | end_time = time.time() | ||
30 | if timeout is not None and timeout > 0: | ||
31 | end_time += timeout | ||
32 | |||
33 | if timeout is None: | ||
34 | wait = 0.1 | ||
35 | else: | ||
36 | wait = max(0, timeout / 10) | ||
37 | |||
38 | while True: | ||
39 | try: | ||
40 | os.mkdir(self.lock_file) | ||
41 | except OSError: | ||
42 | err = sys.exc_info()[1] | ||
43 | if err.errno == errno.EEXIST: | ||
44 | # Already locked. | ||
45 | if os.path.exists(self.unique_name): | ||
46 | # Already locked by me. | ||
47 | return | ||
48 | if timeout is not None and time.time() > end_time: | ||
49 | if timeout > 0: | ||
50 | raise LockTimeout("Timeout waiting to acquire" | ||
51 | " lock for %s" % | ||
52 | self.path) | ||
53 | else: | ||
54 | # Someone else has the lock. | ||
55 | raise AlreadyLocked("%s is already locked" % | ||
56 | self.path) | ||
57 | time.sleep(wait) | ||
58 | else: | ||
59 | # Couldn't create the lock for some other reason | ||
60 | raise LockFailed("failed to create %s" % self.lock_file) | ||
61 | else: | ||
62 | open(self.unique_name, "wb").close() | ||
63 | return | ||
64 | |||
65 | def release(self): | ||
66 | if not self.is_locked(): | ||
67 | raise NotLocked("%s is not locked" % self.path) | ||
68 | elif not os.path.exists(self.unique_name): | ||
69 | raise NotMyLock("%s is locked, but not by me" % self.path) | ||
70 | os.unlink(self.unique_name) | ||
71 | os.rmdir(self.lock_file) | ||
72 | |||
73 | def is_locked(self): | ||
74 | return os.path.exists(self.lock_file) | ||
75 | |||
76 | def i_am_locking(self): | ||
77 | return (self.is_locked() and | ||
78 | os.path.exists(self.unique_name)) | ||
79 | |||
80 | def break_lock(self): | ||
81 | if os.path.exists(self.lock_file): | ||
82 | for name in os.listdir(self.lock_file): | ||
83 | os.unlink(os.path.join(self.lock_file, name)) | ||
84 | os.rmdir(self.lock_file) | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py new file mode 100644 index 0000000..d776de5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/pidlockfile.py | |||
@@ -0,0 +1,190 @@ | |||
1 | # -*- coding: utf-8 -*- | ||
2 | |||
3 | # pidlockfile.py | ||
4 | # | ||
5 | # Copyright © 2008–2009 Ben Finney <ben+python@benfinney.id.au> | ||
6 | # | ||
7 | # This is free software: you may copy, modify, and/or distribute this work | ||
8 | # under the terms of the Python Software Foundation License, version 2 or | ||
9 | # later as published by the Python Software Foundation. | ||
10 | # No warranty expressed or implied. See the file LICENSE.PSF-2 for details. | ||
11 | |||
12 | """ Lockfile behaviour implemented via Unix PID files. | ||
13 | """ | ||
14 | |||
15 | from __future__ import absolute_import | ||
16 | |||
17 | import errno | ||
18 | import os | ||
19 | import time | ||
20 | |||
21 | from . import (LockBase, AlreadyLocked, LockFailed, NotLocked, NotMyLock, | ||
22 | LockTimeout) | ||
23 | |||
24 | |||
25 | class PIDLockFile(LockBase): | ||
26 | """ Lockfile implemented as a Unix PID file. | ||
27 | |||
28 | The lock file is a normal file named by the attribute `path`. | ||
29 | A lock's PID file contains a single line of text, containing | ||
30 | the process ID (PID) of the process that acquired the lock. | ||
31 | |||
32 | >>> lock = PIDLockFile('somefile') | ||
33 | >>> lock = PIDLockFile('somefile') | ||
34 | """ | ||
35 | |||
36 | def __init__(self, path, threaded=False, timeout=None): | ||
37 | # pid lockfiles don't support threaded operation, so always force | ||
38 | # False as the threaded arg. | ||
39 | LockBase.__init__(self, path, False, timeout) | ||
40 | self.unique_name = self.path | ||
41 | |||
42 | def read_pid(self): | ||
43 | """ Get the PID from the lock file. | ||
44 | """ | ||
45 | return read_pid_from_pidfile(self.path) | ||
46 | |||
47 | def is_locked(self): | ||
48 | """ Test if the lock is currently held. | ||
49 | |||
50 | The lock is held if the PID file for this lock exists. | ||
51 | |||
52 | """ | ||
53 | return os.path.exists(self.path) | ||
54 | |||
55 | def i_am_locking(self): | ||
56 | """ Test if the lock is held by the current process. | ||
57 | |||
58 | Returns ``True`` if the current process ID matches the | ||
59 | number stored in the PID file. | ||
60 | """ | ||
61 | return self.is_locked() and os.getpid() == self.read_pid() | ||
62 | |||
63 | def acquire(self, timeout=None): | ||
64 | """ Acquire the lock. | ||
65 | |||
66 | Creates the PID file for this lock, or raises an error if | ||
67 | the lock could not be acquired. | ||
68 | """ | ||
69 | |||
70 | timeout = timeout if timeout is not None else self.timeout | ||
71 | end_time = time.time() | ||
72 | if timeout is not None and timeout > 0: | ||
73 | end_time += timeout | ||
74 | |||
75 | while True: | ||
76 | try: | ||
77 | write_pid_to_pidfile(self.path) | ||
78 | except OSError as exc: | ||
79 | if exc.errno == errno.EEXIST: | ||
80 | # The lock creation failed. Maybe sleep a bit. | ||
81 | if time.time() > end_time: | ||
82 | if timeout is not None and timeout > 0: | ||
83 | raise LockTimeout("Timeout waiting to acquire" | ||
84 | " lock for %s" % | ||
85 | self.path) | ||
86 | else: | ||
87 | raise AlreadyLocked("%s is already locked" % | ||
88 | self.path) | ||
89 | time.sleep(timeout is not None and timeout / 10 or 0.1) | ||
90 | else: | ||
91 | raise LockFailed("failed to create %s" % self.path) | ||
92 | else: | ||
93 | return | ||
94 | |||
95 | def release(self): | ||
96 | """ Release the lock. | ||
97 | |||
98 | Removes the PID file to release the lock, or raises an | ||
99 | error if the current process does not hold the lock. | ||
100 | |||
101 | """ | ||
102 | if not self.is_locked(): | ||
103 | raise NotLocked("%s is not locked" % self.path) | ||
104 | if not self.i_am_locking(): | ||
105 | raise NotMyLock("%s is locked, but not by me" % self.path) | ||
106 | remove_existing_pidfile(self.path) | ||
107 | |||
108 | def break_lock(self): | ||
109 | """ Break an existing lock. | ||
110 | |||
111 | Removes the PID file if it already exists, otherwise does | ||
112 | nothing. | ||
113 | |||
114 | """ | ||
115 | remove_existing_pidfile(self.path) | ||
116 | |||
117 | |||
118 | def read_pid_from_pidfile(pidfile_path): | ||
119 | """ Read the PID recorded in the named PID file. | ||
120 | |||
121 | Read and return the numeric PID recorded as text in the named | ||
122 | PID file. If the PID file cannot be read, or if the content is | ||
123 | not a valid PID, return ``None``. | ||
124 | |||
125 | """ | ||
126 | pid = None | ||
127 | try: | ||
128 | pidfile = open(pidfile_path, 'r') | ||
129 | except IOError: | ||
130 | pass | ||
131 | else: | ||
132 | # According to the FHS 2.3 section on PID files in /var/run: | ||
133 | # | ||
134 | # The file must consist of the process identifier in | ||
135 | # ASCII-encoded decimal, followed by a newline character. | ||
136 | # | ||
137 | # Programs that read PID files should be somewhat flexible | ||
138 | # in what they accept; i.e., they should ignore extra | ||
139 | # whitespace, leading zeroes, absence of the trailing | ||
140 | # newline, or additional lines in the PID file. | ||
141 | |||
142 | line = pidfile.readline().strip() | ||
143 | try: | ||
144 | pid = int(line) | ||
145 | except ValueError: | ||
146 | pass | ||
147 | pidfile.close() | ||
148 | |||
149 | return pid | ||
150 | |||
151 | |||
152 | def write_pid_to_pidfile(pidfile_path): | ||
153 | """ Write the PID in the named PID file. | ||
154 | |||
155 | Get the numeric process ID (“PID”) of the current process | ||
156 | and write it to the named file as a line of text. | ||
157 | |||
158 | """ | ||
159 | open_flags = (os.O_CREAT | os.O_EXCL | os.O_WRONLY) | ||
160 | open_mode = 0o644 | ||
161 | pidfile_fd = os.open(pidfile_path, open_flags, open_mode) | ||
162 | pidfile = os.fdopen(pidfile_fd, 'w') | ||
163 | |||
164 | # According to the FHS 2.3 section on PID files in /var/run: | ||
165 | # | ||
166 | # The file must consist of the process identifier in | ||
167 | # ASCII-encoded decimal, followed by a newline character. For | ||
168 | # example, if crond was process number 25, /var/run/crond.pid | ||
169 | # would contain three characters: two, five, and newline. | ||
170 | |||
171 | pid = os.getpid() | ||
172 | pidfile.write("%s\n" % pid) | ||
173 | pidfile.close() | ||
174 | |||
175 | |||
176 | def remove_existing_pidfile(pidfile_path): | ||
177 | """ Remove the named PID file if it exists. | ||
178 | |||
179 | Removing a PID file that doesn't already exist puts us in the | ||
180 | desired state, so we ignore the condition if the file does not | ||
181 | exist. | ||
182 | |||
183 | """ | ||
184 | try: | ||
185 | os.remove(pidfile_path) | ||
186 | except OSError as exc: | ||
187 | if exc.errno == errno.ENOENT: | ||
188 | pass | ||
189 | else: | ||
190 | raise | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py new file mode 100644 index 0000000..278dff4 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/sqlitelockfile.py | |||
@@ -0,0 +1,156 @@ | |||
1 | from __future__ import absolute_import, division | ||
2 | |||
3 | import time | ||
4 | import os | ||
5 | |||
6 | try: | ||
7 | unicode | ||
8 | except NameError: | ||
9 | unicode = str | ||
10 | |||
11 | from . import LockBase, NotLocked, NotMyLock, LockTimeout, AlreadyLocked | ||
12 | |||
13 | |||
14 | class SQLiteLockFile(LockBase): | ||
15 | "Demonstrate SQL-based locking." | ||
16 | |||
17 | testdb = None | ||
18 | |||
19 | def __init__(self, path, threaded=True, timeout=None): | ||
20 | """ | ||
21 | >>> lock = SQLiteLockFile('somefile') | ||
22 | >>> lock = SQLiteLockFile('somefile', threaded=False) | ||
23 | """ | ||
24 | LockBase.__init__(self, path, threaded, timeout) | ||
25 | self.lock_file = unicode(self.lock_file) | ||
26 | self.unique_name = unicode(self.unique_name) | ||
27 | |||
28 | if SQLiteLockFile.testdb is None: | ||
29 | import tempfile | ||
30 | _fd, testdb = tempfile.mkstemp() | ||
31 | os.close(_fd) | ||
32 | os.unlink(testdb) | ||
33 | del _fd, tempfile | ||
34 | SQLiteLockFile.testdb = testdb | ||
35 | |||
36 | import sqlite3 | ||
37 | self.connection = sqlite3.connect(SQLiteLockFile.testdb) | ||
38 | |||
39 | c = self.connection.cursor() | ||
40 | try: | ||
41 | c.execute("create table locks" | ||
42 | "(" | ||
43 | " lock_file varchar(32)," | ||
44 | " unique_name varchar(32)" | ||
45 | ")") | ||
46 | except sqlite3.OperationalError: | ||
47 | pass | ||
48 | else: | ||
49 | self.connection.commit() | ||
50 | import atexit | ||
51 | atexit.register(os.unlink, SQLiteLockFile.testdb) | ||
52 | |||
53 | def acquire(self, timeout=None): | ||
54 | timeout = timeout if timeout is not None else self.timeout | ||
55 | end_time = time.time() | ||
56 | if timeout is not None and timeout > 0: | ||
57 | end_time += timeout | ||
58 | |||
59 | if timeout is None: | ||
60 | wait = 0.1 | ||
61 | elif timeout <= 0: | ||
62 | wait = 0 | ||
63 | else: | ||
64 | wait = timeout / 10 | ||
65 | |||
66 | cursor = self.connection.cursor() | ||
67 | |||
68 | while True: | ||
69 | if not self.is_locked(): | ||
70 | # Not locked. Try to lock it. | ||
71 | cursor.execute("insert into locks" | ||
72 | " (lock_file, unique_name)" | ||
73 | " values" | ||
74 | " (?, ?)", | ||
75 | (self.lock_file, self.unique_name)) | ||
76 | self.connection.commit() | ||
77 | |||
78 | # Check to see if we are the only lock holder. | ||
79 | cursor.execute("select * from locks" | ||
80 | " where unique_name = ?", | ||
81 | (self.unique_name,)) | ||
82 | rows = cursor.fetchall() | ||
83 | if len(rows) > 1: | ||
84 | # Nope. Someone else got there. Remove our lock. | ||
85 | cursor.execute("delete from locks" | ||
86 | " where unique_name = ?", | ||
87 | (self.unique_name,)) | ||
88 | self.connection.commit() | ||
89 | else: | ||
90 | # Yup. We're done, so go home. | ||
91 | return | ||
92 | else: | ||
93 | # Check to see if we are the only lock holder. | ||
94 | cursor.execute("select * from locks" | ||
95 | " where unique_name = ?", | ||
96 | (self.unique_name,)) | ||
97 | rows = cursor.fetchall() | ||
98 | if len(rows) == 1: | ||
99 | # We're the locker, so go home. | ||
100 | return | ||
101 | |||
102 | # Maybe we should wait a bit longer. | ||
103 | if timeout is not None and time.time() > end_time: | ||
104 | if timeout > 0: | ||
105 | # No more waiting. | ||
106 | raise LockTimeout("Timeout waiting to acquire" | ||
107 | " lock for %s" % | ||
108 | self.path) | ||
109 | else: | ||
110 | # Someone else has the lock and we are impatient.. | ||
111 | raise AlreadyLocked("%s is already locked" % self.path) | ||
112 | |||
113 | # Well, okay. We'll give it a bit longer. | ||
114 | time.sleep(wait) | ||
115 | |||
116 | def release(self): | ||
117 | if not self.is_locked(): | ||
118 | raise NotLocked("%s is not locked" % self.path) | ||
119 | if not self.i_am_locking(): | ||
120 | raise NotMyLock("%s is locked, but not by me (by %s)" % | ||
121 | (self.unique_name, self._who_is_locking())) | ||
122 | cursor = self.connection.cursor() | ||
123 | cursor.execute("delete from locks" | ||
124 | " where unique_name = ?", | ||
125 | (self.unique_name,)) | ||
126 | self.connection.commit() | ||
127 | |||
128 | def _who_is_locking(self): | ||
129 | cursor = self.connection.cursor() | ||
130 | cursor.execute("select unique_name from locks" | ||
131 | " where lock_file = ?", | ||
132 | (self.lock_file,)) | ||
133 | return cursor.fetchone()[0] | ||
134 | |||
135 | def is_locked(self): | ||
136 | cursor = self.connection.cursor() | ||
137 | cursor.execute("select * from locks" | ||
138 | " where lock_file = ?", | ||
139 | (self.lock_file,)) | ||
140 | rows = cursor.fetchall() | ||
141 | return not not rows | ||
142 | |||
143 | def i_am_locking(self): | ||
144 | cursor = self.connection.cursor() | ||
145 | cursor.execute("select * from locks" | ||
146 | " where lock_file = ?" | ||
147 | " and unique_name = ?", | ||
148 | (self.lock_file, self.unique_name)) | ||
149 | return not not cursor.fetchall() | ||
150 | |||
151 | def break_lock(self): | ||
152 | cursor = self.connection.cursor() | ||
153 | cursor.execute("delete from locks" | ||
154 | " where lock_file = ?", | ||
155 | (self.lock_file,)) | ||
156 | self.connection.commit() | ||
diff --git a/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py new file mode 100644 index 0000000..93ff2b5 --- /dev/null +++ b/venv/lib/python3.7/site-packages/pip-10.0.1-py3.7.egg/pip/_vendor/lockfile/symlinklockfile.py | |||
@@ -0,0 +1,70 @@ | |||
1 | from __future__ import absolute_import | ||
2 | |||
3 | import os | ||
4 | import time | ||
5 | |||
6 | from . import (LockBase, NotLocked, NotMyLock, LockTimeout, | ||
7 | AlreadyLocked) | ||
8 | |||
9 | |||
10 | class SymlinkLockFile(LockBase): | ||
11 | """Lock access to a file using symlink(2).""" | ||
12 | |||
13 | def __init__(self, path, threaded=True, timeout=None): | ||
14 | # super(SymlinkLockFile).__init(...) | ||
15 | LockBase.__init__(self, path, threaded, timeout) | ||
16 | # split it back! | ||
17 | self.unique_name = os.path.split(self.unique_name)[1] | ||
18 | |||
19 | def acquire(self, timeout=None): | ||
20 | # Hopefully unnecessary for symlink. | ||
21 | # try: | ||
22 | # open(self.unique_name, "wb").close() | ||
23 | # except IOError: | ||
24 | # raise LockFailed("failed to create %s" % self.unique_name) | ||
25 | timeout = timeout if timeout is not None else self.timeout | ||
26 | end_time = time.time() | ||
27 | if timeout is not None and timeout > 0: | ||
28 | end_time += timeout | ||
29 | |||
30 | while True: | ||
31 | # Try and create a symbolic link to it. | ||
32 | try: | ||
33 | os.symlink(self.unique_name, self.lock_file) | ||
34 | except OSError: | ||
35 | # Link creation failed. Maybe we've double-locked? | ||
36 | if self.i_am_locking(): | ||
37 | # Linked to out unique name. Proceed. | ||
38 | return | ||
39 | else: | ||
40 | # Otherwise the lock creation failed. | ||
41 | if timeout is not None and time.time() > end_time: | ||
42 | if timeout > 0: | ||
43 | raise LockTimeout("Timeout waiting to acquire" | ||
44 | " lock for %s" % | ||
45 | self.path) | ||
46 | else: | ||
47 | raise AlreadyLocked("%s is already locked" % | ||
48 | self.path) | ||
49 | time.sleep(timeout / 10 if timeout is not None else 0.1) | ||
50 | else: | ||
51 | # Link creation succeeded. We're good to go. | ||
52 | return | ||
53 | |||
54 | def release(self): | ||
55 | if not self.is_locked(): | ||
56 | raise NotLocked("%s is not locked" % self.path) | ||
57 | elif not self.i_am_locking(): | ||
58 | raise NotMyLock("%s is locked, but not by me" % self.path) | ||
59 | os.unlink(self.lock_file) | ||
60 | |||
61 | def is_locked(self): | ||
62 | return os.path.islink(self.lock_file) | ||
63 | |||
64 | def i_am_locking(self): | ||
65 | return (os.path.islink(self.lock_file) | ||
66 | and os.readlink(self.lock_file) == self.unique_name) | ||
67 | |||
68 | def break_lock(self): | ||
69 | if os.path.islink(self.lock_file): # exists && link | ||
70 | os.unlink(self.lock_file) | ||