Expose the Parser class properly to Python

This commit is contained in:
Joakim Hove 2019-09-04 14:42:52 +02:00
parent 1d8f07fe62
commit 7984d2a0f4
9 changed files with 103 additions and 16 deletions

View File

@ -240,6 +240,7 @@ if (OPM_ENABLE_PYTHON)
python/cxx/eclipse_state.cpp
python/cxx/group.cpp
python/cxx/group_tree.cpp
python/cxx/parsecontext.cpp
python/cxx/parser.cpp
python/cxx/schedule.cpp
python/cxx/common.cpp
@ -260,7 +261,7 @@ if (OPM_ENABLE_PYTHON)
add_custom_target(opmcommon_python ALL DEPENDS python/python/opm/libopmcommon_python.so)
add_dependencies(opmcommon_python opmcommon)
install( CODE "execute_process(COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX} )" )
install( CODE "execute_process(COMMAND mkdir -p ${CMAKE_INSTALL_PREFIX}/${PYTHON_INSTALL_PREFIX} )" )
install( CODE "execute_process(COMMAND python python/setup.py build_ext --dry-run install --prefix=${CMAKE_INSTALL_PREFIX} )" )
add_test(NAME python_tests

View File

@ -3,6 +3,7 @@
PYBIND11_MODULE(libopmcommon_python, module) {
opmcommon_python::export_ParseContext(module);
opmcommon_python::export_Parser(module);
opmcommon_python::export_Deck(module);
opmcommon_python::export_DeckKeyword(module);

View File

@ -21,12 +21,12 @@ namespace opmcommon_python {
void export_EclipseGrid(py::module& module);
void export_EclipseState(py::module& module);
void export_Group(py::module& module);
void export_GroupTree(py::module& module);
void export_ParseContext(py::module& module);
void export_Parser(py::module& module);
void export_Schedule(py::module& module);
void export_TableManager(py::module& module);
void export_Well(py::module& module);
void export_GroupTree(py::module& module);
}
#endif //SUNBEAM_HPP

View File

@ -0,0 +1,27 @@
#include <opm/parser/eclipse/Parser/ParseContext.hpp>
#include <opm/parser/eclipse/Deck/Deck.hpp>
#include <pybind11/stl.h>
#include "common_state.hpp"
#include "common.hpp"
namespace {
void (ParseContext::*ctx_update)(const std::string&, InputError::Action) = &ParseContext::update;
}
void opmcommon_python::export_ParseContext(py::module& module) {
py::class_< ParseContext >(module, "ParseContext" )
.def(py::init<>())
.def(py::init<const std::vector<std::pair<std::string, InputError::Action>>>())
.def( "update", ctx_update );
py::enum_< InputError::Action >( module, "action" )
.value( "throw", InputError::Action::THROW_EXCEPTION )
.value( "warn", InputError::Action::WARN )
.value( "ignore", InputError::Action::IGNORE );
}

View File

@ -38,8 +38,6 @@ namespace {
return new SunbeamState(false, filename, context, parser);
}
void (ParseContext::*ctx_update)(const std::string&, InputError::Action) = &ParseContext::update;
void add_keyword(Parser* parser, const std::string& json_string) {
const Json::JsonObject keyword(json_string);
parser->addParserKeyword(keyword);
@ -53,24 +51,19 @@ void opmcommon_python::export_Parser(py::module& module) {
module.def( "create_deck", &create_deck );
module.def( "create_deck_string", &create_deck_string);
py::class_<SunbeamState>(module, "SunbeamState")
.def("_schedule", &SunbeamState::getSchedule, ref_internal)
.def("_state", &SunbeamState::getEclipseState, ref_internal)
.def("_deck", &SunbeamState::getDeck, ref_internal)
.def("_summary_config", &SunbeamState::getSummmaryConfig, ref_internal);
py::class_< ParseContext >(module, "ParseContext" )
.def(py::init<>())
.def(py::init<const std::vector<std::pair<std::string, InputError::Action>>>())
.def( "update", ctx_update );
py::enum_< InputError::Action >( module, "action" )
.value( "throw", InputError::Action::THROW_EXCEPTION )
.value( "warn", InputError::Action::WARN )
.value( "ignore", InputError::Action::IGNORE );
py::class_<Parser>(module, "Parser")
.def(py::init<>())
.def("parse", py::overload_cast<const std::string&>(&Parser::parseFile, py::const_))
.def("parse" , py::overload_cast<const std::string&, const ParseContext&>(&Parser::parseFile, py::const_))
.def("parse_string", py::overload_cast<const std::string&>(&Parser::parseString, py::const_))
.def("parse_string", py::overload_cast<const std::string&, const ParseContext&>(&Parser::parseString, py::const_))
.def("add_keyword", add_keyword);
}

View File

@ -1,5 +1,16 @@
# This is the entry point were all the pybind11/C++ symbols are imported into
# Python. Before actually being used the symbols are typically imported one
# more time to a more suitable location; e.g the Parser() class is imported in
# the opm/io/parser/__init__.py file as:
#
# from opm._common import Parser
#
# So that end user code can import it as:
#
# from opm.io.parser import Parser
from __future__ import absolute_import
from .libopmcommon_python import action
from .libopmcommon_python import Parser, ParseContext
#from .schedule import Well, Connection, Schedule
#from .config import EclipseConfig

View File

@ -1,4 +1,5 @@
from opm._common import action
from opm._common import Parser
from opm._common import ParseContext
from .parser_module import parse, load_deck, load_deck_string, parse_string

View File

@ -56,6 +56,7 @@ ext_modules = [
'cxx/eclipse_state.cpp',
'cxx/group.cpp',
'cxx/group_tree.cpp',
'cxx/parsecontext.cpp',
'cxx/parser.cpp',
'cxx/schedule.cpp',
'cxx/common_state.cpp',

View File

@ -0,0 +1,52 @@
import unittest
import os.path
import sys
from opm.io.parser import Parser
from opm.io.parser import ParseContext
class TestParser(unittest.TestCase):
REGIONDATA = """
START -- 0
10 MAI 2007 /
RUNSPEC
DIMENS
2 2 1 /
GRID
DX
4*0.25 /
DY
4*0.25 /
DZ
4*0.25 /
TOPS
4*0.25 /
REGIONS
OPERNUM
3 3 1 2 /
FIPNUM
1 1 2 3 /
"""
def setUp(self):
self.spe3fn = 'tests/spe3/SPE3CASE1.DATA'
self.norne_fname = os.path.abspath('examples/data/norne/NORNE_ATW2013.DATA')
def test_create(self):
parser = Parser()
deck = parser.parse(self.spe3fn)
context = ParseContext()
deck = parser.parse(self.spe3fn, context)
with open(self.spe3fn) as f:
string = f.read()
deck = parser.parse_string(string)
deck = parser.parse_string(string, context)
if __name__ == "__main__":
unittest.main()