duplicity 3.0.8.dev3__tar.gz → 3.0.8.dev6__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (145) hide show
  1. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/AUTHORS.md +1 -1
  2. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/CHANGELOG.md +37 -1
  3. {duplicity-3.0.8.dev3/duplicity.egg-info → duplicity-3.0.8.dev6}/PKG-INFO +3 -4
  4. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/__init__.py +3 -3
  5. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/__main__.py +5 -3
  6. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/_librsyncmodule.c +4 -46
  7. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backend.py +1 -1
  8. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backend_pool.py +1 -1
  9. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/__init__.py +1 -1
  10. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/_cf_cloudfiles.py +3 -5
  11. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/_cf_pyrax.py +3 -5
  12. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/_testbackend.py +7 -8
  13. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/adbackend.py +1 -1
  14. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/azurebackend.py +1 -1
  15. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/b2backend.py +3 -2
  16. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/boxbackend.py +1 -1
  17. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/cfbackend.py +1 -1
  18. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/dpbxbackend.py +3 -5
  19. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/gdocsbackend.py +1 -1
  20. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/gdrivebackend.py +3 -5
  21. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/giobackend.py +1 -1
  22. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/hsibackend.py +1 -1
  23. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/hubicbackend.py +3 -5
  24. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/idrivedbackend.py +1 -2
  25. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/imapbackend.py +7 -7
  26. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/jottacloudbackend.py +1 -1
  27. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/lftpbackend.py +1 -1
  28. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/localbackend.py +1 -1
  29. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/mediafirebackend.py +3 -5
  30. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/megabackend.py +1 -1
  31. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/megav2backend.py +1 -1
  32. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/megav3backend.py +1 -1
  33. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/multibackend.py +1 -1
  34. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/ncftpbackend.py +1 -1
  35. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/onedrivebackend.py +7 -8
  36. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/par2backend.py +1 -1
  37. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/pcabackend.py +3 -5
  38. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/pydrivebackend.py +1 -1
  39. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/pyrax_identity/__init__.py +1 -1
  40. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/pyrax_identity/hubic.py +3 -5
  41. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/rclonebackend.py +5 -3
  42. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/rsyncbackend.py +2 -2
  43. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/s3_boto3_backend.py +8 -7
  44. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/slatebackend.py +3 -5
  45. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/ssh_paramiko_backend.py +3 -5
  46. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/ssh_pexpect_backend.py +3 -5
  47. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/swiftbackend.py +3 -5
  48. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/sxbackend.py +1 -1
  49. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/tahoebackend.py +1 -1
  50. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/webdavbackend.py +14 -24
  51. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/backends/xorrisobackend.py +1 -1
  52. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/cached_ops.py +1 -1
  53. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/cli_data.py +8 -5
  54. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/cli_main.py +8 -22
  55. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/cli_util.py +3 -9
  56. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/config.py +5 -1
  57. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/diffdir.py +2 -1
  58. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/dup_collections.py +1 -1
  59. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/dup_main.py +18 -12
  60. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/dup_tarfile.py +1 -1
  61. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/dup_temp.py +1 -1
  62. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/dup_time.py +5 -9
  63. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/errors.py +1 -1
  64. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/filechunkio.py +1 -1
  65. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/globmatch.py +1 -1
  66. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/gpg.py +1 -1
  67. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/gpginterface.py +1 -1
  68. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/lazy.py +1 -1
  69. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/librsync.py +1 -1
  70. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/log.py +1 -1
  71. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/manifest.py +1 -1
  72. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/patchdir.py +2 -1
  73. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/path.py +1 -15
  74. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/progress.py +1 -1
  75. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/robust.py +1 -1
  76. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/selection.py +13 -42
  77. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/statistics.py +1 -1
  78. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/tempdir.py +1 -1
  79. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/util.py +1 -1
  80. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6/duplicity.egg-info}/PKG-INFO +3 -4
  81. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity.egg-info/SOURCES.txt +0 -1
  82. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity.egg-info/requires.txt +1 -1
  83. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/man/duplicity.1 +8 -1
  84. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/af_ZA/duplicity.mo +0 -0
  85. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ar_SA/duplicity.mo +0 -0
  86. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ca_ES/duplicity.mo +0 -0
  87. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/cs_CZ/duplicity.mo +0 -0
  88. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/da_DK/duplicity.mo +0 -0
  89. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/de_AT/duplicity.mo +0 -0
  90. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/de_DE/duplicity.mo +0 -0
  91. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/el_GR/duplicity.mo +0 -0
  92. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/en_AU/duplicity.mo +0 -0
  93. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/en_GB/duplicity.mo +0 -0
  94. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/en_PR/duplicity.mo +0 -0
  95. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/en_US/duplicity.mo +0 -0
  96. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/es_EM/duplicity.mo +0 -0
  97. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/es_ES/duplicity.mo +0 -0
  98. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/es_MX/duplicity.mo +0 -0
  99. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/es_PR/duplicity.mo +0 -0
  100. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/es_US/duplicity.mo +0 -0
  101. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/fi_FI/duplicity.mo +0 -0
  102. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/fr_FR/duplicity.mo +0 -0
  103. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/he_IL/duplicity.mo +0 -0
  104. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/hu_HU/duplicity.mo +0 -0
  105. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/it_IT/duplicity.mo +0 -0
  106. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ja_JP/duplicity.mo +0 -0
  107. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ko_KR/duplicity.mo +0 -0
  108. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/nl_BE/duplicity.mo +0 -0
  109. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/nl_NL/duplicity.mo +0 -0
  110. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/nl_SR/duplicity.mo +0 -0
  111. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/no_NO/duplicity.mo +0 -0
  112. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/pl_PL/duplicity.mo +0 -0
  113. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/pt_BR/duplicity.mo +0 -0
  114. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/pt_PT/duplicity.mo +0 -0
  115. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ro_RO/duplicity.mo +0 -0
  116. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ru_BY/duplicity.mo +0 -0
  117. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ru_MD/duplicity.mo +0 -0
  118. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ru_RU/duplicity.mo +0 -0
  119. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/ru_UA/duplicity.mo +0 -0
  120. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/sr_SP/duplicity.mo +0 -0
  121. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/sv_SE/duplicity.mo +0 -0
  122. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/tr_TR/duplicity.mo +0 -0
  123. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/uk_UA/duplicity.mo +0 -0
  124. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/vi_VN/duplicity.mo +0 -0
  125. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/zh_CN/duplicity.mo +0 -0
  126. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/zh_HK/duplicity.mo +0 -0
  127. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/zh_MO/duplicity.mo +0 -0
  128. duplicity-3.0.8.dev6/po/zh_SG/duplicity.mo +0 -0
  129. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/po/zh_TW/duplicity.mo +0 -0
  130. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/pyproject.toml +28 -34
  131. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/requirements.txt +2 -2
  132. duplicity-3.0.8.dev6/setup.cfg +4 -0
  133. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/setup.py +6 -10
  134. duplicity-3.0.8.dev3/po/zh_SG/duplicity.mo +0 -0
  135. duplicity-3.0.8.dev3/setup.cfg +0 -8
  136. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/COPYING +0 -0
  137. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/README-LOG.md +0 -0
  138. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/README-REPO.md +0 -0
  139. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/README-TESTING.md +0 -0
  140. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/README.md +0 -0
  141. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/argparse311.py +0 -0
  142. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity/file_naming.py +0 -0
  143. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity.egg-info/dependency_links.txt +0 -0
  144. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity.egg-info/entry_points.txt +0 -0
  145. {duplicity-3.0.8.dev3 → duplicity-3.0.8.dev6}/duplicity.egg-info/top_level.txt +0 -0
@@ -32,7 +32,7 @@ Duplicity Authors
32
32
  - Stefan Breunig <stefan-duplicity@breunig.xyz>
33
33
  - Steve Tynor <steve.tynor@gmail.com>
34
34
  - Thomas Harning Jr <harningt@gmail.com>
35
- - Thomas Laubrock
35
+ - Thomas Laubrock <duplicity-talk@schmu.net>
36
36
  - Tomas Vondra (Launchpad id: tomas-v)
37
37
  - Xavier Lucas <xavier.lucas@corp.ovh.com>
38
38
  - Yigal Asnis
@@ -1,9 +1,45 @@
1
1
 
2
- (Unreleased) / 2025-12-31
2
+ (Unreleased) / 2026-05-12
3
3
  =========================
4
4
 
5
5
 
6
6
 
7
+ rel.3.0.8.dev5 / 2026-05-12
8
+ ===========================
9
+
10
+ * 3997156c:chg: Update README-RELEASE.md.
11
+ * 0f5430db:fix: Fix so GNUPGHOME is not changed in production.
12
+ * 53cc9659:fix: lower boto warning log level, rephrase.
13
+ * 88bfc75e:chg: Misc cleanups for developers
14
+ * 4b0bb8d5:chg: Update 'release pip version' in README-RELEASE.md.
15
+
16
+ rel.3.0.8.dev4 / 2026-03-31
17
+ ===========================
18
+
19
+ * c17b03bc:fix: try/except block masking real S3UploadFailedError
20
+ * db127ce5:new: Add --full-if-n-inc flag for count-based full backup.
21
+ * dc977419:fix: Simplify swig module definition.
22
+ * 0de30e69:chg: Adjust to newer sphinx.
23
+ * c1883117:fix: Add templates for bug and feature requests.
24
+ * 39150d34:fix: delete unused Path.patch_with_attribs.
25
+ * 1a7c6790:fix: Remove support for Python 2.
26
+ * 564dd593:fix: fix flag name --gpg-agent -> --use-agent.
27
+ * 866680d0:chg: Multiple changes for 2026 are planned
28
+ * 29e00b55:fix: Fix incompatibility with Python 3.14.
29
+ * 50faabfc:chg: Partial fix for #924.
30
+ * 00ae7687:fix: webdav, always send warmup OPTIONS request, prevent loop
31
+ * 37841a0e:fix: Handle local version identifiers in b2backend
32
+
33
+ rel.3.0.8.dev3 / 2026-01-14
34
+ ===========================
35
+
36
+ * 3475dd05:fix: Unnecessary passphrase prompt with --encrypt-key --no-check-remote.
37
+ * b8508f6d:chg: Remove slow marker from tests.
38
+
39
+ rel.3.0.8.dev2 / 2026-01-14
40
+ ===========================
41
+
42
+
7
43
  rel.3.0.7 / 2025-12-31
8
44
  ======================
9
45
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: duplicity
3
- Version: 3.0.8.dev3
3
+ Version: 3.0.8.dev6
4
4
  Summary: Encrypted backup using rsync algorithm
5
5
  Author-email: Kenneth Loafman <kenneth@loafman.com>
6
6
  Maintainer: Edgar Soldin, Thomas Laubrock
@@ -18,14 +18,13 @@ Classifier: Operating System :: MacOS
18
18
  Classifier: Operating System :: POSIX
19
19
  Classifier: Programming Language :: C
20
20
  Classifier: Programming Language :: Python :: 3
21
- Classifier: Programming Language :: Python :: 3.9
22
21
  Classifier: Programming Language :: Python :: 3.10
23
22
  Classifier: Programming Language :: Python :: 3.11
24
23
  Classifier: Programming Language :: Python :: 3.12
25
24
  Classifier: Programming Language :: Python :: 3.13
26
25
  Classifier: Programming Language :: Python :: 3.14
27
26
  Classifier: Topic :: System :: Archiving :: Backup
28
- Requires-Python: <3.15,>3.8
27
+ Requires-Python: >=3.10
29
28
  Description-Content-Type: text/markdown
30
29
  License-File: COPYING
31
30
  License-File: AUTHORS.md
@@ -45,7 +44,7 @@ Requires-Dist: httplib2
45
44
  Requires-Dist: pysocks
46
45
  Requires-Dist: jottalib
47
46
  Requires-Dist: keyring
48
- Requires-Dist: lxml<=5.4.0
47
+ Requires-Dist: lxml
49
48
  Requires-Dist: mediafire
50
49
  Requires-Dist: megatools
51
50
  Requires-Dist: paramiko
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -21,7 +21,7 @@
21
21
 
22
22
  import gettext
23
23
 
24
- __version__: str = "3.0.8.dev3"
25
- __reldate__: str = "January 14, 2026"
24
+ __version__: str = "3.0.8.dev6"
25
+ __reldate__: str = "May 12, 2026"
26
26
 
27
27
  gettext.install("duplicity", names=["ngettext"])
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env python3
2
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
2
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
3
3
  #
4
4
  # duplicity -- Encrypted bandwidth efficient backup
5
5
  #
@@ -62,8 +62,10 @@ def dup_run():
62
62
  # check that we can function here
63
63
  if os.environ.get("PYTEST_VERSION") is not None:
64
64
  pass
65
- elif not ((3, 9) <= sys.version_info[:2] <= (3, 14)):
66
- print("Sorry, duplicity requires version 3.9 thru 3.14 of Python.", file=sys.stderr)
65
+ elif os.environ.get("CIBUILDWHEEL") is not None:
66
+ pass
67
+ elif not ((3, 10) <= sys.version_info[:2] <= (3, 14)):
68
+ print("Sorry, duplicity requires Python version 3.10 thru 3.14.", file=sys.stderr)
67
69
  sys.exit(1)
68
70
 
69
71
  try:
@@ -90,11 +90,7 @@ _librsync_sigmaker_cycle(_librsync_SigMakerObject *self, PyObject *args)
90
90
  rs_buffers_t buf;
91
91
  rs_result result;
92
92
 
93
- #if PY_MAJOR_VERSION >= 3
94
93
  if (!PyArg_ParseTuple(args, "y#:cycle", &inbuf, &inbuf_length))
95
- #else
96
- if (!PyArg_ParseTuple(args, "s#:cycle", &inbuf, &inbuf_length))
97
- #endif
98
94
  return NULL;
99
95
 
100
96
  buf.next_in = inbuf;
@@ -110,11 +106,7 @@ _librsync_sigmaker_cycle(_librsync_SigMakerObject *self, PyObject *args)
110
106
  return NULL;
111
107
  }
112
108
 
113
- #if PY_MAJOR_VERSION >= 3
114
109
  return Py_BuildValue("(ily#)", (result == RS_DONE),
115
- #else
116
- return Py_BuildValue("(ils#)", (result == RS_DONE),
117
- #endif
118
110
  (long)inbuf_length - (long)buf.avail_in,
119
111
  outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out);
120
112
  }
@@ -178,11 +170,7 @@ _librsync_new_deltamaker(PyObject* self, PyObject* args)
178
170
  rs_buffers_t buf;
179
171
  rs_result result;
180
172
 
181
- #if PY_MAJOR_VERSION >= 3
182
173
  if (!PyArg_ParseTuple(args,"y#:new_deltamaker", &sig_string, &sig_length))
183
- #else
184
- if (!PyArg_ParseTuple(args,"s#:new_deltamaker", &sig_string, &sig_length))
185
- #endif
186
174
  return NULL;
187
175
 
188
176
  dm = PyObject_New(_librsync_DeltaMakerObject, &_librsync_DeltaMakerType);
@@ -237,11 +225,7 @@ _librsync_deltamaker_cycle(_librsync_DeltaMakerObject *self, PyObject *args)
237
225
  rs_buffers_t buf;
238
226
  rs_result result;
239
227
 
240
- #if PY_MAJOR_VERSION >= 3
241
228
  if (!PyArg_ParseTuple(args, "y#:cycle", &inbuf, &inbuf_length))
242
- #else
243
- if (!PyArg_ParseTuple(args, "s#:cycle", &inbuf, &inbuf_length))
244
- #endif
245
229
  return NULL;
246
230
 
247
231
  buf.next_in = inbuf;
@@ -256,11 +240,7 @@ _librsync_deltamaker_cycle(_librsync_DeltaMakerObject *self, PyObject *args)
256
240
  return NULL;
257
241
  }
258
242
 
259
- #if PY_MAJOR_VERSION >= 3
260
243
  return Py_BuildValue("(ily#)", (result == RS_DONE),
261
- #else
262
- return Py_BuildValue("(ils#)", (result == RS_DONE),
263
- #endif
264
244
  (long)inbuf_length - (long)buf.avail_in,
265
245
  outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out);
266
246
  }
@@ -374,11 +354,7 @@ _librsync_patchmaker_cycle(_librsync_PatchMakerObject *self, PyObject *args)
374
354
  rs_buffers_t buf;
375
355
  rs_result result;
376
356
 
377
- #if PY_MAJOR_VERSION >= 3
378
357
  if (!PyArg_ParseTuple(args, "y#:cycle", &inbuf, &inbuf_length))
379
- #else
380
- if (!PyArg_ParseTuple(args, "s#:cycle", &inbuf, &inbuf_length))
381
- #endif
382
358
  return NULL;
383
359
 
384
360
  buf.next_in = inbuf;
@@ -393,11 +369,7 @@ _librsync_patchmaker_cycle(_librsync_PatchMakerObject *self, PyObject *args)
393
369
  return NULL;
394
370
  }
395
371
 
396
- #if PY_MAJOR_VERSION >= 3
397
372
  return Py_BuildValue("(ily#)", (result == RS_DONE),
398
- #else
399
- return Py_BuildValue("(ils#)", (result == RS_DONE),
400
- #endif
401
373
  (long)inbuf_length - (long)buf.avail_in,
402
374
  outbuf, RS_JOB_BLOCKSIZE - (long)buf.avail_out);
403
375
  }
@@ -441,16 +413,6 @@ static PyTypeObject _librsync_PatchMakerType = {
441
413
 
442
414
  /* --------------- _librsync module definition */
443
415
 
444
- #if PY_MAJOR_VERSION >= 3
445
- #define MOD_DEF(ob, name, doc, methods) \
446
- static struct PyModuleDef moduledef = { \
447
- PyModuleDef_HEAD_INIT, name, doc, -1, methods, }; \
448
- ob = PyModule_Create(&moduledef);
449
- #else
450
- #define MOD_DEF(ob, name, doc, methods) \
451
- ob = Py_InitModule3(name, methods, doc);
452
- #endif
453
-
454
416
  static PyMethodDef _librsyncMethods[] = {
455
417
  {"new_sigmaker", _librsync_new_sigmaker, METH_VARARGS,
456
418
  "Return a sigmaker object, for finding the signature of an object"},
@@ -461,6 +423,9 @@ static PyMethodDef _librsyncMethods[] = {
461
423
  {NULL, NULL, 0, NULL}
462
424
  };
463
425
 
426
+ static struct PyModuleDef moduledef = {
427
+ PyModuleDef_HEAD_INIT, "_librsync", "", -1, _librsyncMethods, };
428
+
464
429
  static PyObject *
465
430
  moduleinit(void)
466
431
  {
@@ -474,7 +439,7 @@ moduleinit(void)
474
439
  Py_TYPE(&_librsync_DeltaMakerType) = &PyType_Type;
475
440
  #endif
476
441
 
477
- MOD_DEF(m, "_librsync", "", _librsyncMethods)
442
+ m = PyModule_Create(&moduledef);
478
443
  if (m == NULL)
479
444
  return NULL;
480
445
 
@@ -491,14 +456,7 @@ moduleinit(void)
491
456
  return m;
492
457
  }
493
458
 
494
- #if PY_MAJOR_VERSION < 3
495
- void init_librsync(void)
496
- {
497
- moduleinit();
498
- }
499
- #else
500
459
  PyObject *PyInit__librsync(void)
501
460
  {
502
461
  return moduleinit();
503
462
  }
504
- #endif
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2009 Eric EJ Johnson
4
4
  #
@@ -39,10 +39,8 @@ class CloudFilesBackend(duplicity.backend.Backend):
39
39
  from cloudfiles import consts
40
40
  from cloudfiles.errors import NoSuchObject
41
41
  except ImportError as e:
42
- raise BackendException(
43
- f"""Cloudfiles backend requires the cloudfiles library available from Rackspace.
44
- Exception: {str(e)}"""
45
- )
42
+ raise BackendException(f"""Cloudfiles backend requires the cloudfiles library available from Rackspace.
43
+ Exception: {str(e)}""")
46
44
 
47
45
  self.resp_exc = ResponseError
48
46
  conn_kwargs = {}
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 J.P. Krauss
4
4
  #
@@ -37,10 +37,8 @@ class PyraxBackend(duplicity.backend.Backend):
37
37
  try:
38
38
  import pyrax
39
39
  except ImportError as e:
40
- raise BackendException(
41
- f"""Pyrax backend requires the pyrax library available from Rackspace.
42
- Exception: {str(e)}"""
43
- )
40
+ raise BackendException(f"""Pyrax backend requires the pyrax library available from Rackspace.
41
+ Exception: {str(e)}""")
44
42
 
45
43
  # Inform Pyrax that we're talking to Rackspace
46
44
  # per Jesus Monzon (gsusmonzon)
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -25,19 +25,16 @@ import inspect
25
25
  import json
26
26
  import logging
27
27
  import os
28
- from random import random
29
28
  import re
30
29
  import sys
31
30
  import time
31
+ from random import random
32
32
 
33
33
  import duplicity.backend
34
- from duplicity import (
35
- log,
36
- path,
37
- progress,
38
- )
34
+ from duplicity import log
35
+ from duplicity import path
36
+ from duplicity import progress
39
37
  from duplicity.errors import BackendException
40
- from testing import _runtest_dir
41
38
 
42
39
 
43
40
  class BackendErrors:
@@ -66,6 +63,8 @@ class _TestBackend(duplicity.backend.Backend):
66
63
 
67
64
  def __init__(self, parsed_url):
68
65
  super().__init__(parsed_url)
66
+ from testing import _runtest_dir
67
+
69
68
  log._logger.addHandler(logging.FileHandler(f"{_runtest_dir}/testbackend.log"))
70
69
  log.Warn("TestBackend is not made for production use!")
71
70
  # The URL form "file:MyFile" is not a valid duplicity target.
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2016 Stefan Breunig
4
4
  # Based on the backend onedrivebackend.py
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 Matthieu Huin
4
4
  # Copyright 2015 Scott McKenzie
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright (c) 2015 Matthew Bentley
4
4
  #
@@ -73,7 +73,8 @@ class B2Backend(duplicity.backend.Backend):
73
73
  try: # figure out what version of b2sdk we have
74
74
  from b2sdk import __version__ as VERSION # pylint: disable=import-error
75
75
 
76
- v_split = VERSION.split(".")
76
+ v_public = VERSION.partition("+")[0] # ignore local version identifier if present
77
+ v_split = v_public.split(".")
77
78
  self.v_num = [int(x) for x in v_split]
78
79
  except Exception as e:
79
80
  self.v_num = [0, 0, 0]
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2020 Jose L. Domingo Lopez
4
4
  #
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 Kenneth Loafman
4
4
  #
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 jno
4
4
  # Copyright 2016 Dmitry Nezhevenko
@@ -120,11 +120,9 @@ class DPBXBackend(duplicity.backend.Backend):
120
120
  )
121
121
  from dropbox.oauth import DropboxOAuth2FlowNoRedirect
122
122
  except ImportError as e:
123
- raise BackendException(
124
- f"""This backend requires the dropbox package version 6.9.0
123
+ raise BackendException(f"""This backend requires the dropbox package version 6.9.0
125
124
  To install use "sudo pip install dropbox==6.9.0"
126
- Exception: {str(e)}"""
127
- )
125
+ Exception: {str(e)}""")
128
126
 
129
127
  self.api_account = None
130
128
  self.api_client = None
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2011 Carlos Abalde
4
4
  #
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2015 Yigal Asnis
4
4
  # Copyright 2021 Jindrich Makovicka
@@ -38,11 +38,9 @@ class GDriveBackend(duplicity.backend.Backend):
38
38
  from googleapiclient.discovery import build
39
39
  from google.oauth2.service_account import Credentials
40
40
  except ImportError as e:
41
- raise BackendException(
42
- f"""GDrive backend requires Google API client installation.
41
+ raise BackendException(f"""GDrive backend requires Google API client installation.
43
42
  Please read the manpage for setup details.
44
- Exception: {str(e)}"""
45
- )
43
+ Exception: {str(e)}""")
46
44
 
47
45
  # Note Google has 2 drive methods, `Shared(previously Team) Drives` and `My Drive`
48
46
  # both can be shared but require different addressing
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2009 Michael Terry
4
4
  #
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2013 J.P. Krauss
4
4
  #
@@ -38,10 +38,8 @@ class HubicBackend(PyraxBackend):
38
38
  try:
39
39
  import pyrax
40
40
  except ImportError as e:
41
- raise BackendException(
42
- f"""Hubic backend requires the pyrax library available from Rackspace.
43
- Exception: {str(e)}"""
44
- )
41
+ raise BackendException(f"""Hubic backend requires the pyrax library available from Rackspace.
42
+ Exception: {str(e)}""")
45
43
 
46
44
  # Inform Pyrax that we're talking to Hubic
47
45
  pyrax.set_setting("identity_type", "duplicity.backends.pyrax_identity.hubic.HubicIdentity")
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2021 Menno Smits
4
4
  #
@@ -31,7 +31,6 @@ from duplicity import config
31
31
  from duplicity import log
32
32
  from duplicity.errors import BackendException
33
33
 
34
-
35
34
  #
36
35
  # This backend works with the IDrive "dedup implementation". V0.1
37
36
  # (for all new and recent accounts)
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -168,7 +168,7 @@ class ImapBackend(duplicity.backend.Backend):
168
168
  while allowedTimeout > 0:
169
169
  try:
170
170
  self.conn.select(config.imap_mailbox)
171
- (result, flist) = self.conn.search(None, "Subject", remote_filename)
171
+ result, flist = self.conn.search(None, "Subject", remote_filename)
172
172
  if result != "OK":
173
173
  raise Exception(flist[0])
174
174
 
@@ -176,7 +176,7 @@ class ImapBackend(duplicity.backend.Backend):
176
176
  if flist[0] == "":
177
177
  raise Exception("no mail with subject %s")
178
178
 
179
- (result, flist) = self.conn.fetch(flist[0], "(RFC822)")
179
+ result, flist = self.conn.fetch(flist[0], "(RFC822)")
180
180
 
181
181
  if result != "OK":
182
182
  raise Exception(flist[0])
@@ -211,7 +211,7 @@ class ImapBackend(duplicity.backend.Backend):
211
211
 
212
212
  def _list(self):
213
213
  ret = []
214
- (result, flist) = self.conn.select(config.imap_mailbox)
214
+ result, flist = self.conn.select(config.imap_mailbox)
215
215
  if result != "OK":
216
216
  raise BackendException(flist[0])
217
217
 
@@ -219,14 +219,14 @@ class ImapBackend(duplicity.backend.Backend):
219
219
  # address
220
220
 
221
221
  # Search returns an error if you haven't selected an IMAP folder.
222
- (result, flist) = self.conn.search(None, "FROM", self.remote_dir)
222
+ result, flist = self.conn.search(None, "FROM", self.remote_dir)
223
223
  if result != "OK":
224
224
  raise Exception(flist[0])
225
225
  if flist[0] == b"":
226
226
  return ret
227
227
  nums = flist[0].strip().split(b" ")
228
228
  set = b"%s:%s" % (nums[0], nums[-1]) # pylint: disable=redefined-builtin
229
- (result, flist) = self.conn.fetch(set, "(BODY[HEADER])")
229
+ result, flist = self.conn.fetch(set, "(BODY[HEADER])")
230
230
  if result != "OK":
231
231
  raise Exception(flist[0])
232
232
 
@@ -247,7 +247,7 @@ class ImapBackend(duplicity.backend.Backend):
247
247
  return ret
248
248
 
249
249
  def imapf(self, fun, *args):
250
- (ret, flist) = fun(*args)
250
+ ret, flist = fun(*args)
251
251
  if ret != "OK":
252
252
  raise Exception(flist[0])
253
253
  return flist
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2014 Havard Gulldahl
4
4
  # Copyright 2013 jno
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2016 Roman Yepishev
4
4
  #
@@ -38,10 +38,8 @@ class MediafireBackend(duplicity.backend.Backend):
38
38
  try:
39
39
  import mediafire.client
40
40
  except ImportError as e:
41
- raise BackendException(
42
- f"""Mediafire backend requires the mediafire library.
43
- Exception: {str(e)}"""
44
- )
41
+ raise BackendException(f"""Mediafire backend requires the mediafire library.
42
+ Exception: {str(e)}""")
45
43
 
46
44
  duplicity.backend.Backend.__init__(self, parsed_url)
47
45
 
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2017 Tomas Vondra
4
4
  # Copyright 2017 Kenneth Loafman
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2020 Jose L. Domingo Lopez
4
4
  #
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2020 Jose L. Domingo Lopez
4
4
  #
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2015 Steve Tynor
4
4
  # Copyright 2016 Thomas Harning Jr
@@ -1,4 +1,4 @@
1
- # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; encoding:utf-8 -*-
1
+ # -*- Mode:Python; indent-tabs-mode:nil; tab-width:4; coding:utf-8 -*-
2
2
  #
3
3
  # Copyright 2002 Ben Escoto
4
4
  # Copyright 2007 Kenneth Loafman