# This file is part of maggit.
#
# Copyright 2015 Matthieu Gautier <dev@mgautier.fr>
#
# Pit is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# Pit is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# Additional permission under the GNU Affero GPL version 3 section 7:
#
# If you modify this Program, or any covered work, by linking or
# combining it with other code, such other code is not for that reason
# alone subject to any of the requirements of the GNU Affero GPL
# version 3.
#
# You should have received a copy of the GNU Affero General Public License
# along with maggit. If not, see http://www.gnu.org/licenses
#
# In summary:
# - You can use this program for no cost.
# - You can use this program for both personal and commercial reasons.
# - You do not have to share your own program's code which uses this program.
# - You have to share modifications (e.g bug-fixes, improvements) you've made to this program.
from maggit.sha import Sha
_setattr = object.__setattr__
class MetaGitObjectSkipInit(type):
def __call__(cls, repo, sha):
sha = Sha.cast(sha)
try:
return repo.objectCache[sha]
except KeyError:
obj = super().__call__(repo, sha)
repo.objectCache[sha] = obj
return obj
[docs]class GitObject(metaclass=MetaGitObjectSkipInit):
"""The base class for all git objects.
Git objects are conceptualy constant. However as we try to be lazy,
slots are not fill at object creation and set when user read it.
So GitObject are not constant but behave as if they were.
Attributes:
repo (:class:`~maggit.Repo`) : The repo associated with the object.
sha (:class:`~maggit.Sha`) : The sha of the object.
"""
__slots__ = ('__weakref__',
'repo',
'sha', '_sha')
def _compute_sha(self):
return Sha(self._sha)
def __init__(self, repo, sha):
_setattr(self, 'repo', repo)
_setattr(self, '_sha', sha)
self._read()
def __getattr__(self, name):
"""This is call cause an attribute has not been found.
This is probably cause the slot's descriptor raise a AttributeError.
This means that this may be a computed slot. So compute it."""
try:
f = getattr(self, "_compute_"+name)
except KeyError:
raise KeyError("%s has not attribute %n"%(self, name))
v = f()
_setattr(self, name, v)
return v
@staticmethod
def __setattr__(name, value):
raise RuntimeError("Cannot modify a GitObject")
def __eq__(self, other):
return self._sha == other._sha
def __hash__(self):
return hash(self._sha)