summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README4
-rw-r--r--doc/tutorial.txt2
-rw-r--r--lib/git/cmd.py10
-rw-r--r--lib/git/method_missing.py26
-rw-r--r--test/git/test_blob.py10
-rw-r--r--test/git/test_commit.py22
-rw-r--r--test/git/test_git.py4
-rw-r--r--test/git/test_head.py2
-rw-r--r--test/git/test_repo.py32
-rw-r--r--test/git/test_tag.py4
-rw-r--r--test/git/test_tree.py8
11 files changed, 49 insertions, 75 deletions
diff --git a/README b/README
index ded718b9..a4d8c86e 100644
--- a/README
+++ b/README
@@ -9,10 +9,6 @@ Tom Preston-Werner and Chris Wanstrath.
.. _grit: http://grit.rubyforge.org
-The idea for the ``method_missing`` stuff was `taken from this blog post`_.
-
-.. _taken from this blog post: http://blog.iffy.us/?p=43
-
REQUIREMENTS
============
diff --git a/doc/tutorial.txt b/doc/tutorial.txt
index 92ed3cdc..5ad56129 100644
--- a/doc/tutorial.txt
+++ b/doc/tutorial.txt
@@ -184,7 +184,7 @@ What Else?
There is more stuff in there, like the ability to tar or gzip repos, stats,
log, blame, and probably a few other things. Additionally calls to the git
-instance are handled through a ``method_missing`` construct, which makes
+instance are handled through a ``__getattr__`` construct, which makes
available any git commands directly, with a nice conversion of Python dicts
to command line parameters.
diff --git a/lib/git/cmd.py b/lib/git/cmd.py
index a6e8f6cc..38cfe3bd 100644
--- a/lib/git/cmd.py
+++ b/lib/git/cmd.py
@@ -8,7 +8,6 @@ import os
import subprocess
import re
from utils import *
-from method_missing import MethodMissingMixin
from errors import GitCommandError
# Enables debugging of GitPython's git commands
@@ -17,7 +16,7 @@ GIT_PYTHON_TRACE = os.environ.get("GIT_PYTHON_TRACE", False)
execute_kwargs = ('istream', 'with_keep_cwd', 'with_extended_output',
'with_exceptions', 'with_raw_output')
-class Git(MethodMissingMixin):
+class Git(object):
"""
The Git class manages communication with the Git binary
"""
@@ -25,6 +24,11 @@ class Git(MethodMissingMixin):
super(Git, self).__init__()
self.git_dir = git_dir
+ def __getattr__(self, name):
+ if name[:1] == '_':
+ raise AttributeError(name)
+ return lambda *args, **kwargs: self._call_process(name, *args, **kwargs)
+
@property
def get_dir(self):
return self.git_dir
@@ -131,7 +135,7 @@ class Git(MethodMissingMixin):
args.append("--%s=%s" % (dashify(k), v))
return args
- def method_missing(self, method, *args, **kwargs):
+ def _call_process(self, method, *args, **kwargs):
"""
Run the given git command with the specified arguments and return
the result as a String
diff --git a/lib/git/method_missing.py b/lib/git/method_missing.py
deleted file mode 100644
index 250fcc6d..00000000
--- a/lib/git/method_missing.py
+++ /dev/null
@@ -1,26 +0,0 @@
-# method_missing.py
-# Copyright (C) 2008 Michael Trier (mtrier@gmail.com) and contributors
-# Portions derived from http://blog.iffy.us/?p=43
-#
-# This module is part of GitPython and is released under
-# the BSD License: http://www.opensource.org/licenses/bsd-license.php
-
-class MethodMissingMixin(object):
- """
- A Mixin' to implement the 'method_missing' Ruby-like protocol.
-
- Ideas were `taken from the following blog post
- <http://blog.iffy.us/?p=43>`_
- """
- def __getattr__(self, attr):
- class MethodMissing(object):
- def __init__(self, wrapped, method):
- self.__wrapped__ = wrapped
- self.__method__ = method
- def __call__(self, *args, **kwargs):
- return self.__wrapped__.method_missing(self.__method__, *args, **kwargs)
- return MethodMissing(self, attr)
-
- def method_missing(self, *args, **kwargs):
- """ This method should be overridden in the derived class. """
- raise NotImplementedError(str(self.__wrapped__) + " 'method_missing' method has not been implemented.")
diff --git a/test/git/test_blob.py b/test/git/test_blob.py
index b7f44ff0..68afdbd8 100644
--- a/test/git/test_blob.py
+++ b/test/git/test_blob.py
@@ -12,7 +12,7 @@ class TestBlob(object):
def setup(self):
self.repo = Repo(GIT_REPO)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_should_return_blob_contents(self, git):
git.return_value = fixture('cat_file_blob')
blob = Blob(self.repo, **{'id': 'abc'})
@@ -20,7 +20,7 @@ class TestBlob(object):
assert_true(git.called)
assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_should_cache_data(self, git):
git.return_value = fixture('cat_file_blob')
blob = Blob(self.repo, **{'id': 'abc'})
@@ -30,7 +30,7 @@ class TestBlob(object):
assert_equal(git.call_count, 1)
assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_should_return_file_size(self, git):
git.return_value = fixture('cat_file_blob_size')
blob = Blob(self.repo, **{'id': 'abc'})
@@ -38,7 +38,7 @@ class TestBlob(object):
assert_true(git.called)
assert_equal(git.call_args, (('cat_file', 'abc'), {'s': True}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_should_cache_file_size(self, git):
git.return_value = fixture('cat_file_blob_size')
blob = Blob(self.repo, **{'id': 'abc'})
@@ -56,7 +56,7 @@ class TestBlob(object):
blob = Blob(self.repo, **{'id': 'abc'})
assert_equal("text/plain", blob.mime_type)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_should_display_blame_information(self, git):
git.return_value = fixture('blame')
b = Blob.blame(self.repo, 'master', 'lib/git.py')
diff --git a/test/git/test_commit.py b/test/git/test_commit.py
index ac807dc2..fb887d28 100644
--- a/test/git/test_commit.py
+++ b/test/git/test_commit.py
@@ -11,7 +11,7 @@ class TestCommit(object):
def setup(self):
self.repo = Repo(GIT_REPO)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_bake(self, git):
git.return_value = fixture('rev_list_single')
@@ -24,12 +24,12 @@ class TestCommit(object):
assert_true(git.called)
assert_equal(git.call_args, (('rev_list', '4c8124ffcf4039d292442eeccabdeca5af5c5017'), {'pretty': 'raw', 'max_count': 1}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_id_abbrev(self, git):
git.return_value = fixture('rev_list_commit_idabbrev')
assert_equal('80f136f', self.repo.commit('80f136f500dfdb8c3e8abf4ae716f875f0a1b57f').id_abbrev)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diff(self, git):
git.return_value = fixture('diff_p')
@@ -54,7 +54,7 @@ class TestCommit(object):
assert_true(git.called)
assert_equal(git.call_args, (('diff', 'master'), {'full_index': True}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diff_with_two_commits(self, git):
git.return_value = fixture('diff_2')
@@ -65,7 +65,7 @@ class TestCommit(object):
assert_true(git.called)
assert_equal(git.call_args, (('diff', '59ddc32', '13d27d5'), {'full_index': True}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diff_with_files(self, git):
git.return_value = fixture('diff_f')
@@ -77,7 +77,7 @@ class TestCommit(object):
assert_true(git.called)
assert_equal(git.call_args, (('diff', '59ddc32', '--', 'lib'), {'full_index': True}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diff_with_two_commits_and_files(self, git):
git.return_value = fixture('diff_2f')
@@ -89,7 +89,7 @@ class TestCommit(object):
assert_true(git.called)
assert_equal(git.call_args, (('diff', '59ddc32', '13d27d5', '--', 'lib'), {'full_index': True}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diffs(self, git):
git.return_value = fixture('diff_p')
@@ -117,7 +117,7 @@ class TestCommit(object):
'91169e1f5fa4de2eaea3f176461f5dc784796769',
), {'full_index': True}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diffs_on_initial_import(self, git):
git.return_value = fixture('diff_i')
@@ -144,7 +144,7 @@ class TestCommit(object):
assert_true(git.called)
assert_equal(git.call_args, (('show', '634396b2f541a9f2d58b00be1a07f0c358b999b3'), {'full_index': True, 'pretty': 'raw'}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diffs_on_initial_import_with_empty_commit(self, git):
git.return_value = fixture('show_empty_commit')
@@ -156,7 +156,7 @@ class TestCommit(object):
assert_true(git.called)
assert_equal(git.call_args, (('show', '634396b2f541a9f2d58b00be1a07f0c358b999b3'), {'full_index': True, 'pretty': 'raw'}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diffs_with_mode_only_change(self, git):
git.return_value = fixture('diff_mode_only')
@@ -171,7 +171,7 @@ class TestCommit(object):
assert_true(git.called)
assert_equal(git.call_args, (('show', '91169e1f5fa4de2eaea3f176461f5dc784796769'), {'full_index': True, 'pretty': 'raw'}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_stats(self, git):
git.return_value = fixture('diff_numstat')
diff --git a/test/git/test_git.py b/test/git/test_git.py
index cc732032..5a99dc6e 100644
--- a/test/git/test_git.py
+++ b/test/git/test_git.py
@@ -14,11 +14,11 @@ class TestGit(object):
self.git = Git(base)
@patch(Git, 'execute')
- def test_method_missing_calls_execute(self, git):
+ def test__call_process_calls_execute(self, git):
git.return_value = ''
self.git.version()
assert_true(git.called)
- # assert_equal(git.call_args, ((("%s version " % self.git_bin_base),), {}))
+ assert_equal(git.call_args, ((['git', 'version'],), {}))
@raises(GitCommandError)
def test_it_raises_errors(self):
diff --git a/test/git/test_head.py b/test/git/test_head.py
index 6d32b2d3..d3af3d6b 100644
--- a/test/git/test_head.py
+++ b/test/git/test_head.py
@@ -11,7 +11,7 @@ class TestHead(object):
def setup(self):
self.repo = Repo(GIT_REPO)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_repr(self, git):
git.return_value = fixture('for_each_ref')
diff --git a/test/git/test_repo.py b/test/git/test_repo.py
index 46c5d00c..21b43a88 100644
--- a/test/git/test_repo.py
+++ b/test/git/test_repo.py
@@ -28,7 +28,7 @@ class TestRepo(object):
for head in self.repo.heads:
assert_equal(Head, head.__class__)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_heads_should_populate_head_data(self, git):
git.return_value = fixture('for_each_ref')
@@ -39,7 +39,7 @@ class TestRepo(object):
assert_true(git.called)
assert_equal(git.call_args, (('for_each_ref', 'refs/heads'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_commits(self, git):
git.return_value = fixture('rev_list')
@@ -67,7 +67,7 @@ class TestRepo(object):
assert_true(git.called)
assert_equal(git.call_args, (('rev_list', 'master'), {'skip': 0, 'pretty': 'raw', 'max_count': 10}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_commit_count(self, git):
git.return_value = fixture('rev_list_count')
@@ -76,7 +76,7 @@ class TestRepo(object):
assert_true(git.called)
assert_equal(git.call_args, (('rev_list', 'master'), {}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_commit(self, git):
git.return_value = fixture('rev_list_single')
@@ -87,7 +87,7 @@ class TestRepo(object):
assert_true(git.called)
assert_equal(git.call_args, (('rev_list', '4c8124ffcf4039d292442eeccabdeca5af5c5017'), {'pretty': 'raw', 'max_count': 1}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_tree(self, git):
git.return_value = fixture('ls_tree_a')
@@ -99,7 +99,7 @@ class TestRepo(object):
assert_true(git.called)
assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_blob(self, git):
git.return_value = fixture('cat_file_blob')
@@ -110,7 +110,7 @@ class TestRepo(object):
assert_equal(git.call_args, (('cat_file', 'abc'), {'p': True}))
@patch(Repo, '__init__')
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_init_bare(self, repo, git):
git.return_value = True
@@ -122,7 +122,7 @@ class TestRepo(object):
assert_equal(repo.call_args, (('repos/foo/bar.git',), {}))
@patch(Repo, '__init__')
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_init_bare_with_options(self, repo, git):
git.return_value = True
@@ -134,7 +134,7 @@ class TestRepo(object):
assert_equal(repo.call_args, (('repos/foo/bar.git',), {}))
@patch(Repo, '__init__')
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_fork_bare(self, repo, git):
git.return_value = None
@@ -145,7 +145,7 @@ class TestRepo(object):
assert_true(repo.called)
@patch(Repo, '__init__')
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_fork_bare_with_options(self, repo, git):
git.return_value = None
@@ -156,7 +156,7 @@ class TestRepo(object):
{'bare': True, 'template': '/awesome'}))
assert_true(repo.called)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diff(self, git):
self.repo.diff('master^', 'master')
@@ -173,7 +173,7 @@ class TestRepo(object):
assert_true(git.called)
assert_equal(git.call_args, (('diff', 'master^', 'master', '--', 'foo/bar', 'foo/baz'), {}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_diff(self, git):
git.return_value = fixture('diff_p')
@@ -248,7 +248,7 @@ class TestRepo(object):
def test_repr(self):
assert_equal('<GitPython.Repo "%s/.git">' % os.path.abspath(GIT_REPO), repr(self.repo))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_log(self, git):
git.return_value = fixture('rev_list')
assert_equal('4c8124ffcf4039d292442eeccabdeca5af5c5017', self.repo.log()[0].id)
@@ -257,15 +257,15 @@ class TestRepo(object):
assert_equal(git.call_count, 2)
assert_equal(git.call_args, (('log', 'master'), {'pretty': 'raw'}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_log_with_path_and_options(self, git):
git.return_value = fixture('rev_list')
self.repo.log('master', 'file.rb', **{'max_count': 1})
assert_true(git.called)
assert_equal(git.call_args, (('log', 'master', '--', 'file.rb'), {'pretty': 'raw', 'max_count': 1}))
- # @patch(Git, 'method_missing')
- # @patch(Git, 'method_missing')
+ # @patch(Git, '_call_process')
+ # @patch(Git, '_call_process')
# def test_commit_deltas_from_nothing_new(self, gitb, gita):
# gitb.return_value = fixture("rev_list_delta_b")
# gita.return_value = fixture("rev_list_delta_a")
diff --git a/test/git/test_tag.py b/test/git/test_tag.py
index 6626ec65..2f915b8d 100644
--- a/test/git/test_tag.py
+++ b/test/git/test_tag.py
@@ -12,7 +12,7 @@ class TestTag(object):
def setup(self):
self.repo = Repo(GIT_REPO)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_list_from_string(self, git):
git.return_value = fixture('for_each_ref_tags')
@@ -25,7 +25,7 @@ class TestTag(object):
assert_true(git.called)
assert_equal(git.call_args, (('for_each_ref', 'refs/tags'), {'sort': 'committerdate', 'format': '%(refname)%00%(objectname)'}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_repr(self, git):
git.return_value = fixture('for_each_ref')
diff --git a/test/git/test_tree.py b/test/git/test_tree.py
index 2c7fdd58..957b8962 100644
--- a/test/git/test_tree.py
+++ b/test/git/test_tree.py
@@ -12,7 +12,7 @@ class TestTree(object):
self.repo = Repo(GIT_REPO)
self.tree = Tree(self.repo)
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_contents_should_cache(self, git):
git.return_value = fixture('ls_tree_a') + fixture('ls_tree_b')
@@ -56,7 +56,7 @@ class TestTree(object):
self.tree.content_from_string(None, "040000 bogus 650fa3f0c17f1edb4ae53d8dcca4ac59d86e6c44 test")
@patch(Blob, 'size')
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_slash(self, blob, git):
git.return_value = fixture('ls_tree_a')
blob.return_value = 1
@@ -70,7 +70,7 @@ class TestTree(object):
assert_equal(git.call_args, (('ls_tree', 'master'), {}))
@patch(Blob, 'size')
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_slash_with_zero_length_file(self, blob, git):
git.return_value = fixture('ls_tree_a')
blob.return_value = 0
@@ -83,7 +83,7 @@ class TestTree(object):
assert_true(git.called)
assert_equal(git.call_args, (('ls_tree', 'master'), {}))
- @patch(Git, 'method_missing')
+ @patch(Git, '_call_process')
def test_slash_with_commits(self, git):
git.return_value = fixture('ls_tree_commit')