Skip to content

Commit

Permalink
fix #174
Browse files Browse the repository at this point in the history
Replace __desc* attribute in python and lua api with a description
function. The __desc attributes are kept for backward compatibility.
  • Loading branch information
rkaminsk committed Dec 2, 2019
1 parent 92dd6cd commit 37f57cb
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 48 deletions.
4 changes: 2 additions & 2 deletions examples/clingo/setconf/setconf-lua.lp
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ function print_conf(conf, ident)
if #subconf >= 0 then
label = label .. "[0.." .. tostring(#subconf) .. "]"
end
print (ident .. label .. " - " .. conf["__desc_" .. key])
print (ident .. label .. " - " .. conf:description(key))
print_conf(subconf, " " .. ident .. label .. ".")
else
print (ident .. key .. "[=" .. tostring(subconf) .. "] - " .. conf["__desc_" .. key])
print (ident .. key .. "[=" .. tostring(subconf) .. "] - " .. conf:description(key))
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions examples/clingo/setconf/setconf-py.lp
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ def print_conf(conf, ident):
label = key
if (len(subconf) >= 0):
label += "[0.." + str(len(subconf)) + "]"
print ("{0}{1} - {2}".format(ident, label, getattr(conf, "__desc_" + key)))
print ("{0}{1} - {2}".format(ident, label, conf.description(key)))
print_conf(subconf, " " + ident + label + ".")
else:
print ("{0}{1}[={2}] - {3}".format(ident, key, subconf, getattr(conf, "__desc_" + key)))
print ("{0}{1}[={2}] - {3}".format(ident, key, subconf, conf.description(key)))

def main(prg):
prg.ground([("base", [])])
Expand Down
47 changes: 33 additions & 14 deletions libluaclingo/luaclingo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1911,6 +1911,26 @@ struct Configuration : Object<Configuration> {
}
return 1;
}

bool get_subkey(lua_State *L, char const *name, clingo_id_t &subkey) {
if ((call_c(L, clingo_configuration_type, conf, key) & clingo_configuration_type_map) &&
call_c(L, clingo_configuration_map_has_subkey, conf, key, name)) {
subkey = call_c(L, clingo_configuration_map_at, conf, key, name);
return true;
}
return false;
}

static int description(lua_State *L) {
auto &self = get_self(L);
char const *name = luaL_checkstring(L, 2);
clingo_id_t subkey;
if (self.get_subkey(L, name, subkey)) {
lua_pushstring(L, call_c(L, clingo_configuration_description, self.conf, subkey)); // +1
return 1;
}
return luaL_error(L, "unknown option: %s", name);
}
static int index(lua_State *L) {
auto &self = get_self(L);
char const *name = luaL_checkstring(L, 2);
Expand All @@ -1926,25 +1946,23 @@ struct Configuration : Object<Configuration> {
bool desc = strncmp("__desc_", name, 7) == 0;
if (desc) { name += 7; }

if ((call_c(L, clingo_configuration_type, self.conf, self.key) & clingo_configuration_type_map) &&
call_c(L, clingo_configuration_map_has_subkey, self.conf, self.key, name)) {
auto subkey = call_c(L, clingo_configuration_map_at, self.conf, self.key, name);
clingo_id_t subkey;
if (self.get_subkey(L, name, subkey)) {
// NOTE: for backward compatibility should be removed in the future
if (desc) {
lua_pushstring(L, call_c(L, clingo_configuration_description, self.conf, subkey)); // +1
return 1;
}
else {
if (call_c(L, clingo_configuration_type, self.conf, subkey) & clingo_configuration_type_value) {
if (!call_c(L, clingo_configuration_value_is_assigned, self.conf, subkey)) { lua_pushnil(L); return 1; }
size_t size = call_c(L, clingo_configuration_value_get_size, self.conf, subkey);
char *ret = static_cast<char*>(lua_newuserdata(L, sizeof(*ret) * size)); // +1
handle_c_error(L, clingo_configuration_value_get(self.conf, subkey, ret, size));
lua_pushstring(L, ret); // +1
lua_replace(L, -2); // -1
return 1;
}
else { return Configuration::new_(L, self.conf, subkey); } // +1
else if (call_c(L, clingo_configuration_type, self.conf, subkey) & clingo_configuration_type_value) {
if (!call_c(L, clingo_configuration_value_is_assigned, self.conf, subkey)) { lua_pushnil(L); return 1; }
size_t size = call_c(L, clingo_configuration_value_get_size, self.conf, subkey);
char *ret = static_cast<char*>(lua_newuserdata(L, sizeof(*ret) * size)); // +1
handle_c_error(L, clingo_configuration_value_get(self.conf, subkey, ret, size));
lua_pushstring(L, ret); // +1
lua_replace(L, -2); // -1
return 1;
}
else { return Configuration::new_(L, self.conf, subkey); } // +1
}

lua_pushnil(L); // +1
Expand Down Expand Up @@ -2002,6 +2020,7 @@ constexpr char const *Configuration::typeName;
luaL_Reg const Configuration::meta[] = {
{"__len", len},
{"iter", iter},
{"description", description},
{nullptr, nullptr}
};

Expand Down
97 changes: 67 additions & 30 deletions libpyclingo/pyclingo.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3005,6 +3005,7 @@ struct.
struct Configuration : ObjectBase<Configuration> {
clingo_configuration_t *conf;
clingo_id_t key;
static PyMethodDef tp_methods[];
static PyGetSetDef tp_getset[];

static constexpr char const *tp_type = "Configuration";
Expand All @@ -3027,8 +3028,7 @@ To list the subgroups of an option group, use the `Configuration.keys` member.
Array option groups, like solver, have a non-negative length and can be
iterated. Furthermore, there are meta options having key `configuration`.
Assigning a meta option sets a number of related options. To get further
information about an option or option group `<opt>`, use property
`__desc_<opt>` to retrieve a description.
information about an option or option group `<opt>`, call `description(<opt>)`.

Notes
-----
Expand All @@ -3042,7 +3042,7 @@ The following example shows how to modify the configuration to enumerate all

>>> import clingo
>>> prg = clingo.Control()
>>> prg.configuration.solve.__desc_models
>>> prg.configuration.solve.description("models")
'Compute at most %A models (0 for all)\n'
>>> prg.configuration.solve.models = 0
>>> prg.add("base", [], "{a;b}.")
Expand Down Expand Up @@ -3078,38 +3078,59 @@ The following example shows how to modify the configuration to enumerate all
return list;
}

Object tp_getattro(Reference name) {
auto current_ = pyToCpp<std::string>(name);
char const *current = current_.c_str();
bool desc = strncmp("__desc_", current, 7) == 0;
if (desc) { current += 7; }
bool get_subkey(char const *name, clingo_id_t &subkey) {
clingo_configuration_type_bitset_t type;
handle_c_error(clingo_configuration_type(conf, key, &type));
if (type & clingo_configuration_type_map) {
bool haskey;
handle_c_error(clingo_configuration_map_has_subkey(conf, key, current, &haskey));
handle_c_error(clingo_configuration_map_has_subkey(conf, key, name, &haskey));
if (haskey) {
clingo_id_t subkey;
handle_c_error(clingo_configuration_map_at(conf, key, current, &subkey));
if (desc) {
char const *ret;
handle_c_error(clingo_configuration_description(conf, subkey, &ret));
return cppToPy(ret);
}
else {
handle_c_error(clingo_configuration_type(conf, subkey, &type));
if (type & clingo_configuration_type_value) {
bool assigned;
handle_c_error(clingo_configuration_value_is_assigned(conf, subkey, &assigned));
if (!assigned) { Py_RETURN_NONE; }
size_t size;
handle_c_error(clingo_configuration_value_get_size(conf, subkey, &size));
std::vector<char> ret(size);
handle_c_error(clingo_configuration_value_get(conf, subkey, ret.data(), size));
return cppToPy(ret.data());
}
else { return construct(subkey, conf); }
handle_c_error(clingo_configuration_map_at(conf, key, name, &subkey));
return true;
}
}
return false;
}

Object description(Reference name) {
auto cppname = pyToCpp<std::string>(name);
clingo_id_t subkey;
if (get_subkey(cppname.c_str(), subkey)) {
char const *ret;
handle_c_error(clingo_configuration_description(conf, subkey, &ret));
return cppToPy(ret);
}
else {
return PyErr_Format(PyExc_RuntimeError, "unknown option: %s", cppname.c_str());
}
}
Object tp_getattro(Reference name) {
auto current_ = pyToCpp<std::string>(name);
char const *current = current_.c_str();
bool desc = strncmp("__desc_", current, 7) == 0;
if (desc) { current += 7; }
clingo_id_t subkey;
if (get_subkey(current, subkey)) {
// NOTE: for backward compatibility should be removed in the future
if (desc) {
char const *ret;
handle_c_error(clingo_configuration_description(conf, subkey, &ret));
return cppToPy(ret);
}
else {
clingo_configuration_type_bitset_t type;
handle_c_error(clingo_configuration_type(conf, subkey, &type));
if (type & clingo_configuration_type_value) {
bool assigned;
handle_c_error(clingo_configuration_value_is_assigned(conf, subkey, &assigned));
if (!assigned) { Py_RETURN_NONE; }
size_t size;
handle_c_error(clingo_configuration_value_get_size(conf, subkey, &size));
std::vector<char> ret(size);
handle_c_error(clingo_configuration_value_get(conf, subkey, ret.data(), size));
return cppToPy(ret.data());
}
else { return construct(subkey, conf); }
}
}
return PyObject_GenericGetAttr(toPy(), name.toPy());
Expand Down Expand Up @@ -3147,6 +3168,23 @@ The following example shows how to modify the configuration to enumerate all
}
};

PyMethodDef Configuration::tp_methods[] = {
{"description", to_function<&Configuration::description>(), METH_O, R"(description(self, name: str) -> str

Get a description for a option or option group.

Parameters
----------
name : str
The name of the option.

Returns
-------
str
)"},
{nullptr, nullptr, 0, nullptr}
};

PyGetSetDef Configuration::tp_getset[] = {
// keys
{(char *)"keys", to_getter<&Configuration::keys>(), nullptr, (char *)R"(keys: Optional[List[str]]
Expand Down Expand Up @@ -3513,7 +3551,6 @@ PyMethodDef PropagateInit::tp_methods[] = {

Add a watch for the solver literal in the given phase.


Parameters
----------
literal : int
Expand Down

0 comments on commit 37f57cb

Please sign in to comment.