Asked because of this: Default argument in c++
Say I have a function such as this: void f(int p1=1, int p2=2, int p3=3, int p4=4);
And I want to call it using only some of the arguments - the rest will be the defaults.
Something like this would work:
template<bool P1=true, bool P2=true, bool P3=true, bool P4=true>
void f(int p1=1, int p2=2, int p3=3, int p4=4);
// specialize:
template<>
void f<false, true, false, false>(int p1) {
f(1, p1);
}
template<>
void f<false, true, true, false>(int p1, int p2) {
f(1, p1, p2);
}
// ... and so on.
// Would need a specialization for each combination of arguments
// which is very tedious and error-prone
// Use:
f<false, true, false, false>(5); // passes 5 as p2 argument
But it requires too much code to be practical.
Is there a better way to do this?
Use the Named Parameters Idiom (→ FAQ link).
The Boost.Parameters library (→ link) can also solve this task, but paid for by code verbosity and greatly reduced clarity. It's also deficient in handling constructors. And it requires having the Boost library installed, of course.
Have a look at the Boost.Parameter library.
It implements named paramaters in C++. Example:
#include <boost/parameter/name.hpp>
#include <boost/parameter/preprocessor.hpp>
#include <iostream>
//Define
BOOST_PARAMETER_NAME(p1)
BOOST_PARAMETER_NAME(p2)
BOOST_PARAMETER_NAME(p3)
BOOST_PARAMETER_NAME(p4)
BOOST_PARAMETER_FUNCTION(
(void),
f,
tag,
(optional
(p1, *, 1)
(p2, *, 2)
(p3, *, 3)
(p4, *, 4)))
{
std::cout << "p1: " << p1
<< ", p2: " << p2
<< ", p3: " << p3
<< ", p4: " << p4 << "\n";
}
//Use
int main()
{
//Prints "p1: 1, p2: 5, p3: 3, p4: 4"
f(_p2=5);
}
Although Boost.Parameters is amusing, it suffers (unfortunately) for a number of issues, among which placeholder collision (and having to debug quirky preprocessors/template errors):
BOOST_PARAMETER_NAME(p1)
Will create the _p1 placeholder that you then use later on. If you have two different headers declaring the same placeholder, you get a conflict. Not fun.
There is a much simpler (both conceptually and practically) answer, based on the Builder Pattern somewhat is the Named Parameters Idiom.
Instead of specifying such a function:
void f(int a, int b, int c = 10, int d = 20);
You specify a structure, on which you will override the operator():
the constructor is used to ask for mandatory arguments (not strictly in the Named Parameters Idiom, but nobody said you had to follow it blindly), and default values are set for the optional ones
each optional parameter is given a setter
Generally, it is combined with Chaining which consists in making the setters return a reference to the current object so that the calls can be chained on a single line.
class f {
public:
// Take mandatory arguments, set default values
f(int a, int b): _a(a), _b(b), _c(10), _d(20) {}
// Define setters for optional arguments
// Remember the Chaining idiom
f& c(int v) { _c = v; return *this; }
f& d(int v) { _d = v; return *this; }
// Finally define the invocation function
void operator()() const;
private:
int _a;
int _b;
int _c;
int _d;
}; // class f
The invocation is:
f(/*a=*/1, /*b=*/2).c(3)(); // the last () being to actually invoke the function
I've seen a variant putting the mandatory arguments as parameters to operator(), this avoids keeping the arguments as attributes but the syntax is a bit weirder:
f().c(3)(/*a=*/1, /*b=*/2);
Once the compiler has inlined all the constructor and setters call (which is why they are defined here, while operator() is not), it should result in similarly efficient code compared to the "regular" function invocation.
This isn't really an answer, but...
In C++ Template Metaprogramming by David Abrahams and Aleksey Gurtovoy (published in 2004!) the authors talk about this:
While writing this book, we reconsidered the interface used for named
function parameter support. With a little experimentation we
discovered that it’s possible to provide the ideal syntax by using
keyword objects with overloaded assignment operators:
f(slew = .799, name = "z");
They go on to say:
We’re not going to get into the implementation details of this named
parameter library here; it’s straightforward enough that we suggest
you try implementing it yourself as an exercise.
This was in the context of template metaprogramming and Boost::MPL. I'm not too sure how their "straighforward" implementation would jive with default parameters, but I assume it would be transparent.
Related
I'm struggling how to create a python Enum object inside the Python C API. The enum class has assigned tp_base to PyEnum_Type, so it inherits Enum. But, I can't figure out a way to tell the Enum base class what items are in the enum. I want to allow iteration and lookup from Python using the __members__ attribute that every Python Enum provides.
Thank you,
Jelle
It is not straightforward at all. The Enum is a Python class using a Python metaclass. It is possible to create it in C but it will be just emulating the constructing Python code in C - the end result is the same and while it speeds up things slightly, you'll most probably run the code only once within each program run.
In any case it is possible, but it is not easy at all. I'll show how to do it in Python:
from enum import Enum
class Color(Enum):
RED = 1
GREEN = 2
BLUE = 3
print(Color)
print(Color.RED)
is the same as:
from enum import Enum
name = 'Color'
bases = (Enum,)
enum_meta = type(Enum)
namespace = enum_meta.__prepare__(name, bases)
namespace['RED'] = 1
namespace['GREEN'] = 2
namespace['BLUE'] = 3
Color = enum_meta(name, bases, namespace)
print(Color)
print(Color.RED)
The latter is the code that you need to translate into C.
Edited note: An answer on a very similar question details how enum.Enum has a functional interface that can be used instead. That is almost certainly the correct approach. I think my answer here is a useful alternative approach to be aware of, although it probably isn't the best solution to this problem.
I'm aware that this answer is slightly cheating, but this is exactly the kind of code that's better written in Python, and in the C API we still have access to the full Python interpreter. My reasoning for this is that the main reason to keep things entirely in C is performance, and it seems unlikely that creating enum objects will be performance critical.
I'll give three versions, essentially depending on the level of complexity.
First, the simplest case: the enum is entirely known and defined and compile-time. Here we simply set up an empty global dict, run the Python code, then extract the enum from the global dict:
PyObject* get_enum(void) {
const char str[] = "from enum import Enum\n"
"class Colour(Enum):\n"
" RED = 1\n"
" GREEN = 2\n"
" BLUE = 3\n"
"";
PyObject *global_dict=NULL, *should_be_none=NULL, *output=NULL;
global_dict = PyDict_New();
if (!global_dict) goto cleanup;
should_be_none = PyRun_String(str, Py_file_input, global_dict, global_dict);
if (!should_be_none) goto cleanup;
// extract Color from global_dict
output = PyDict_GetItemString(global_dict, "Colour");
if (!output) {
// PyDict_GetItemString does not set exceptions
PyErr_SetString(PyExc_KeyError, "could not get 'Colour'");
} else {
Py_INCREF(output); // PyDict_GetItemString returns a borrow reference
}
cleanup:
Py_XDECREF(global_dict);
Py_XDECREF(should_be_none);
return output;
}
Second, we might want to change what we define in C at runtime. For example, maybe the input parameters pick the enum values. Here, I'm going to use string formatting to insert the appropriate values into our string. There's a number of options here: sprintf, PyBytes_Format, the C++ standard library, using Python strings (perhaps with another call into Python code?). Pick whichever you're most comfortable with.
PyObject* get_enum_fmt(int red, int green, int blue) {
const char str[] = "from enum import Enum\n"
"class Colour(Enum):\n"
" RED = %d\n"
" GREEN = %d\n"
" BLUE = %d\n"
"";
PyObject *formatted_str=NULL, *global_dict=NULL, *should_be_none=NULL, *output=NULL;
formatted_str = PyBytes_FromFormat(str, red, green, blue);
if (!formatted_str) goto cleanup;
global_dict = PyDict_New();
if (!global_dict) goto cleanup;
should_be_none = PyRun_String(PyBytes_AsString(formatted_str), Py_file_input, global_dict, global_dict);
if (!should_be_none) goto cleanup;
// extract Color from global_dict
output = PyDict_GetItemString(global_dict, "Colour");
if (!output) {
// PyDict_GetItemString does not set exceptions
PyErr_SetString(PyExc_KeyError, "could not get 'Colour'");
} else {
Py_INCREF(output); // PyDict_GetItemString returns a borrow reference
}
cleanup:
Py_XDECREF(formatted_str);
Py_XDECREF(global_dict);
Py_XDECREF(should_be_none);
return output;
}
Obviously you can do as much or as little as you like with string formatting - I've just picked a simple example to show the point. The main differences from the previous version are the call to PyBytes_FromFormat to set up the string, and the call to PyBytes_AsString that gets the underlying char* out of the prepared bytes object.
Finally, we could prepare the enum attributes in C Python dict and pass it in. This necessitates a bit of a change. Essentially I use #AnttiHaapala's lower-level Python code, but insert namespace.update(contents) after the call to __prepare__.
PyObject* get_enum_dict(const char* key1, int value1, const char* key2, int value2) {
const char str[] = "from enum import Enum\n"
"name = 'Colour'\n"
"bases = (Enum,)\n"
"enum_meta = type(Enum)\n"
"namespace = enum_meta.__prepare__(name, bases)\n"
"namespace.update(contents)\n"
"Colour = enum_meta(name, bases, namespace)\n";
PyObject *global_dict=NULL, *contents_dict=NULL, *value_as_object=NULL, *should_be_none=NULL, *output=NULL;
global_dict = PyDict_New();
if (!global_dict) goto cleanup;
// create and fill the contents dictionary
contents_dict = PyDict_New();
if (!contents_dict) goto cleanup;
value_as_object = PyLong_FromLong(value1);
if (!value_as_object) goto cleanup;
int set_item_result = PyDict_SetItemString(contents_dict, key1, value_as_object);
Py_CLEAR(value_as_object);
if (set_item_result!=0) goto cleanup;
value_as_object = PyLong_FromLong(value2);
if (!value_as_object) goto cleanup;
set_item_result = PyDict_SetItemString(contents_dict, key2, value_as_object);
Py_CLEAR(value_as_object);
if (set_item_result!=0) goto cleanup;
set_item_result = PyDict_SetItemString(global_dict, "contents", contents_dict);
if (set_item_result!=0) goto cleanup;
should_be_none = PyRun_String(str, Py_file_input, global_dict, global_dict);
if (!should_be_none) goto cleanup;
// extract Color from global_dict
output = PyDict_GetItemString(global_dict, "Colour");
if (!output) {
// PyDict_GetItemString does not set exceptions
PyErr_SetString(PyExc_KeyError, "could not get 'Colour'");
} else {
Py_INCREF(output); // PyDict_GetItemString returns a borrow reference
}
cleanup:
Py_XDECREF(contents_dict);
Py_XDECREF(global_dict);
Py_XDECREF(should_be_none);
return output;
}
Again, this presents a reasonably flexible way to get values from C into a generated enum.
For the sake of testing I used the follow simple Cython wrapper - this is just presented for completeness to help people try these functions.
cdef extern from "cenum.c":
object get_enum()
object get_enum_fmt(int, int, int)
object get_enum_dict(char*, int, char*, int)
def py_get_enum():
return get_enum()
def py_get_enum_fmt(red, green, blue):
return get_enum_fmt(red, green, blue)
def py_get_enum_dict(key1, value1, key2, value2):
return get_enum_dict(key1, value1, key2, value2)
To reiterate: this answer is only partly in the C API, but the approach of calling Python from C is one that I've found productive at times for "run-once" code that would be tricky to write entirely in C.
In python you can do list[2:] to get every element after the second element. Is there any way to do the same thing with an array in c++?
I hope I figured an acceptable answer. Unfortunately in C++, you cannot overload operator[] with more than one argument so I used operator() instead.
#include <iostream>
#include <vector>
template <typename T>
class WrapperVector
{
private:
std::vector<T> data;
public:
WrapperVector(size_t reserve_size)
{
data.reserve(reserve_size);
}
WrapperVector(typename std::vector<T>::iterator start, typename std::vector<T>::iterator end)
{
data = std::vector<T>(start, end);
}
// appends element to the end of container, just like in Python
void append(T element)
{
data.push_back(element);
}
/* instead of operator[], operator() must be used
because operator[] can't accept more than one argument */
// instead of self[x:y], use this(x, y)
WrapperVector<T> operator()(size_t start, size_t end)
{
return WrapperVector<T>(data.begin() + start, data.begin() + end);
}
// instead of self[x:], use this(x)
WrapperVector<T> operator()(size_t start)
{
return WrapperVector<T>(data.begin() + start, data.end());
}
// prints all elements to cout
void print()
{
if (!data.size())
{
std::cout << "No elements.\n";
return;
}
std::cout << data[0];
size_t length = data.size();
for(size_t i=1; i < length; i++)
std::cout << ' ' << data[i];
std::cout << '\n';
}
};
int main()
{
WrapperVector<int> w(5);
w.append(1);
w.append(2);
w.append(3);
w.append(4);
w.append(5);
w(0).print();
w(1, 3).print();
// you can also save the slice
WrapperVector<int> w2 = w(2);
WrapperVector<int> w3 = w(2, 4);
w2.print();
w3.print();
return 0;
}
Now you could even overload it to accept three arguments to account for the step, just like in Python. I let that as an exercise to you.
Instead of creating a custom class that introduces some amount of maintenance and certain limitations you can use the concept of iterators. Two iterators are used to represent a range of values. For example the function
template<typename TIterator>
foo(TIterator start, TIterator end);
would take a range of objects that is only specified by two iterators. It's a template, so it can take iterators from different containers. To select a sub-range from a range given this way you can use std::next() and std::prev(). For example for a
std::vector<int> list;
you can call foo with a subrange starting from third element as:
foo(std::next(list.begin(), 2), list.end());
or call foo with a subrange from the third to the second last element:
foo(std::next(list.begin(), 2), std::prev(list.end(), 1));
If you need/want to copy a subrange you can easily do that. For example
std::vector<int> subList(std::next(list.begin(), 2),
std::prev(list.end(), 1));
would create a vector sublist that contains the third to second last element from list.
Of cause those are just simple examples. In a real world application you need to check if those subranges are valid/exist.
The advantages are:
no extra wrapper classes
no need to copy any data (only the iterators themselves)
the standard library works almost exclusively with iterators to represent ranges, so it's good to stick to that concept.
With templates you can easily support all containers in the standard library as long as their iterators satisfy the requirements listed in the reference. (You could use the above examples with std::array, std::list and most other containers without any modifications, except for the type of list of cause)
iterators are an interface for user or third party containers, as long as they provide iterators that satisfy the requirements listed in the reference.
On the contra side:
the code gets a bit more complex
it may take some time to understand iterators, because it's a quite different concept than other languages use.
How does one go about to parse a group of required but mutually exclusive arguments using the python C-api?
E.g. given the function definition
static PyObject* my_func(PyObject *self, PyObject *args, PyObject *kwargs) {
double a; // first argument, required
double b=0, c=0; // second argument, required but mutually exclusive, b is default keyword if no keyword is set
char d[] = "..."; // third argument, optional
// parse arguments
...
}
My idea here was to parse the input arguments twice, i.e. replacing ... above with:
static const char *kwList1[] = {"a","b","c","d"};
static const char *kwList2[] = {"a","b","d"};
int ret;
if (!(ret = PyArg_ParseTupleAndKeywords(args,kwargs,"d|dds",(char **)kwList1,&a,&b,&c,&d))) {
ret = PyArg_ParseTupleAndKeywords(args,kwargs,"d|ds",(char **)kwList2,&a,&b,&d));
}
if (!ret) return NULL;
// verify that one of, but not both, variables b and c are non-zero
...
However, the second call to PyArg_ParseTupleAndKeywords() returns 0 for valid input so I assume here that the variables args and kwargs have some attributes set by the first call to PyArg_ParseTupleAndKeywords() that causes the second call to fail (output python error is: TypeError: a float is required).
I'm aware that the above could be solved using the argparse python module but would prefer a solution directly using the C-api. One idea here would be if it were possible to first copy of the input args and kwargs into two new PyObject variables and use these in the second call to PyArg_ParseTupleAndKeywords(), however I can't find any api-function to do so (guess I also would need to know howto release the memory allocated for this).
Seems like the issue were that the first call to PyArg_ParseTupleAndKeywords() set the error indicator which caused the second call to the function to fail. So the solution is to insert a call to PyErr_Clear() between the calls to PyArg_ParseTupleAndKeywords(). In summary, the following code performs the task
static PyObject* my_func(PyObject *self, PyObject *args, PyObject *kwargs) {
double a; // first argument, required
double b=0, c=0; // second argument, required but mutually exclusive, b is default keyword if no keyword is set
char d[] = "..."; // third argument, optional
// parse arguments
static const char *kwList1[] = {"a","b","c","d"};
static const char *kwList2[] = {"a","b","d"};
int ret;
if (!(ret = PyArg_ParseTupleAndKeywords(args,kwargs,"d|dds",(char **)kwList1,&a,&b,&c,&d))) {
PyErr_Clear();
ret = PyArg_ParseTupleAndKeywords(args,kwargs,"d|ds",(char **)kwList2,&a,&b,&d));
}
if (!ret) return NULL;
// verify that one of, but not both, variables b and c are non-zero
if (b==0 && c==0) {
PyErr_SetString(PyExc_TypeError,"Required mutually exclusive arguments 'b' or 'c' (pos 2) not found (or input with value 0)");
return NULL;
} else if (b!=0 && c!=0) {
PyErr_SetString(PyExc_TypeError,"Use of multiple mutually exclusive required arguments 'b' and 'c' (pos 2)");
return NULL;
}
...
}
Then again this does not guard against the calling the function with both the arguments b and c given that one of them is 0 and the other not. However this is a minor problem.
I am trying to find (line and column position) all the references of a specific function declaration when parsing a C++ source file via libclang in Python.
For example:
#include <iostream>
using namespace std;
int addition (int a, int b)
{
int r;
r=a+b;
return r;
}
int main ()
{
int z, q;
z = addition (5,3);
q = addition (5,5);
cout << "The first result is " << z;
cout << "The second result is " << q;
}
So, for the source file above, I would like for the function declaration for addition in line 5, I would like the find_all_function_decl_references(see below) to return the references of addition at lines 15 and 16.
I have tried this (adapted from here)
import clang.cindex
import ccsyspath
index = clang.cindex.Index.create()
translation_unit = index.parse(filename, args=args)
for node in translation_unit.cursor.walk_preorder():
node_definition = node.get_definition()
if node.location.file is None:
continue
if node.location.file.name != sourcefile:
continue
if node_def is None:
pass
if node.kind.name == 'FUNCTION_DECL':
if node.kind.is_reference():
find_all_function_decl_references(node_definition.displayname) # TODO
Another approach could be to store all the function declarations found on a list and run the find_all_function_decl_references method on each.
Does anyone has any idea of how to approach this? How this find_all_function_decl_references method would be? (I am very new with libclang and Python.)
I have seen this where the def find_typerefs is finding all references to some type but I am not sure how to implement it for my needs.
Ideally, I would like to be able to fetch all references for any declaration; not only functions but variable declarations, parameter declarations (e.g. the a and b in the example above in line 7), class declarations etc.
EDIT
Following Andrew's comment, here are some details regarding my setup specifications:
LLVM 3.8.0-win64
libclang-py3 3.8.1
Python3.5.1 (in Windows, I assume CPython)
For the args, I tried both the ones suggested in the answer here and the ones from another answer.
*Please note, given my small programming experience I could appreciate an answer with a brief explanation of how it works.
The thing that really makes this problem challenging is the complexity of C++.
Consider what is callable in C++: functions, lambdas, the function call operator, member functions, template functions and member template functions. So in the case of just matching call expressions, you'd need to be able to disambiguate these cases.
Furthermore, libclang doesn't offer a perfect view of the clang AST (some nodes don't get exposed completely, particularly some nodes related to templates). Consequently, it's possible (even likely) that an arbitrary code fragment would contain some construct where libclangs view of the AST was insufficient to associate the call expression with a declaration.
However, if you're prepared to restrict yourself to a subset of the language it may be possible to make some headway - for example, the following sample tries to associate call sites with function declarations. It does this by doing a single pass over all the nodes in the AST matching function declarations with call expressions.
from clang.cindex import *
def is_function_call(funcdecl, c):
""" Determine where a call-expression cursor refers to a particular function declaration
"""
defn = c.get_definition()
return (defn is not None) and (defn == funcdecl)
def fully_qualified(c):
""" Retrieve a fully qualified function name (with namespaces)
"""
res = c.spelling
c = c.semantic_parent
while c.kind != CursorKind.TRANSLATION_UNIT:
res = c.spelling + '::' + res
c = c.semantic_parent
return res
def find_funcs_and_calls(tu):
""" Retrieve lists of function declarations and call expressions in a translation unit
"""
filename = tu.cursor.spelling
calls = []
funcs = []
for c in tu.cursor.walk_preorder():
if c.location.file is None:
pass
elif c.location.file.name != filename:
pass
elif c.kind == CursorKind.CALL_EXPR:
calls.append(c)
elif c.kind == CursorKind.FUNCTION_DECL:
funcs.append(c)
return funcs, calls
idx = Index.create()
args = '-x c++ --std=c++11'.split()
tu = idx.parse('tmp.cpp', args=args)
funcs, calls = find_funcs_and_calls(tu)
for f in funcs:
print(fully_qualified(f), f.location)
for c in calls:
if is_function_call(f, c):
print('-', c)
print()
To show how well this works, you need a slightly more challenging example to parse:
// tmp.cpp
#include <iostream>
using namespace std;
namespace impl {
int addition(int x, int y) {
return x + y;
}
void f() {
addition(2, 3);
}
}
int addition (int a, int b) {
int r;
r=a+b;
return r;
}
int main () {
int z, q;
z = addition (5,3);
q = addition (5,5);
cout << "The first result is " << z;
cout << "The second result is " << q;
}
And I get the output:
impl::addition
- <SourceLocation file 'tmp.cpp', line 10, column 9>
impl::f
addition
- <SourceLocation file 'tmp.cpp', line 22, column 7>
- <SourceLocation file 'tmp.cpp', line 23, column 7>
main
Scaling this up to consider more types of declarations would (IMO) be non-trivial and an interesting project in it's own right.
Addressing comments
Given that there are some questions about whether the code in this answer produces the results I've provided, I've added a gist of the code (that reproduces the content of this question) and a very minimal vagrant machine image that you can use to experiment with. Once the machine is booted you can clone the gist, and reproduce the answer with the commands:
git clone https://gist.github.com/AndrewWalker/daa2af23f34fe9a6acc2de579ec45535 find-func-decl-refs
cd find-func-decl-refs
export LD_LIBRARY_PATH=/usr/lib/llvm-3.8/lib/ && python3 main.py
I want to use Boost.Python to create a Python wrapper for a C++ constructor with optional arguments. I want the Python wrapper to act like this:
class Foo():
def __init__(self, filename, phase, stages=None, level=0):
"""
filename -- string
phase -- int
stages -- optional list of strings
level -- optional int
"""
if stages is None:
stages = []
# ...
How do I do this with Boost.Python? I don't see how to do it with make_constructor, and I don't know how to make a constructor with raw_function. Is there some better documentation than this out there?
My specific problem is trying to add two optional arguments (stages and level) to these two constructors:
https://github.com/BVLC/caffe/blob/rc3/python/caffe/_caffe.cpp#L76-L96
Thanks to Dan's comments, I found a solution that works. I'll copy most of it here since there are some interesting tidbits about how to extract objects from bp::object, etc.
// Net constructor
shared_ptr<Net<Dtype> > Net_Init(string param_file, int phase,
const int level, const bp::object& stages,
const bp::object& weights_file) {
CheckFile(param_file);
// Convert stages from list to vector
vector<string> stages_vector;
if (!stages.is_none()) {
for (int i = 0; i < len(stages); i++) {
stages_vector.push_back(bp::extract<string>(stages[i]));
}
}
// Initialize net
shared_ptr<Net<Dtype> > net(new Net<Dtype>(param_file,
static_cast<Phase>(phase), level, &stages_vector));
// Load weights
if (!weights_file.is_none()) {
std::string weights_file_str = bp::extract<std::string>(weights_file);
CheckFile(weights_file_str);
net->CopyTrainedLayersFrom(weights_file_str);
}
return net;
}
BOOST_PYTHON_MODULE(_caffe) {
bp::class_<Net<Dtype>, shared_ptr<Net<Dtype> >, boost::noncopyable >("Net",
bp::no_init)
.def("__init__", bp::make_constructor(&Net_Init,
bp::default_call_policies(), (bp::arg("network_file"), "phase",
bp::arg("level")=0, bp::arg("stages")=bp::object(),
bp::arg("weights_file")=bp::object())))
}
The generated signature is:
__init__(boost::python::api::object, std::string network_file, int phase,
int level=0, boost::python::api::object stages=None,
boost::python::api::object weights_file=None)
And I can use it like:
net = caffe.Net('network.prototxt', weights_file='weights.caffemodel',
phase=caffe.TEST, level=1, stages=['deploy'])
Full code available in pull request here: https://github.com/BVLC/caffe/pull/3863