From 5f149c1a9c36c985158c0757377af958362b3582 Mon Sep 17 00:00:00 2001
From: Hugo van Kemenade <hugovk@users.noreply.github.com>
Date: Wed, 16 Nov 2022 18:13:01 +0200
Subject: [PATCH 1/4] Add support for Python 3.10 and 3.11

---
 .github/workflows/pythonpackage.yml | 6 +++---
 setup.py                            | 3 +++
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml
index c695ad3..3c05764 100644
--- a/.github/workflows/pythonpackage.yml
+++ b/.github/workflows/pythonpackage.yml
@@ -15,14 +15,14 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: [3.5, 3.6, 3.7, 3.8, 3.9]
+        python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
 
     steps:
-    - uses: actions/checkout@v2
+    - uses: actions/checkout@v3
       with:
         fetch-depth: 1000
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@v2
+      uses: actions/setup-python@v4
       with:
         python-version: ${{ matrix.python-version }}
     - name: Install dependencies
diff --git a/setup.py b/setup.py
index 31dc62f..5d324cd 100755
--- a/setup.py
+++ b/setup.py
@@ -39,5 +39,8 @@
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",
+        "Programming Language :: Python :: 3.10",
+        "Programming Language :: Python :: 3.11",
+        "Programming Language :: Python :: 3 :: Only",
     ]
 )

From a6f0856d807efc1e7bc37d13f9cfbcdb91dea2ac Mon Sep 17 00:00:00 2001
From: Hugo van Kemenade <hugovk@users.noreply.github.com>
Date: Wed, 16 Nov 2022 18:15:02 +0200
Subject: [PATCH 2/4] Remove redundant Travis CI config/code

---
 .travis.yml                                   | 20 -------------------
 gitdb/test/lib.py                             | 15 --------------
 gitdb/test/performance/test_pack.py           |  4 ----
 gitdb/test/performance/test_pack_streaming.py |  3 ---
 gitdb/test/performance/test_stream.py         |  2 --
 5 files changed, 44 deletions(-)
 delete mode 100644 .travis.yml

diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index b980d36..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-# NOT USED, just for reference. See github actions for CI configuration
-language: python
-python:
-  - "3.4"
-  - "3.5"
-  - "3.6"
-  # - "pypy" - won't work as smmap doesn't work (see smmap/.travis.yml for details)
-
-git:
-  # a higher depth is needed for one of the tests - lets fet
-  depth: 1000
-install:
-  - pip install coveralls
-script: 
-  - ulimit -n 48
-  - ulimit -n
-  - nosetests -v --with-coverage
-after_success:
-  - coveralls
-
diff --git a/gitdb/test/lib.py b/gitdb/test/lib.py
index abd4ad5..465a899 100644
--- a/gitdb/test/lib.py
+++ b/gitdb/test/lib.py
@@ -58,21 +58,6 @@ def setUpClass(cls):
 
 #{ Decorators
 
-def skip_on_travis_ci(func):
-    """All tests decorated with this one will raise SkipTest when run on travis ci.
-    Use it to workaround difficult to solve issues
-    NOTE: copied from bcore (https://github.com/Byron/bcore)"""
-    @wraps(func)
-    def wrapper(self, *args, **kwargs):
-        if 'TRAVIS' in os.environ:
-            import pytest
-            pytest.skip("Cannot run on travis-ci")
-        # end check for travis ci
-        return func(self, *args, **kwargs)
-    # end wrapper
-    return wrapper
-
-
 def with_rw_directory(func):
     """Create a temporary directory which can be written to, remove it if the
     test succeeds, but leave it otherwise to aid additional debugging"""
diff --git a/gitdb/test/performance/test_pack.py b/gitdb/test/performance/test_pack.py
index b59d5a9..643186b 100644
--- a/gitdb/test/performance/test_pack.py
+++ b/gitdb/test/performance/test_pack.py
@@ -17,7 +17,6 @@
 from gitdb.typ import str_blob_type
 from gitdb.exc import UnsupportedOperation
 from gitdb.db.pack import PackedDB
-from gitdb.test.lib import skip_on_travis_ci
 
 import sys
 import os
@@ -26,7 +25,6 @@
 
 class TestPackedDBPerformance(TestBigRepoR):
 
-    @skip_on_travis_ci
     def test_pack_random_access(self):
         pdb = PackedDB(os.path.join(self.gitrepopath, "objects/pack"))
 
@@ -79,7 +77,6 @@ def test_pack_random_access(self):
         print("PDB: Obtained %i streams by sha and read all bytes totallying %i KiB ( %f KiB / s ) in %f s ( %f streams/s )" %
               (max_items, total_kib, total_kib / (elapsed or 1), elapsed, max_items / (elapsed or 1)), file=sys.stderr)
 
-    @skip_on_travis_ci
     def test_loose_correctness(self):
         """based on the pack(s) of our packed object DB, we will just copy and verify all objects in the back
         into the loose object db (memory).
@@ -106,7 +103,6 @@ def test_loose_correctness(self):
             mdb._cache.clear()
         # end for each sha to copy
 
-    @skip_on_travis_ci
     def test_correctness(self):
         pdb = PackedDB(os.path.join(self.gitrepopath, "objects/pack"))
         # disabled for now as it used to work perfectly, checking big repositories takes a long time
diff --git a/gitdb/test/performance/test_pack_streaming.py b/gitdb/test/performance/test_pack_streaming.py
index 76f0f4a..5bf6790 100644
--- a/gitdb/test/performance/test_pack_streaming.py
+++ b/gitdb/test/performance/test_pack_streaming.py
@@ -12,7 +12,6 @@
 from gitdb.db.pack import PackedDB
 from gitdb.stream import NullStream
 from gitdb.pack import PackEntity
-from gitdb.test.lib import skip_on_travis_ci
 
 import os
 import sys
@@ -34,7 +33,6 @@ def write(self, d):
 
 class TestPackStreamingPerformance(TestBigRepoR):
 
-    @skip_on_travis_ci
     def test_pack_writing(self):
         # see how fast we can write a pack from object streams.
         # This will not be fast, as we take time for decompressing the streams as well
@@ -61,7 +59,6 @@ def test_pack_writing(self):
         print(sys.stderr, "PDB Streaming: Wrote pack of size %i kb in %f s (%f kb/s)" %
               (total_kb, elapsed, total_kb / (elapsed or 1)), sys.stderr)
 
-    @skip_on_travis_ci
     def test_stream_reading(self):
         # raise SkipTest()
         pdb = PackedDB(os.path.join(self.gitrepopath, "objects/pack"))
diff --git a/gitdb/test/performance/test_stream.py b/gitdb/test/performance/test_stream.py
index 92d28e4..9a8b15b 100644
--- a/gitdb/test/performance/test_stream.py
+++ b/gitdb/test/performance/test_stream.py
@@ -20,7 +20,6 @@
 from gitdb.test.lib import (
     make_memory_file,
     with_rw_directory,
-    skip_on_travis_ci
 )
 
 
@@ -44,7 +43,6 @@ class TestObjDBPerformance(TestBigRepoR):
     large_data_size_bytes = 1000 * 1000 * 50        # some MiB should do it
     moderate_data_size_bytes = 1000 * 1000 * 1      # just 1 MiB
 
-    @skip_on_travis_ci
     @with_rw_directory
     def test_large_data_streaming(self, path):
         ldb = LooseObjectDB(path)

From faed217d14965932b333c07219ed401a661d2651 Mon Sep 17 00:00:00 2001
From: Hugo van Kemenade <hugovk@users.noreply.github.com>
Date: Wed, 16 Nov 2022 18:16:09 +0200
Subject: [PATCH 3/4] Drop support for EOL Python 3.5 and 3.6

---
 .github/workflows/pythonpackage.yml | 2 +-
 setup.py                            | 3 +--
 2 files changed, 2 insertions(+), 3 deletions(-)

diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml
index 3c05764..0d039ad 100644
--- a/.github/workflows/pythonpackage.yml
+++ b/.github/workflows/pythonpackage.yml
@@ -15,7 +15,7 @@ jobs:
     runs-on: ubuntu-latest
     strategy:
       matrix:
-        python-version: ["3.5", "3.6", "3.7", "3.8", "3.9", "3.10", "3.11"]
+        python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
 
     steps:
     - uses: actions/checkout@v3
diff --git a/setup.py b/setup.py
index 5d324cd..d38b267 100755
--- a/setup.py
+++ b/setup.py
@@ -22,7 +22,7 @@
     zip_safe=False,
     install_requires=['smmap>=3.0.1,<6'],
     long_description="""GitDB is a pure-Python git object database""",
-    python_requires='>=3.6',
+    python_requires='>=3.7',
     # See https://pypi.python.org/pypi?%3Aaction=list_classifiers
     classifiers=[
         "Development Status :: 5 - Production/Stable",
@@ -35,7 +35,6 @@
         "Operating System :: MacOS :: MacOS X",
         "Programming Language :: Python",
         "Programming Language :: Python :: 3",
-        "Programming Language :: Python :: 3.6",
         "Programming Language :: Python :: 3.7",
         "Programming Language :: Python :: 3.8",
         "Programming Language :: Python :: 3.9",

From 7a68270d6c78b81f577b433dc6351b26bc27b7cf Mon Sep 17 00:00:00 2001
From: Hugo van Kemenade <hugovk@users.noreply.github.com>
Date: Wed, 16 Nov 2022 18:17:20 +0200
Subject: [PATCH 4/4] Upgrade Python syntax with pyupgrade --py37-plus

---
 doc/source/conf.py                            |  9 ++++-----
 gitdb/db/base.py                              | 12 ++++++------
 gitdb/db/git.py                               |  4 ++--
 gitdb/db/loose.py                             |  4 ++--
 gitdb/db/mem.py                               |  2 +-
 gitdb/db/pack.py                              |  2 +-
 gitdb/db/ref.py                               |  8 ++++----
 gitdb/fun.py                                  |  2 +-
 gitdb/pack.py                                 |  4 ++--
 gitdb/stream.py                               | 12 ++++++------
 gitdb/test/db/test_ref.py                     |  2 +-
 gitdb/test/lib.py                             |  6 +++---
 gitdb/test/performance/test_pack.py           |  1 -
 gitdb/test/performance/test_pack_streaming.py |  1 -
 gitdb/test/performance/test_stream.py         |  1 -
 gitdb/test/test_example.py                    |  2 +-
 gitdb/test/test_stream.py                     |  4 ++--
 gitdb/util.py                                 | 14 +++++++-------
 18 files changed, 43 insertions(+), 47 deletions(-)

diff --git a/doc/source/conf.py b/doc/source/conf.py
index 3ab15ab..b387f60 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -1,4 +1,3 @@
-# -*- coding: utf-8 -*-
 #
 # GitDB documentation build configuration file, created by
 # sphinx-quickstart on Wed Jun 30 00:01:32 2010.
@@ -38,8 +37,8 @@
 master_doc = 'index'
 
 # General information about the project.
-project = u'GitDB'
-copyright = u'2011, Sebastian Thiel'
+project = 'GitDB'
+copyright = '2011, Sebastian Thiel'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
@@ -172,8 +171,8 @@
 # Grouping the document tree into LaTeX files. List of tuples
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
-    ('index', 'GitDB.tex', u'GitDB Documentation',
-     u'Sebastian Thiel', 'manual'),
+    ('index', 'GitDB.tex', 'GitDB Documentation',
+     'Sebastian Thiel', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
diff --git a/gitdb/db/base.py b/gitdb/db/base.py
index f0b8a05..e89052e 100644
--- a/gitdb/db/base.py
+++ b/gitdb/db/base.py
@@ -22,7 +22,7 @@
 __all__ = ('ObjectDBR', 'ObjectDBW', 'FileDBBase', 'CompoundDB', 'CachingDB')
 
 
-class ObjectDBR(object):
+class ObjectDBR:
 
     """Defines an interface for object database lookup.
     Objects are identified either by their 20 byte bin sha"""
@@ -63,7 +63,7 @@ def sha_iter(self):
     #} END query interface
 
 
-class ObjectDBW(object):
+class ObjectDBW:
 
     """Defines an interface to create objects in the database"""
 
@@ -105,7 +105,7 @@ def store(self, istream):
     #} END edit interface
 
 
-class FileDBBase(object):
+class FileDBBase:
 
     """Provides basic facilities to retrieve files of interest, including
     caching facilities to help mapping hexsha's to objects"""
@@ -117,7 +117,7 @@ def __init__(self, root_path):
         **Note:** The base will not perform any accessablity checking as the base
             might not yet be accessible, but become accessible before the first
             access."""
-        super(FileDBBase, self).__init__()
+        super().__init__()
         self._root_path = root_path
 
     #{ Interface
@@ -133,7 +133,7 @@ def db_path(self, rela_path):
     #} END interface
 
 
-class CachingDB(object):
+class CachingDB:
 
     """A database which uses caches to speed-up access"""
 
@@ -176,7 +176,7 @@ def _set_cache_(self, attr):
         elif attr == '_db_cache':
             self._db_cache = dict()
         else:
-            super(CompoundDB, self)._set_cache_(attr)
+            super()._set_cache_(attr)
 
     def _db_query(self, sha):
         """:return: database containing the given 20 byte sha
diff --git a/gitdb/db/git.py b/gitdb/db/git.py
index 7a43d72..e2cb468 100644
--- a/gitdb/db/git.py
+++ b/gitdb/db/git.py
@@ -39,7 +39,7 @@ class GitDB(FileDBBase, ObjectDBW, CompoundDB):
 
     def __init__(self, root_path):
         """Initialize ourselves on a git objects directory"""
-        super(GitDB, self).__init__(root_path)
+        super().__init__(root_path)
 
     def _set_cache_(self, attr):
         if attr == '_dbs' or attr == '_loose_db':
@@ -68,7 +68,7 @@ def _set_cache_(self, attr):
             # finally set the value
             self._loose_db = loose_db
         else:
-            super(GitDB, self)._set_cache_(attr)
+            super()._set_cache_(attr)
         # END handle attrs
 
     #{ ObjectDBW interface
diff --git a/gitdb/db/loose.py b/gitdb/db/loose.py
index a63a2ef..4ef7750 100644
--- a/gitdb/db/loose.py
+++ b/gitdb/db/loose.py
@@ -75,7 +75,7 @@ class LooseObjectDB(FileDBBase, ObjectDBR, ObjectDBW):
         new_objects_mode = int("644", 8)
 
     def __init__(self, root_path):
-        super(LooseObjectDB, self).__init__(root_path)
+        super().__init__(root_path)
         self._hexsha_to_file = dict()
         # Additional Flags - might be set to 0 after the first failure
         # Depending on the root, this might work for some mounts, for others not, which
@@ -151,7 +151,7 @@ def set_ostream(self, stream):
         """:raise TypeError: if the stream does not support the Sha1Writer interface"""
         if stream is not None and not isinstance(stream, Sha1Writer):
             raise TypeError("Output stream musst support the %s interface" % Sha1Writer.__name__)
-        return super(LooseObjectDB, self).set_ostream(stream)
+        return super().set_ostream(stream)
 
     def info(self, sha):
         m = self._map_loose_object(sha)
diff --git a/gitdb/db/mem.py b/gitdb/db/mem.py
index b2542ff..1b954cb 100644
--- a/gitdb/db/mem.py
+++ b/gitdb/db/mem.py
@@ -37,7 +37,7 @@ class MemoryDB(ObjectDBR, ObjectDBW):
     exists in the target storage before introducing actual IO"""
 
     def __init__(self):
-        super(MemoryDB, self).__init__()
+        super().__init__()
         self._db = LooseObjectDB("path/doesnt/matter")
 
         # maps 20 byte shas to their OStream objects
diff --git a/gitdb/db/pack.py b/gitdb/db/pack.py
index 90de02b..1ce786b 100644
--- a/gitdb/db/pack.py
+++ b/gitdb/db/pack.py
@@ -39,7 +39,7 @@ class PackedDB(FileDBBase, ObjectDBR, CachingDB, LazyMixin):
     _sort_interval = 500
 
     def __init__(self, root_path):
-        super(PackedDB, self).__init__(root_path)
+        super().__init__(root_path)
         # list of lists with three items:
         # * hits - number of times the pack was hit with a request
         # * entity - Pack entity instance
diff --git a/gitdb/db/ref.py b/gitdb/db/ref.py
index 2bb1de7..6bb2a64 100644
--- a/gitdb/db/ref.py
+++ b/gitdb/db/ref.py
@@ -20,7 +20,7 @@ class ReferenceDB(CompoundDB):
     ObjectDBCls = None
 
     def __init__(self, ref_file):
-        super(ReferenceDB, self).__init__()
+        super().__init__()
         self._ref_file = ref_file
 
     def _set_cache_(self, attr):
@@ -28,7 +28,7 @@ def _set_cache_(self, attr):
             self._dbs = list()
             self._update_dbs_from_ref_file()
         else:
-            super(ReferenceDB, self)._set_cache_(attr)
+            super()._set_cache_(attr)
         # END handle attrs
 
     def _update_dbs_from_ref_file(self):
@@ -44,7 +44,7 @@ def _update_dbs_from_ref_file(self):
         try:
             with codecs.open(self._ref_file, 'r', encoding="utf-8") as f:
                 ref_paths = [l.strip() for l in f]
-        except (OSError, IOError):
+        except OSError:
             pass
         # END handle alternates
 
@@ -79,4 +79,4 @@ def _update_dbs_from_ref_file(self):
     def update_cache(self, force=False):
         # re-read alternates and update databases
         self._update_dbs_from_ref_file()
-        return super(ReferenceDB, self).update_cache(force)
+        return super().update_cache(force)
diff --git a/gitdb/fun.py b/gitdb/fun.py
index abb4277..a4454de 100644
--- a/gitdb/fun.py
+++ b/gitdb/fun.py
@@ -113,7 +113,7 @@ def delta_chunk_apply(dc, bbuf, write):
     # END handle chunk mode
 
 
-class DeltaChunk(object):
+class DeltaChunk:
 
     """Represents a piece of a delta, it can either add new data, or copy existing
     one from a source buffer"""
diff --git a/gitdb/pack.py b/gitdb/pack.py
index 0b26c12..cabce4c 100644
--- a/gitdb/pack.py
+++ b/gitdb/pack.py
@@ -170,7 +170,7 @@ def write_stream_to_pack(read, write, zstream, base_crc=None):
 #} END utilities
 
 
-class IndexWriter(object):
+class IndexWriter:
 
     """Utility to cache index information, allowing to write all information later
     in one go to the given stream
@@ -257,7 +257,7 @@ class PackIndexFile(LazyMixin):
     index_version_default = 2
 
     def __init__(self, indexpath):
-        super(PackIndexFile, self).__init__()
+        super().__init__()
         self._indexpath = indexpath
 
     def close(self):
diff --git a/gitdb/stream.py b/gitdb/stream.py
index 37380ad..222b843 100644
--- a/gitdb/stream.py
+++ b/gitdb/stream.py
@@ -219,13 +219,13 @@ def read(self, size=-1):
         # END clamp size
 
         if size == 0:
-            return bytes()
+            return b''
         # END handle depletion
 
         # deplete the buffer, then just continue using the decompress object
         # which has an own buffer. We just need this to transparently parse the
         # header from the zlib stream
-        dat = bytes()
+        dat = b''
         if self._buf:
             if self._buflen >= size:
                 # have enough data
@@ -553,7 +553,7 @@ def size(self):
 
 #{ W Streams
 
-class Sha1Writer(object):
+class Sha1Writer:
 
     """Simple stream writer which produces a sha whenever you like as it degests
     everything it is supposed to write"""
@@ -650,7 +650,7 @@ class FDCompressedSha1Writer(Sha1Writer):
     exc = IOError("Failed to write all bytes to filedescriptor")
 
     def __init__(self, fd):
-        super(FDCompressedSha1Writer, self).__init__()
+        super().__init__()
         self.fd = fd
         self.zip = zlib.compressobj(zlib.Z_BEST_SPEED)
 
@@ -677,7 +677,7 @@ def close(self):
     #} END stream interface
 
 
-class FDStream(object):
+class FDStream:
 
     """A simple wrapper providing the most basic functions on a file descriptor
     with the fileobject interface. Cannot use os.fdopen as the resulting stream
@@ -711,7 +711,7 @@ def close(self):
         close(self._fd)
 
 
-class NullStream(object):
+class NullStream:
 
     """A stream that does nothing but providing a stream interface.
     Use it like /dev/null"""
diff --git a/gitdb/test/db/test_ref.py b/gitdb/test/db/test_ref.py
index 2049698..664aa54 100644
--- a/gitdb/test/db/test_ref.py
+++ b/gitdb/test/db/test_ref.py
@@ -23,7 +23,7 @@ def make_alt_file(self, alt_path, alt_list):
         The list can be empty"""
         with open(alt_path, "wb") as alt_file:
             for alt in alt_list:
-                alt_file.write(alt.encode("utf-8") + "\n".encode("ascii"))
+                alt_file.write(alt.encode("utf-8") + b"\n")
 
     @with_rw_directory
     def test_writing(self, path):
diff --git a/gitdb/test/lib.py b/gitdb/test/lib.py
index 465a899..da59d3b 100644
--- a/gitdb/test/lib.py
+++ b/gitdb/test/lib.py
@@ -40,7 +40,7 @@ class TestBase(unittest.TestCase):
     @classmethod
     def setUpClass(cls):
         try:
-            super(TestBase, cls).setUpClass()
+            super().setUpClass()
         except AttributeError:
             pass
 
@@ -70,7 +70,7 @@ def wrapper(self):
             try:
                 return func(self, path)
             except Exception:
-                sys.stderr.write("Test {}.{} failed, output is at {!r}\n".format(type(self).__name__, func.__name__, path))
+                sys.stderr.write(f"Test {type(self).__name__}.{func.__name__} failed, output is at {path!r}\n")
                 keep = True
                 raise
         finally:
@@ -161,7 +161,7 @@ def make_memory_file(size_in_bytes, randomize=False):
 #{ Stream Utilities
 
 
-class DummyStream(object):
+class DummyStream:
 
     def __init__(self):
         self.was_read = False
diff --git a/gitdb/test/performance/test_pack.py b/gitdb/test/performance/test_pack.py
index 643186b..f034baf 100644
--- a/gitdb/test/performance/test_pack.py
+++ b/gitdb/test/performance/test_pack.py
@@ -3,7 +3,6 @@
 # This module is part of GitDB and is released under
 # the New BSD License: http://www.opensource.org/licenses/bsd-license.php
 """Performance tests for object store"""
-from __future__ import print_function
 
 from gitdb.test.performance.lib import (
     TestBigRepoR
diff --git a/gitdb/test/performance/test_pack_streaming.py b/gitdb/test/performance/test_pack_streaming.py
index 5bf6790..db790f1 100644
--- a/gitdb/test/performance/test_pack_streaming.py
+++ b/gitdb/test/performance/test_pack_streaming.py
@@ -3,7 +3,6 @@
 # This module is part of GitDB and is released under
 # the New BSD License: http://www.opensource.org/licenses/bsd-license.php
 """Specific test for pack streams only"""
-from __future__ import print_function
 
 from gitdb.test.performance.lib import (
     TestBigRepoR
diff --git a/gitdb/test/performance/test_stream.py b/gitdb/test/performance/test_stream.py
index 9a8b15b..91dc891 100644
--- a/gitdb/test/performance/test_stream.py
+++ b/gitdb/test/performance/test_stream.py
@@ -3,7 +3,6 @@
 # This module is part of GitDB and is released under
 # the New BSD License: http://www.opensource.org/licenses/bsd-license.php
 """Performance data streaming performance"""
-from __future__ import print_function
 
 from gitdb.test.performance.lib import TestBigRepoR
 from gitdb.db import LooseObjectDB
diff --git a/gitdb/test/test_example.py b/gitdb/test/test_example.py
index 6e80bf5..cc4d40d 100644
--- a/gitdb/test/test_example.py
+++ b/gitdb/test/test_example.py
@@ -32,7 +32,7 @@ def test_base(self):
             pass
         # END ignore exception if there are no loose objects
 
-        data = "my data".encode("ascii")
+        data = b"my data"
         istream = IStream("blob", len(data), BytesIO(data))
 
         # the object does not yet have a sha
diff --git a/gitdb/test/test_stream.py b/gitdb/test/test_stream.py
index 5d4b93d..5e2e1ba 100644
--- a/gitdb/test/test_stream.py
+++ b/gitdb/test/test_stream.py
@@ -115,13 +115,13 @@ def test_decompress_reader(self):
 
     def test_sha_writer(self):
         writer = Sha1Writer()
-        assert 2 == writer.write("hi".encode("ascii"))
+        assert 2 == writer.write(b"hi")
         assert len(writer.sha(as_hex=1)) == 40
         assert len(writer.sha(as_hex=0)) == 20
 
         # make sure it does something ;)
         prev_sha = writer.sha()
-        writer.write("hi again".encode("ascii"))
+        writer.write(b"hi again")
         assert writer.sha() != prev_sha
 
     def test_compressed_writer(self):
diff --git a/gitdb/util.py b/gitdb/util.py
index f9f8c0e..3151c06 100644
--- a/gitdb/util.py
+++ b/gitdb/util.py
@@ -94,7 +94,7 @@ def remove(*args, **kwargs):
 #{ compatibility stuff ...
 
 
-class _RandomAccessBytesIO(object):
+class _RandomAccessBytesIO:
 
     """Wrapper to provide required functionality in case memory maps cannot or may
     not be used. This is only really required in python 2.4"""
@@ -131,7 +131,7 @@ def byte_ord(b):
 #{ Routines
 
 
-def make_sha(source=''.encode("ascii")):
+def make_sha(source=b''):
     """A python2.4 workaround for the sha/hashlib module fiasco
 
     **Note** From the dulwich project """
@@ -151,7 +151,7 @@ def allocate_memory(size):
 
     try:
         return mmap.mmap(-1, size)  # read-write by default
-    except EnvironmentError:
+    except OSError:
         # setup real memory instead
         # this of course may fail if the amount of memory is not available in
         # one chunk - would only be the case in python 2.4, being more likely on
@@ -174,7 +174,7 @@ def file_contents_ro(fd, stream=False, allow_mmap=True):
             # supports stream and random access
             try:
                 return mmap.mmap(fd, 0, access=mmap.ACCESS_READ)
-            except EnvironmentError:
+            except OSError:
                 # python 2.4 issue, 0 wants to be the actual size
                 return mmap.mmap(fd, os.fstat(fd).st_size, access=mmap.ACCESS_READ)
             # END handle python 2.4
@@ -234,7 +234,7 @@ def to_bin_sha(sha):
 
 #{ Utilities
 
-class LazyMixin(object):
+class LazyMixin:
 
     """
     Base class providing an interface to lazily retrieve attribute values upon
@@ -266,7 +266,7 @@ def _set_cache_(self, attr):
         pass
 
 
-class LockedFD(object):
+class LockedFD:
 
     """
     This class facilitates a safe read and write operation to a file on disk.
@@ -327,7 +327,7 @@ def open(self, write=False, stream=False):
                 self._fd = fd
             # END handle file descriptor
         except OSError as e:
-            raise IOError("Lock at %r could not be obtained" % self._lockfilepath()) from e
+            raise OSError("Lock at %r could not be obtained" % self._lockfilepath()) from e
         # END handle lock retrieval
 
         # open actual file if required