Skip to content
This repository was archived by the owner on Dec 31, 2024. It is now read-only.

Python3 support #60

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 32 additions & 5 deletions pyserpent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,12 @@
#include <iostream>
#include "funcs.h"

#if PY_MAJOR_VERSION >= 3
#define PY_STRING_FORMAT "y#"
#else
#define PY_STRING_FORMAT "s#"
#endif

#define PYMETHOD(name, FROM, method, TO) \
static PyObject * name(PyObject *, PyObject *args) { \
try { \
Expand Down Expand Up @@ -32,7 +38,7 @@
#define FROMSTR(v) \
const char *command; \
int len; \
if (!PyArg_ParseTuple(args, "s#", &command, &len)) \
if (!PyArg_ParseTuple(args, PY_STRING_FORMAT, &command, &len)) \
return NULL; \
std::string v = std::string(command, len); \

Expand All @@ -41,7 +47,7 @@
int len1; \
const char *command2; \
int len2; \
if (!PyArg_ParseTuple(args, "s#s#", &command1, &len1, &command2, &len2)) \
if (!PyArg_ParseTuple(args, PY_STRING_FORMAT PY_STRING_FORMAT, &command1, &len1, &command2, &len2)) \
return NULL; \
std::string a1##v = std::string(command1, len1); \
std::string a2##v = std::string(command2, len2); \
Expand All @@ -61,7 +67,7 @@
// Convert metadata into python wrapper form [file, ln, ch]
PyObject* pyifyMetadata(Metadata m) {
PyObject* a = PyList_New(0);
PyList_Append(a, Py_BuildValue("s#", m.file.c_str(), m.file.length()));
PyList_Append(a, Py_BuildValue(PY_STRING_FORMAT, m.file.c_str(), m.file.length()));
PyList_Append(a, Py_BuildValue("i", m.ln));
PyList_Append(a, Py_BuildValue("i", m.ch));
return a;
Expand All @@ -72,7 +78,7 @@ PyObject* pyifyMetadata(Metadata m) {
PyObject* pyifyNode(Node n) {
PyObject* a = PyList_New(0);
PyList_Append(a, Py_BuildValue("i", n.type == ASTNODE));
PyList_Append(a, Py_BuildValue("s#", n.val.c_str(), n.val.length()));
PyList_Append(a, Py_BuildValue(PY_STRING_FORMAT, n.val.c_str(), n.val.length()));
PyList_Append(a, pyifyMetadata(n.metadata));
for (unsigned i = 0; i < n.args.size(); i++)
PyList_Append(a, pyifyNode(n.args[i]));
Expand All @@ -81,7 +87,7 @@ PyObject* pyifyNode(Node n) {

// Convert string into python wrapper form
PyObject* pyifyString(std::string s) {
return Py_BuildValue("s#", s.c_str(), s.length());
return Py_BuildValue(PY_STRING_FORMAT, s.c_str(), s.length());
}

// Convert integer into python wrapper form
Expand All @@ -108,8 +114,13 @@ int cppifyInt(PyObject* o) {
// Convert pyobject string into normal form
std::string cppifyString(PyObject* o) {
const char *command;
#if PY_MAJOR_VERSION >= 3
if (!PyArg_Parse(o, "y", &command))
err("Argument should be bytes", Metadata());
#else
if (!PyArg_Parse(o, "s", &command))
err("Argument should be string", Metadata());
#endif
return std::string(command);
}

Expand Down Expand Up @@ -190,7 +201,23 @@ static PyMethodDef PyextMethods[] = {
{NULL, NULL, 0, NULL} /* Sentinel */
};

#if PY_MAJOR_VERSION >= 3
static struct PyModuleDef SerpentModule = {
PyModuleDef_HEAD_INIT,
"serpent_pyext",
"...",
-1,
PyextMethods
};

PyMODINIT_FUNC PyInit_serpent_pyext(void) {
return PyModule_Create(&SerpentModule);
}

#else
PyMODINIT_FUNC initserpent_pyext(void)
{
Py_InitModule( "serpent_pyext", PyextMethods );
}
#endif

58 changes: 34 additions & 24 deletions serpent.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,14 @@
import serpent_pyext as pyext
import sys, re
import binascii

VERSION = '1.8.0'

def strtobytes(x):
return x.encode('ascii') if isinstance(x, str) else x

def bytestostr(x):
return x.decode('ascii') if isinstance(x, bytes) else x

class Metadata(object):
def __init__(self, li):
Expand All @@ -23,7 +29,7 @@ def out(self):
return [0, self.val, self.metadata.out()]

def __repr__(self):
return str(self.val)
return str(bytestostr(self.val))


class Astnode(object):
Expand All @@ -37,8 +43,8 @@ def out(self):
return o

def __repr__(self):
o = '(' + self.val
subs = map(repr, self.args)
o = '(' + bytestostr(self.val)
subs = list(map(bytestostr, map(repr, self.args)))
k = 0
out = " "
while k < len(subs) and o != "(seq":
Expand All @@ -63,24 +69,28 @@ def node(li):


def take(x):
return pyext.parse_lll(x) if isinstance(x, (str, unicode)) else x.out()

if sys.version_info[0] < 3:
return pyext.parse_lll(x) if isinstance(x, (str, unicode)) else x.out()
else:
return pyext.parse_lll(x) if isinstance(x, (str, bytes)) else x.out()

def takelist(x):
return map(take, parse(x).args if isinstance(x, (str, unicode)) else x)


compile = lambda x: pyext.compile(x)
compile_to_lll = lambda x: node(pyext.compile_to_lll(x))
compile_lll = lambda x: pyext.compile_lll(take(x))
parse = lambda x: node(pyext.parse(x))
rewrite = lambda x: node(pyext.rewrite(take(x)))
pretty_compile = lambda x: map(node, pyext.pretty_compile(x))
pretty_compile_lll = lambda x: map(node, pyext.pretty_compile_lll(take(x)))
serialize = lambda x: pyext.serialize(takelist(x))
deserialize = lambda x: map(node, pyext.deserialize(x))
mk_signature = lambda x: pyext.mk_signature(x)
mk_full_signature = lambda x: pyext.mk_full_signature(x)
if sys.version_info[0] < 3:
return map(take, parse(x).args if isinstance(x, (str, unicode)) else x)
else:
return map(take, parse(x).args if isinstance(x, (str, bytes)) else x)

compile = lambda x: pyext.compile(strtobytes(x))
compile_to_lll = lambda x: node(pyext.compile_to_lll(strtobytes(x)))
compile_lll = lambda x: pyext.compile_lll(take(strtobytes(x)))
parse = lambda x: node(pyext.parse(strtobytes(x)))
rewrite = lambda x: node(pyext.rewrite(take(strtobytes(x))))
pretty_compile = lambda x: map(node, pyext.pretty_compile(strtobytes(x)))
pretty_compile_lll = lambda x: map(node, pyext.pretty_compile_lll(take(strtobytes(x))))
serialize = lambda x: pyext.serialize(takelist(strtobytes(x)))
deserialize = lambda x: map(node, pyext.deserialize(strtobytes(x)))
mk_signature = lambda x: pyext.mk_signature(strtobytes(x))
mk_full_signature = lambda x: pyext.mk_full_signature(strtobytes(x))
get_prefix = lambda x, y: pyext.get_prefix(x, y) % 2**32

is_numeric = lambda x: isinstance(x, (int, long))
Expand Down Expand Up @@ -168,13 +178,13 @@ def decode_abi(arr, *lens):

def main():
if len(sys.argv) == 1:
print "serpent <command> <arg1> <arg2> ..."
print("serpent <command> <arg1> <arg2> ...")
else:
cmd = sys.argv[2] if sys.argv[1] == '-s' else sys.argv[1]
if sys.argv[1] == '-s':
args = [sys.stdin.read()] + sys.argv[3:]
elif sys.argv[1] == '-v':
print VERSION
print(VERSION)
sys.exit()
else:
cmd = sys.argv[1]
Expand All @@ -186,8 +196,8 @@ def main():
kwargs['source'] = 'cmdline'
o = globals()[cmd](*args, **kwargs)
if isinstance(o, (Token, Astnode, list)):
print repr(o)
print(repr(o))
elif cmd in ['mk_signature', 'mk_full_signature', 'get_prefix']:
print o
print(o)
else:
print o.encode('hex')
print(binascii.b2a_hex(o).decode('ascii'))