Skip to content

Commit

Permalink
Add support for pypy
Browse files Browse the repository at this point in the history
Fortunately pypy provides support for a lot of the CPython API, so the
changes are minimal.

The most important changes are:

- constructors always get a keyword argument dictionary, even if no
  keyword arguments are passed

- trying to assign to a read-only attribute raises TypeError instead of
  AttributeError

Apart from that, pypy does not provide MAXPATHLEN. There is a hack in
place currently, but there is only place that's using that macro, and
there shouldn't be a need for it much longer.

This fixes #209.
  • Loading branch information
carlosmn committed Jan 26, 2014
1 parent 1cc112c commit 30084e0
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 14 deletions.
2 changes: 1 addition & 1 deletion src/config.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Config_init(Config *self, PyObject *args, PyObject *kwds)
char *path = NULL;
int err;

if (kwds) {
if (kwds && PyDict_Size(kwds) > 0) {
PyErr_SetString(PyExc_TypeError,
"Config takes no keyword arguments");
return -1;
Expand Down
2 changes: 1 addition & 1 deletion src/index.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Index_init(Index *self, PyObject *args, PyObject *kwds)
char *path;
int err;

if (kwds) {
if (kwds && PyDict_Size(kwds) > 0) {
PyErr_SetString(PyExc_TypeError, "Index takes no keyword arguments");
return -1;
}
Expand Down
12 changes: 11 additions & 1 deletion src/pygit2.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,24 @@

#define PY_SSIZE_T_CLEAN
#include <Python.h>
#include <osdefs.h>

/* Pypy does not provide this header */
#ifndef PYPY_VERSION
# include <osdefs.h>
#endif

#include <git2.h>
#include "error.h"
#include "types.h"
#include "utils.h"
#include "repository.h"
#include "oid.h"

/* FIXME: This is for pypy */
#ifndef MAXPATHLEN
# define MAXPATHLEN 1024
#endif

extern PyObject *GitError;

extern PyTypeObject RepositoryType;
Expand Down
2 changes: 1 addition & 1 deletion src/repository.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ Repository_init(Repository *self, PyObject *args, PyObject *kwds)
char *path;
int err;

if (kwds) {
if (kwds && PyDict_Size(kwds) > 0) {
PyErr_SetString(PyExc_TypeError,
"Repository takes no keyword arguments");
return -1;
Expand Down
19 changes: 13 additions & 6 deletions test/test_commit.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
from pygit2 import GIT_OBJ_COMMIT, Signature, Oid
from . import utils

# pypy raises TypeError on writing to read-only, so we need to check
# and change the test accordingly
try:
import __pypy__
except ImportError:
__pypy__ = None

COMMIT_SHA = '5fe808e8953c12735680c257f56600cb0de44b10'

Expand Down Expand Up @@ -131,12 +137,13 @@ def test_modify_commit(self):
author = ('Jane Doe', 'jdoe2@example.com', 12345)

commit = self.repo[COMMIT_SHA]
self.assertRaises(AttributeError, setattr, commit, 'message', message)
self.assertRaises(AttributeError, setattr, commit, 'committer',
committer)
self.assertRaises(AttributeError, setattr, commit, 'author', author)
self.assertRaises(AttributeError, setattr, commit, 'tree', None)
self.assertRaises(AttributeError, setattr, commit, 'parents', None)

error_type = AttributeError if not __pypy__ else TypeError
self.assertRaises(error_type, setattr, commit, 'message', message)
self.assertRaises(error_type, setattr, commit, 'committer', committer)
self.assertRaises(error_type, setattr, commit, 'author', author)
self.assertRaises(error_type, setattr, commit, 'tree', None)
self.assertRaises(error_type, setattr, commit, 'parents', None)


if __name__ == '__main__':
Expand Down
15 changes: 11 additions & 4 deletions test/test_tag.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
import pygit2
from . import utils

# pypy raises TypeError on writing to read-only, so we need to check
# and change the test accordingly
try:
import __pypy__
except ImportError:
__pypy__ = None

TAG_SHA = '3d2962987c695a29f1f80b6c3aa4ec046ef44369'

Expand Down Expand Up @@ -84,10 +90,11 @@ def test_modify_tag(self):
tagger = ('John Doe', 'jdoe@example.com', 12347)

tag = self.repo[TAG_SHA]
self.assertRaises(AttributeError, setattr, tag, 'name', name)
self.assertRaises(AttributeError, setattr, tag, 'target', target)
self.assertRaises(AttributeError, setattr, tag, 'tagger', tagger)
self.assertRaises(AttributeError, setattr, tag, 'message', message)
error_type = AttributeError if not __pypy__ else TypeError
self.assertRaises(error_type, setattr, tag, 'name', name)
self.assertRaises(error_type, setattr, tag, 'target', target)
self.assertRaises(error_type, setattr, tag, 'tagger', tagger)
self.assertRaises(error_type, setattr, tag, 'message', message)

def test_get_object(self):
repo = self.repo
Expand Down

0 comments on commit 30084e0

Please sign in to comment.