Boost.Python invalid keyword argument crashing the interpreter - boost-python

I'm trying to define a class with multiple constructors methods, some of which take keyword arguments. Everything works as expected/intended until the constructor is passed a bad parameter list, in which case the interpreter dies instead of throwing an exception. Here's a minimal example:
#include <boost/python.hpp>
#include <string>
class Crash {
public:
Crash(std::string) { }
Crash(int, int) { }
};
BOOST_PYTHON_MODULE(mymodule) {
using namespace boost::python;
class_<Crash>("Crash", init<std::string>())
.def(init<int, int>((arg("i") = 3)))
;
}
Output:
Python 2.7.3 (default, Apr 10 2012, 23:31:26) [MSC v.1500 32 bit (Intel)] on win 32
Type "help", "copyright", "credits" or "license" for more information.
>>> import mymodule as mm
>>> mm.Crash("asdf")
<mymodule.Crash object at 0x00D9FB70>
>>> mm.Crash(3)
<mymodule.Crash object at 0x00D9FE10>
>>> mm.Crash(4, i=5)
<mymodule.Crash object at 0x00D9FB70>
>>> mm.Crash(i=3) # kills the interpreter
Putting in an invalid keyword, e.g., Crash(blah=4), also kills the interpreter.
Is this a Boost.Python bug, or am I doing something wrong?
I'm using Boost 1.51 / Python 2.7.3 / MSVC 9.0.

Related

Including edk2-libc in efi shell application

How would one approach adding support for https://github.com/tianocore/edk2-libc, say I want to include stdio and use printf in my edk2 application? I followed StdLib/Readme.txt, and am able to successfully build examples in the AppPkg, however, when I try to add StdLib to my project I get errors like these:
LibString.lib(Searching.obj) : error LNK2005: strspn already defined in LibString.lib(Searching.obj)
LibCtype.lib(CClass.obj) : error LNK2005: isspace already defined in LibCtype.lib(CClass.obj)
(...)
LibC.lib(Main.obj) : error LNK2001: unresolved external symbol main
I do have the boilerplate (!include StdLib/StdLib.inc) added to my dsc file and in inf, I have StdLib.dec added to Packages and LibC and LibStdio added to LibraryClasses. I am using VS2017 toolchain for compilation and am using edk2-stable202108 release.
I was able to achieve this using below configuration for Hello Application of AppPkg.
Hello.inf
[Defines]
INF_VERSION = 0x00010006
BASE_NAME = Hello
FILE_GUID = a912f198-7f0e-4803-b908-b757b806ec83
MODULE_TYPE = UEFI_APPLICATION
VERSION_STRING = 0.1
ENTRY_POINT = ShellCEntryLib
#
# VALID_ARCHITECTURES = IA32 X64
#
[Sources]
Hello.c
[Packages]
MdePkg/MdePkg.dec
ShellPkg/ShellPkg.dec
StdLib/StdLib.dec
[LibraryClasses]
UefiLib
ShellCEntryLib
BaseLib
BaseMemoryLib
MemoryAllocationLib
LibStdLib
LibStdio
LibString
DevConsole
Hello.c
#include <Uefi.h>
#include <Library/UefiLib.h>
#include <Library/ShellCEntryLib.h>
#include <stdio.h>
int
main (
IN int Argc,
IN char **Argv
)
{
printf("Hello, world!\n");
return 0;
}
What I have understood is that LibC has ShellAppMain() defined in it which internally calls extern main(). So You need to provide definition of main() in your source just like I did in Hello.c

BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS used to overload multi-type templates : macro with several args as one

With a regular class BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS works :
>> more dummy.cpp
#include <boost/python.hpp>
using namespace boost::python;
class X
{
public:
X() {};
int twice(int x=5, float y=2.) {return (int)(x*y);};
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(X_twice_overloads, X::twice, 0, 2)
BOOST_PYTHON_MODULE(dummy)
{
class_<X>("X").def("twice", &X::twice, X_twice_overloads(args("x", "y")));
}
>> make
g++ -I /usr/include/python2.7 -o dummy.so -fPIC -shared dummy.cpp -lboost_python -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dummy; dx = dummy.X(); print dx.twice(), dx.twice(2,-1.)
10 -2
OK, that works.
Now I need to "templatize" a class with one (only) type T :
>> more dummyT.cpp
#include <string>
#include <boost/python.hpp>
using namespace boost::python;
template<typename T>
class Y
{
public:
Y() {};
T twice(T x=5, float y=2.) {return (T)(x*y);};
};
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Yint_twice_overloads, Y<int>::twice, 0, 2)
template<typename T, typename O>
void exportY(std::string type)
{
class_<Y<T>>(type.c_str()).def("twice", &Y<T>::twice, O(args("x", "y")));
};
BOOST_PYTHON_MODULE(dummyT)
{
exportY<int, Yint_twice_overloads>("Yint");
}
>> make dummyT
g++ -I /usr/include/python2.7 -o dummyT.so -fPIC -shared dummyT.cpp -lboost_python -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dummyT; dy = dummyT.Yint(); print dy.twice(), dy.twice(2,-1.)
10 -2
OK: works fine.
But, now I need to "templatize" a class with 2 types T and U:
>> more dummyTU.cpp
#include <string>
#include <boost/python.hpp>
#include <boost/preprocessor.hpp>
using namespace boost::python;
template<typename T, typename U>
class Z
{
public:
Z() {};
T twice(T x=5, U y=2.) {return (T)(x*y);};
};
#define SEVERAL_ARGS_AS_ONE_EXPAND(a,b) Z<a,b>::twice
#define SEVERAL_ARGS_AS_ONE_EXPAND_EXPAND(a,b) SEVERAL_ARGS_AS_ONE_EXPAND(a,b)
#define SEVERAL_ARGS_AS_ONE(a,b) SEVERAL_ARGS_AS_ONE_EXPAND_EXPAND(a,b)
#define ARGS int, float
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Zintfloat_twice_overloads, SEVERAL_ARGS_AS_ONE(ARGS), 0, 2)
template<typename T, typename U, typename O>
void exportZ(std::string type)
{
class_<Z<T,U>>(type.c_str()).def("twice", &Z<T,U>::twice, O(args("x", "y")));
};
BOOST_PYTHON_MODULE(dummyTU)
{
exportZ<int, float, Zintfloat_twice_overloads>("Zintfloat");
}
>> make dummyTU
g++ -I /usr/include/python2.7 -o dummyTU.so -fPIC -shared dummyTU.cpp -lboost_python -lpython2.7
dummyTU.cpp:19:98: error: macro "SEVERAL_ARGS_AS_ONE" requires 2 arguments, but only 1 given
19 | BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Zintfloat_twice_overloads, SEVERAL_ARGS_AS_ONE(ARGS), 0, 2)
This breaks.
As far as I understand the "double macro expand" trick should make "several args as one", but, this seems to fail. Can't get BOOST_PP_XXX to work either. Is there a way to get this to work ?
Solution:
>> more dummyTU.cpp
#include <string>
#include <boost/python.hpp>
using namespace boost::python;
template<typename T, typename U>
class Z
{
public:
Z() {};
T twice(T x=5, U y=2.) {return (T)(x*y);};
};
#define SEVERAL_ARGS_AS_ONE_EXPAND(a,b) Z<a,b>
#define SEVERAL_ARGS_AS_ONE_EXPAND_EXPAND(...) SEVERAL_ARGS_AS_ONE_EXPAND(__VA_ARGS__)
#define SEVERAL_ARGS_AS_ONE(...) SEVERAL_ARGS_AS_ONE_EXPAND_EXPAND(__VA_ARGS__)
#define N_ARGS() int,float
typedef SEVERAL_ARGS_AS_ONE(N_ARGS()) ZintfloatTD;
BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(Zintfloat_twice_overloads, ZintfloatTD::twice, 0, 2)
template<typename T, typename U, typename O>
void exportZ(std::string type)
{
class_<Z<T,U>>(type.c_str()).def("twice", &Z<T,U>::twice, O(args("x", "y")));
};
BOOST_PYTHON_MODULE(dummyTU)
{
exportZ<int, float, Zintfloat_twice_overloads>("Zintfloat");
}
>> make dummyTU
g++ -I /usr/include/python2.7 -o dummyTU.so -fPIC -shared dummyTU.cpp -lboost_python -lpython2.7
>> python
Python 2.7.17 (default, Oct 19 2019, 23:36:22)
[GCC 9.2.1 20191008] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import dummyTU; dz = dummyTU.Zintfloat(); print dz.twice(), dz.twice(2,-1.)
10 -2

The def keyword always seems to give me an error feedback

def my_function(country = "Norway"):
print("I am from " + country)
my_function("Sweden")
my_function("India")
my_function()
my_function("Brazil")
Syntax Error: invalid syntax
Your code should be working.
I tried below in PyCharm IDE, It worked for me.
def my_function(country = "Norway"):
print("I am from " + country)
my_function("Sweden")
# Output = I am from Sweden
Tried below code from Command line:
C:\Users\OmkarJ>python
Python 3.6.2 (v3.6.2:5fd33b5, Jul 8 2017, 04:57:36) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> def my_function(country = "Norway"):
... print("I am from " + country)
...
>>> my_function("Sweden")
I am from Sweden
>>> my_function("India")
I am from India
>>>

Swig -> Perl5 : Error compiling simplest SWIG-Module with VC15

I have a quite simple Swig Module for Demo purposes but can't get the wrapper/stub to get compiled.
Swigtest.h:
#pragma once
class Swigtest {
public:
Swigtest() {};
int func1(int param1);
};
Swigtest.cpp
#include "Swigtest.h"
int Swigtest::func1(int param1)
{
return param1 + 1;
}
Swigtest.i
%module Swigtest
%{
#include "Swigtest.h"
%}
%include "Swigtest.h"
The wrapper ist generated with swig.exe -c++ -perl5 Swigtest.i and then the compilation of the wrapper Swigtest_wrap.cxx fails with the following first error:
[path_to_perl_lib]\lib\core\win32.h(371): error C2061: syntax error: identifier 'STRLEN'
I'm using VisualStudio 2015 Toolset (acutally running on VS17) with Target Platform Version 8.1 and Swigwin 3.0.12.
Thank's for your help!

Pycuda test_driver.py raises Attribute Error

I'm trying to install pycuda on Linux Mint with a GeForce 960M and Cuda 8.0 installed. When I run the test_driver.py script it outputs the following error:
============================= test session starts ==============================
platform linux2 -- Python 2.7.12, pytest-3.0.3, py-1.4.31, pluggy-0.4.0
rootdir: /home/milton/Downloads/pycuda-2016.1.2, inifile:
collected 28 items
test_driver.py ...................x.....F..
=================================== FAILURES ===================================
________________________ TestDriver.test_multi_context _________________________
args = (,), kwargs = {}
pycuda = <module 'pycuda' from '/home/milton/miniconda2/lib/python2.7/site-packages/pycuda-2016.1.2-py2.7-linux-x86_64.egg/pycuda/init.pyc'>
ctx = <pycuda._driver.Context object at 0x7f540e39d758>
clear_context_caches = <function clear_context_caches at 0x7f540ee26758>
collect =<built-in function collect>
def f(*args, **kwargs):
import pycuda.driver
# appears to be idempotent, i.e. no harm in calling it more than once
pycuda.driver.init()
ctx = make_default_context()
try:
assert isinstance(ctx.get_device().name(), str)
assert isinstance(ctx.get_device().compute_capability(), tuple)
assert isinstance(ctx.get_device().get_attributes(), dict)
inner_f(*args, **kwargs)
../../../miniconda2/lib/python2.7/site-packages/pycuda-2016.1.2-py2.7-linux-x86_64.egg/pycuda/tools.py:460:
self = <test_driver.TestDriver instance at 0x7f540c21fc20>
#mark_cuda_test
def test_multi_context(self):
if drv.get_version() < (2,0,0):
return
if drv.get_version() >= (2,2,0):
if drv.Context.get_device().compute_mode == drv.compute_mode.EXCLUSIVE:
E AttributeError: type object 'compute_mode' has no attribute 'EXCLUSIVE'
test_driver.py:638: AttributeError
================ 1 failed, 26 passed, 1 xfailed in 6.92 seconds ================
python driver compute mode only supports following modes:
DEFAULT,
PROHIBITED,
EXCLUSIVE_PROCESS
so please change this:
if drv.Context.get_device().compute_mode == drv.compute_mode.EXCLUSIVE:
to
if drv.Context.get_device().compute_mode == drv.compute_mode.EXCLUSIVE_PROCESS:
in your test_driver.py file