Repository: borgbackup/borg

Issue:
use more py39 features
master and 1.4-maint branch only, 1.2-maint is still on py38, 1.1-maint even older.

https://docs.python.org/3/whatsnew/3.9.html

especially:

- [ ] https://docs.python.org/3/whatsnew/3.9.html#dictionary-merge-update-operators
- [ ] https://docs.python.org/3/whatsnew/3.9.html#new-string-methods-to-remove-prefixes-and-suffixes



Discussion:
> https://docs.python.org/3/whatsnew/3.9.html#random new randbytes function

Note: `random.randbytes` is not intended for secure random:

> [random.randbytes(n)](https://docs.python.org/3/library/random.html?highlight=random%20random%20randbytes#random.randbytes)
> 
> This method should not be used for generating security tokens. Use [secrets.token_bytes()](https://docs.python.org/3/library/secrets.html#secrets.token_bytes) instead.

In my humble opinion we should always use secure random even if it is not always necessary. Deciding which numbers are safe to generate insecurely and which ones are not **is error prone**. It is much simpler to generate all random securely *unless* we are experiencing a *measurable* performance degradation.

Resolving patch:
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -281,7 +281,6 @@ def members_appended(*ds):
         'Operating System :: POSIX :: Linux',
         'Programming Language :: Python',
         'Programming Language :: Python :: 3',
-        'Programming Language :: Python :: 3.8',
         'Programming Language :: Python :: 3.9',
         'Programming Language :: Python :: 3.10',
         'Programming Language :: Python :: 3.11',
@@ -310,5 +309,5 @@ def members_appended(*ds):
     setup_requires=['setuptools_scm>=1.7'],
     install_requires=install_requires,
     extras_require=extras_require,
-    python_requires='>=3.8',
+    python_requires='>=3.9',
 )
diff --git a/src/borg/archiver.py b/src/borg/archiver.py
--- a/src/borg/archiver.py
+++ b/src/borg/archiver.py
@@ -2584,11 +2584,11 @@ def do_break_lock(self, args, repository):
 
         {now}
             The current local date and time, by default in ISO-8601 format.
-            You can also supply your own `format string <https://docs.python.org/3.8/library/datetime.html#strftime-and-strptime-behavior>`_, e.g. {now:%Y-%m-%d_%H:%M:%S}
+            You can also supply your own `format string <https://docs.python.org/3.9/library/datetime.html#strftime-and-strptime-behavior>`_, e.g. {now:%Y-%m-%d_%H:%M:%S}
 
         {utcnow}
             The current UTC date and time, by default in ISO-8601 format.
-            You can also supply your own `format string <https://docs.python.org/3.8/library/datetime.html#strftime-and-strptime-behavior>`_, e.g. {utcnow:%Y-%m-%d_%H:%M:%S}
+            You can also supply your own `format string <https://docs.python.org/3.9/library/datetime.html#strftime-and-strptime-behavior>`_, e.g. {utcnow:%Y-%m-%d_%H:%M:%S}
 
         {user}
             The user name (or UID, if no name is available) of the user running borg.
@@ -4514,7 +4514,7 @@ def define_borg_mount(parser):
         +++++++++++++++++++++++++++
 
         The ``--format`` option uses python's `format string syntax
-        <https://docs.python.org/3.8/library/string.html#formatstrings>`_.
+        <https://docs.python.org/3.9/library/string.html#formatstrings>`_.
 
         Examples:
         ::


Test patch: