Embedded Python: Getting func obj from imported module - c++

I have a Python module that I import from my C++ code (I'm embedding Python). This module contains a function create() that I want to get a hold of in my C++ code (i.e. store it in a boost::python::object instance).
Here's what I tried. A run-time error occurs on the indicated line in my C++ code. The error occurs because it is unable to find the "hero.create" function inside the main namespace.
C++ code
namespace python = boost::python;
// Standard Boost.Python code
// Here I just create objects for the main module and its namespace
python::object main_module(
python::handle<>(python::borrowed(PyImport_AddModule("__main__")))
);
python::object main_namespace(main_module.attr("__dict__"));
// This is my code
//
python::exec("import hero", main_namespace, main_namespace);
python::object func(main_namespace["hero.create"]); // Run-time error
Entity ent = python::extract<Entity>(func());
// I also tried doing this, but it didn't work either...
// python::object func(main_namespace["hero"].attr("__dict__")["create"]);
// However, if I do this, all works fine...
// python::exec("from hero import create", main_namespace, main_namespace);
// python::object func(main_namespace["create"]); // No error
Python code (hero.py)
from entity import Entity
def create():
ent = Entity()
# ...
return ent

You need to do main_namespace["hero"].attr("create"). Import creates only one name in the namespace, and it's a module object. Names cannot have dots in them — . is a getattr operator — so hero.create is the same as getattr(hero, 'create').
You could also use boost::python::import directly, instead of execing import statement.

Related

How do you print or capture the current module name?

I want to print the module name of my main source file in that source file. I tried this:
import std.stdio;
import std.traits; // moduleName template
int main(string[] args)
{
writeln("The module name is: ",moduleName!moduleName);
return 0;
}
However, it prints:
The module name is: std.traits
The moduleName template description is:
Get the module name (including package) for the given symbol.
So moduleName!moduleName should give std.traits.
Just replace the template argument with any other symbol to get it's module name.
For example writeln(moduleName!main).
Another way is using writeln(__MODULE__).
Using __MODULE__ is the way to go. It's a special token, like __FILE__ and __LINE__, which means it'll get expanded at the call site. See the specs for some example.

How to restore a mock created with jest.mock()?

Apparently mock.mockRestore() does not restore the original implementation of a mock created using jest.mock()
// a.js
export default class A {}
// b.js
import A from './a';
export default class B extends A {}
// test.js
import A from './a';
import B from './b';
jest.mock('./a');
jest.mock('./b');
const b = new B();
test('instanceOf', () => {
A.mockRestore();
B.mockRestore();
expect(b).toBeInstanceOf(A); // fails
});
mockFn.mockRestore only works for a mock function created with jest.spyOn:
const obj = {
func: () => 'original'
}
test('func', () => {
const mock = jest.spyOn(obj, 'func');
mock.mockReturnValue('mocked');
expect(obj.func()).toBe('mocked'); // Success!
mock.mockRestore();
expect(obj.func()).toBe('original'); // Success!
})
jest.spyOn wraps the original function and provides mockRestore as a way to restore the original function.
jest.mock calls work a little differently.
Jest takes over the require system and jest.mock tells Jest that it should return the module mock instead of the actual module whenever it is required.
This means that the module mock doesn't wrap the original module, it completely replaces the original module in the require system. So mockRestore may be defined on mock functions within the module mock, but calling it doesn't restore the original implementation.
jest.mock is typically used when you want to mock an entire module for the whole test.
It is particularly useful when using ES6-style import statements since babel-jest hoists jest.mock calls and they run before anything else in the test file (including any import statements):
import A from './a'; // <= A is already mocked...
jest.mock('./a'); // <= ...because this runs first
test('A', () => {
// ...
}
There isn't an easy way to restore the original module during a test that uses jest.mock since its primary use is to mock a module for an entire test.
If you are trying to use both a mock and the original implementation during the same test there are a few options:
Mock one particular function using jest.spyOn and restore it using mockRestore
Use jest.doMock to avoid the hoisting behavior of jest.mock...just note you also need to use require within the scope that uses jest.doMock instead of using a top-level import
Use jest.requireActual at any time to require the original module
Assuming you cant use spyOn,
you can do something like this:
// test.js
jest.mock('./a');
import A from './a';
A.mockImplementation(params => 'mockVal');
const actualA = jest.requireActual('./a');
test('instanceOf', () => {
A.mockRestore(); // acts like mockReset()
A.mockImplementation((params) => {
return actualA(params);
});
});

Importing a specific function from a module

I have a module called prog1.py which contains a function and other statements, like this:
def func(a,b,c)
...
...
return output
var = input('input')
...
I'm trying to call just the function func from a different module prog2.py like this:
from prog1 import func
N = input('input2')
for i in range(N)
func(x,y,z) # with x,y,z already defined
So when executing prog2.py instead of asking for my input2, it asks for my input from prog1.py. I can move from prog1 import func to my for loop but I don't want it to ask for the other input. Is there a way to call func without using whatever else is in prog1.py?
The top level code of a module is executed upon import and there is no way around this.
If you don't want the line
var = input('input')
to be executed, remove it, put it in a function or guard it with
if __name__ == '__main__'
var = input('input')
(usually at the end of the module).

How to get Swig to generate a Python class instead of free functions?

How can I get Swig generate Python code as a class instead of free functions?
%module SimulatorAppWrapper
%{
#define SWIG_FILE_WITH_INIT
#include "SimulatorAppWrapper.hpp"
%}
%include "SimulatorAppWrapper.hpp"
My wrapper source is fairly trivial:
class SimulatorAppWrapper
{
public:
typedef std::map<const char*, const char*> ConfigSettings;
SimulatorAppWrapper();
~SimulatorAppWrapper();
void AddConfigKey(const char* k, const char* v);
int Run();
};
From here I generate Swig source and link against it using:
swig -python -c++ SimulatorAppWrapper.i
However I check the build module I get the following where I have free functions instead of something like a class:
>>> import SimulatorAppWrapper
>>> dir(_SimulatorAppWrapper)
['SWIG_PyInstanceMethod_New', 'SimulatorAppWrapper_AddConfigKey', 'SimulatorAppWrapper_Run', 'SimulatorAppWrapper_swigregister', '__doc__', '__file__', '__name__', '__package__', 'delete_SimulatorAppWrapper', 'new_SimulatorAppWrapper']
I would like to be able to do something like the following:
simApp = SimulatorAppWrapper
simApp.Run()
I can't see anything wrong with the SWIG .i or your .h.
But your test would be simApp = SimulatorAppWrapper() (note the parentheses) then either semicolon or new line before simApp.Run().
Also you should use from SimulatorAppWrapper import SimulatorAppWrapper since you have named your module SimulatorAppWrapper.
Finally, you do not need an underscore in dir(_SimulatorAppWrapper). The list you see is the set of SWIG wrapper functions which get called when you create instance, etc. For example when you call SimulatorAppWrapper() this actually calls new_SimulatorAppWrapper(). Try dir(SimulatorAppWrapper) (which in your original code will be dir() on the module object, but if you use the "from import" as I suggest above it will be dir() on your class).

HaxePunk: Nothing is rendering when exporting to C++

So I'm making a game with Haxe and Haxepunk. Fine. Except that when I export to C++, nothing is rendering! I posted this previously on the Haxepunk boards, so more info can be found here. Here's an excerpt from the Haxepunk thread;
I can still compile it just fine, but nothing in the game is actually rendering except for the background color I defined. The console still works and renders fine, though. The HaxePunk console tells me Atlases using BitmapData will not be managed.
I'm using Ash's component-entity system, and I'm not using Haxe's Entities. The relevant objects have a Visible component attached to them, which looks like this;
package game.component;
import com.haxepunk.Graphic;
import com.haxepunk.graphics.Image;
class Visible {
public var image(default, default) : Graphic;
public function new() {
this.image = Image.createRect(16, 16, 0xFF0000);
}
}
And this is the associated rendering system;
package game.system;
import ash.core.Engine;
import ash.core.Entity;
import ash.core.System;
import ash.tools.ListIteratingSystem;
import com.haxepunk.HXP;
import Constants;
import game.component.Positionable;
import game.component.Visible;
import game.node.RenderNode;
class RenderingSystem extends ListIteratingSystem<RenderNode> {
public function new() {
super(RenderNode, this.updateNode);
}
private function updateNode(node:RenderNode, time:Float) : Void {
node.renderable.image.render(HXP.buffer, node.position.position, Constants.ORIGIN);
}
}
Any tips?
If you are using buffer rendering in C++ you'll need to set the render mode inside the constructor. This is because the Engine constructor is the only place a screen buffer is created. Unfortunately the API docs don't clearly explain this.
class Main extends Engine
{
public function new()
{
super(0, 0, 60, false, RenderMode.BUFFER);
}
}