From 405b9531cfa6e78e50c8bc44628ef5b48e441207 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Piotr=20Ma=C5=9Blanka?= <piotr.maslanka@henrietta.com.pl>
Date: Sun, 9 Feb 2020 15:26:00 +0100
Subject: [PATCH] v2.4.6

---
 CHANGELOG.md        |  2 +-
 docs/files.rst      |  7 +++++++
 docs/index.rst      |  1 +
 satella/__init__.py |  2 +-
 satella/files.py    | 29 +++++++++++++++++++++++++++++
 setup.cfg           |  1 -
 tests/test_files.py | 18 ++++++++++++++++++
 7 files changed, 57 insertions(+), 3 deletions(-)
 create mode 100644 docs/files.rst
 create mode 100644 satella/files.py
 create mode 100644 tests/test_files.py

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 761e9c22..47ab76d2 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,6 @@
 # v2.4.6
 
-* _TBA_
+* added `satella.files`
 
 # v2.4.5
 
diff --git a/docs/files.rst b/docs/files.rst
new file mode 100644
index 00000000..35da516b
--- /dev/null
+++ b/docs/files.rst
@@ -0,0 +1,7 @@
+File management routines
+========================
+
+read_re_sub_and_write
+---------------------
+
+.. autofunction:: satella.files.read_re_sub_and_write
diff --git a/docs/index.rst b/docs/index.rst
index 222e5ca4..2608553a 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -22,6 +22,7 @@ Visit the project's page at GitHub_!
            json
            posix
            import
+           files
 
 
 Indices and tables
diff --git a/satella/__init__.py b/satella/__init__.py
index 143d8e99..fdc8312a 100644
--- a/satella/__init__.py
+++ b/satella/__init__.py
@@ -1 +1 @@
-__version__ = '2.4.6rc1'
+__version__ = '2.4.6'
diff --git a/satella/files.py b/satella/files.py
new file mode 100644
index 00000000..c24c5113
--- /dev/null
+++ b/satella/files.py
@@ -0,0 +1,29 @@
+import logging
+import typing as tp
+import re
+
+logger = logging.getLogger(__name__)
+
+__all__ = ['read_re_sub_and_write']
+
+
+def read_re_sub_and_write(path: str, pattern: tp.Union[re.Pattern, str],
+                          repl: tp.Union[tp.Callable[[re.Match], str]]) -> None:
+    """
+    Read a text file, treat with re.sub and write the contents
+
+    :param path: path of file to reat
+    :param pattern: re.Pattern or a string, a pattern to match the file contents
+    :param repl: string or a callable(str)->str to replace the contents
+    """
+    with open(path, 'r') as f_in:
+        data = f_in.read()
+
+    if isinstance(pattern, re.Pattern):
+        data = pattern.sub(repl, data)
+    else:
+        data = re.sub(pattern, repl, data)
+
+    with open(path, 'w') as f_out:
+        f_out.write(data)
+
diff --git a/setup.cfg b/setup.cfg
index 76f466c6..11e48984 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,7 +1,6 @@
 # coding: utf-8
 [metadata]
 name = satella
-description-file = A set of useful routines and libraries for writing Python long-running services
 long-description = file: README.md
 long-description-content-type = text/markdown; charset=UTF-8
 license_files = LICENSE
diff --git a/tests/test_files.py b/tests/test_files.py
new file mode 100644
index 00000000..0353012f
--- /dev/null
+++ b/tests/test_files.py
@@ -0,0 +1,18 @@
+import unittest
+import os
+import tempfile
+from satella.files import read_re_sub_and_write
+
+
+class TestFiles(unittest.TestCase):
+    def test_read_re_sub_and_write(self):
+        filename = tempfile.mktemp()
+        with open(filename, 'w') as f_out:
+            f_out.write('RE')
+
+        read_re_sub_and_write(filename, r'RE', 'sub')
+
+        with open(filename, 'r') as f_in:
+            self.assertEqual('sub', f_in.read())
+
+        os.unlink(filename)
-- 
GitLab