diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml index c695ad3..0d039ad 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.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/.gitignore b/.gitignore index e0b4e85..8b7da92 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ dist/ *.so .noseids *.sublime-workspace +*.egg-info diff --git a/.gitmodules b/.gitmodules index d85b15c..e73cded 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "smmap"] path = gitdb/ext/smmap - url = https://github.com/Byron/smmap.git + url = https://github.com/gitpython-developers/smmap.git 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/Makefile b/Makefile index e063028..a7acbb1 100644 --- a/Makefile +++ b/Makefile @@ -16,7 +16,7 @@ release:: clean force_release:: clean git push --tags python3 setup.py sdist bdist_wheel - twine upload -s -i 27C50E7F590947D7273A741E85194C08421980C9 dist/* + twine upload dist/* doc:: make -C doc/ html diff --git a/doc/source/changes.rst b/doc/source/changes.rst index 5ef1326..7d85ea5 100644 --- a/doc/source/changes.rst +++ b/doc/source/changes.rst @@ -2,6 +2,12 @@ Changelog ######### +****** +4.0.10 +****** + +- improvements to the way external packages are imported. + ***** 4.0.9 ***** 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/__init__.py b/gitdb/__init__.py index 2460145..b777632 100644 --- a/gitdb/__init__.py +++ b/gitdb/__init__.py @@ -12,15 +12,13 @@ def _init_externals(): """Initialize external projects by putting them into the path""" - for module in ('smmap',): - if 'PYOXIDIZER' not in os.environ: - sys.path.append(os.path.join(os.path.dirname(__file__), 'ext', module)) - - try: - __import__(module) - except ImportError as e: - raise ImportError("'%s' could not be imported, assure it is located in your PYTHONPATH" % module) from e - # END verify import + if 'PYOXIDIZER' not in os.environ: + where = os.path.join(os.path.dirname(__file__), 'ext', 'smmap') + if os.path.exists(where): + sys.path.append(where) + + import smmap + del smmap # END handle imports #} END initialization @@ -30,7 +28,7 @@ def _init_externals(): __author__ = "Sebastian Thiel" __contact__ = "byronimo@gmail.com" __homepage__ = "https://github.com/gitpython-developers/gitdb" -version_info = (4, 0, 9) +version_info = (4, 0, 10) __version__ = '.'.join(str(i) for i in version_info) 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/ext/smmap b/gitdb/ext/smmap index db88100..334ef84 160000 --- a/gitdb/ext/smmap +++ b/gitdb/ext/smmap @@ -1 +1 @@ -Subproject commit db8810096503dd8a1f5a021ff39be907417f90a7 +Subproject commit 334ef84a05c953ed5dbec7b9c6d4310879eeab5a 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 abd4ad5..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 @@ -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""" @@ -85,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: @@ -176,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 b59d5a9..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 @@ -17,7 +16,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 +24,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 +76,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 +102,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..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 @@ -12,7 +11,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 +32,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 +58,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..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 @@ -20,7 +19,6 @@ from gitdb.test.lib import ( make_memory_file, with_rw_directory, - skip_on_travis_ci ) @@ -44,7 +42,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) 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 diff --git a/setup.py b/setup.py index 31dc62f..5214849 100755 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ __author__ = "Sebastian Thiel" __contact__ = "byronimo@gmail.com" __homepage__ = "https://github.com/gitpython-developers/gitdb" -version_info = (4, 0, 9) +version_info = (4, 0, 10) __version__ = '.'.join(str(i) for i in version_info) setup( @@ -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,9 +35,11 @@ "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", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3 :: Only", ] )
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: