1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
Obtained from: https://github.com/pimutils/vdirsyncer/commit/8b063c39cb3e26a2beef5b6beed7e99c9e9641ac
--- setup.py.orig 2024-09-11 15:26:58 UTC
+++ setup.py
@@ -16,8 +16,6 @@ requirements = [
"click>=5.0,<9.0",
"click-log>=0.3.0, <0.5.0",
"requests >=2.20.0",
- # https://github.com/untitaker/python-atomicwrites/commit/4d12f23227b6a944ab1d99c507a69fdbc7c9ed6d # noqa
- "atomicwrites>=0.1.7",
"aiohttp>=3.8.0,<4.0.0",
"aiostream>=0.4.3,<0.5.0",
]
--- vdirsyncer/cli/utils.py.orig 2024-09-11 15:26:58 UTC
+++ vdirsyncer/cli/utils.py
@@ -10,7 +10,6 @@ import click
import aiohttp
import click
-from atomicwrites import atomic_write
from .. import BUGTRACKER_HOME
from .. import DOCS_HOME
@@ -21,6 +20,7 @@ from ..sync.status import SqliteStatus
from ..sync.exceptions import StorageEmpty
from ..sync.exceptions import SyncConflict
from ..sync.status import SqliteStatus
+from ..utils import atomic_write
from ..utils import expand_path
from ..utils import get_storage_init_args
from . import cli_logger
--- vdirsyncer/storage/filesystem.py.orig 2024-09-11 15:26:58 UTC
+++ vdirsyncer/storage/filesystem.py
@@ -5,9 +5,8 @@ import subprocess
import os
import subprocess
-from atomicwrites import atomic_write
-
from .. import exceptions
+from ..utils import atomic_write
from ..utils import checkdir
from ..utils import expand_path
from ..utils import generate_href
--- vdirsyncer/storage/google.py.orig 2024-09-11 15:26:58 UTC
+++ vdirsyncer/storage/google.py
@@ -11,9 +11,9 @@ import click
import aiohttp
import click
-from atomicwrites import atomic_write
from .. import exceptions
+from ..utils import atomic_write
from ..utils import checkdir
from ..utils import expand_path
from ..utils import open_graphical_browser
--- vdirsyncer/storage/singlefile.py.orig 2024-09-11 15:26:58 UTC
+++ vdirsyncer/storage/singlefile.py
@@ -8,9 +8,8 @@ from typing import Iterable
import os
from typing import Iterable
-from atomicwrites import atomic_write
-
from .. import exceptions
+from ..utils import atomic_write
from ..utils import checkfile
from ..utils import expand_path
from ..utils import get_etag_from_file
--- vdirsyncer/utils.py.orig 2024-09-11 15:26:58 UTC
+++ vdirsyncer/utils.py
@@ -1,8 +1,10 @@ from __future__ import annotations
from __future__ import annotations
+import contextlib
import functools
import os
import sys
+import tempfile
import uuid
from inspect import getfullargspec
from typing import Callable
@@ -220,3 +222,27 @@ def open_graphical_browser(url, new=0, autoraise=True)
return
raise RuntimeError("No graphical browser found. Please open the URL " "manually.")
+
+
+@contextlib.contextmanager
+def atomic_write(dest, mode="wb", overwrite=False):
+ if "w" not in mode:
+ raise RuntimeError("`atomic_write` requires write access")
+
+ fd, src = tempfile.mkstemp(prefix=os.path.basename(dest), dir=os.path.dirname(dest))
+ file = os.fdopen(fd, mode=mode)
+
+ try:
+ yield file
+ except Exception:
+ os.unlink(src)
+ raise
+ else:
+ file.flush()
+ file.close()
+
+ if overwrite:
+ os.rename(src, dest)
+ else:
+ os.link(src, dest)
+ os.unlink(src)
|