Skip to content

Commit

Permalink
Automatic to_<tag> Python method. (#9)
Browse files Browse the repository at this point in the history
  • Loading branch information
msoeken authored Jul 22, 2018
1 parent 5ed17b6 commit 07a674d
Show file tree
Hide file tree
Showing 3 changed files with 71 additions and 30 deletions.
7 changes: 5 additions & 2 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
Change Log
==========

v0.3 (not yet released)
-----------------------
v0.3 (July 22, 2018)
--------------------

* Throw and catch errors in `read`.

Expand All @@ -18,6 +18,9 @@ v0.3 (not yet released)
* General commands: ``store --pop`` to remove current store element
`#8 <https://github.com/msoeken/alice/pull/8>`_

* Automatic ``to_<tag>`` in Python interface as shortcut for ``write_<tag>(log=True)["contents"]``
`#9 <https://github.com/msoeken/alice/pull/9>`_

v0.2 (May 7, 2018)
------------------

Expand Down
32 changes: 32 additions & 0 deletions include/alice/api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,37 @@ struct insert_write_commands<CLI, Tuple, 0>
}
};

#if defined ALICE_PYTHON
template<typename CLI, typename Tuple, std::size_t Index>
struct make_special_write_commands
{
make_special_write_commands( CLI& cli, py::module& m )
{
make_special_write_commands<CLI, Tuple, Index - 1> irc( cli, m );

using tag_type = std::tuple_element_t<Index - 1, Tuple>;
//cli.template insert_write_command<tag_type>( fmt::format( "write_{}", alice_globals::get().write_tags[Index - 1] ), alice_globals::get().write_names[Index - 1] );

auto const& tag = alice_globals::get().write_tags[Index - 1];
const auto name = fmt::format( "write_{}", tag );
auto const& cmd = cli.env->commands().at( name );
m.def( fmt::format( "to_{}", tag ).c_str(), [cmd, name]( py::kwargs kwargs ) -> py::str {
auto pargs = detail::make_args( name, kwargs );
pargs.push_back( "--log" );
cmd->run( pargs );
const auto log = cmd->log();
return py::str( log["contents"].template get<std::string>() );
} );
}
};

template<typename CLI, typename Tuple>
struct make_special_write_commands<CLI, Tuple, 0>
{
make_special_write_commands( CLI& cli, py::module& m ) {}
};
#endif

/*! \brief Returns a one-line string to show when printing store contents
This macro is used to return a string that is shown in the output of
Expand Down Expand Up @@ -501,6 +532,7 @@ PYBIND11_MODULE(prefix, m) \
{ \
_ALICE_MAIN_BODY(prefix) \
alice::detail::create_python_module( cli, m ); \
make_special_write_commands<cli_t, alice_write_tags, std::tuple_size<alice_write_tags>::value> swc( cli, m ); \
}
#elif defined ALICE_CINTERFACE
#define ALICE_MAIN(prefix) \
Expand Down
62 changes: 34 additions & 28 deletions include/alice/detail/python.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,39 @@ class return_value_dict
std::string repr_html;
};

inline std::vector<std::string> make_args( const std::string& name, py::kwargs kwargs )
{
std::vector<std::string> pargs = {name};

for ( const auto& kp : kwargs )
{
// get the key as string
const auto skey = kp.first.cast<std::string>();
const auto value = kp.second;

// TODO cast float to string?
if ( py::isinstance<py::bool_>( value ) )
{
if ( value.cast<bool>() )
{
pargs.push_back( "--" + skey );
}
}
else if ( py::isinstance<py::int_>( value ) )
{
pargs.push_back( "--" + skey );
pargs.push_back( std::to_string( value.cast<int>() ) );
}
else
{
pargs.push_back( "--" + skey );
pargs.push_back( value.cast<std::string>() );
}
}

return pargs;
}

template<typename CLI>
void create_python_module( CLI& cli, py::module& m )
{
Expand All @@ -187,34 +220,7 @@ void create_python_module( CLI& cli, py::module& m )
for ( const auto& p : cli.env->commands() )
{
m.def( p.first.c_str(), [p]( py::kwargs kwargs ) -> py::object {
std::vector<std::string> pargs = {p.first};

for ( const auto& kp : kwargs )
{
// get the key as string
const auto skey = kp.first.cast<std::string>();
const auto value = kp.second;

// TODO cast float to string?
if ( py::isinstance<py::bool_>( value ) )
{
if ( value.cast<bool>() )
{
pargs.push_back( "--" + skey );
}
}
else if ( py::isinstance<py::int_>( value ) )
{
pargs.push_back( "--" + skey );
pargs.push_back( std::to_string( value.cast<int>() ) );
}
else
{
pargs.push_back( "--" + skey );
pargs.push_back( value.cast<std::string>() );
}
}
p.second->run( pargs );
p.second->run( make_args( p.first, kwargs ) );

const auto log = p.second->log();

Expand Down

0 comments on commit 07a674d

Please sign in to comment.