Skip to content

Strange behavior with ternary operator #493

Description

@sadseeker

I noticed strange behavior while trying to use ternary operator with boost::python::dict and list.
I'm trying to do something like this

using py = boost::python;

py::dict globals;
py::dict dict;
py::list list;
bool condition = true;
globals["mol"] = condition ? dict : list;
py::exec("print(type(mol))", globals);

What I expected: <class 'list'> or <class 'dict'>
What I got: <class 'Boost.Python.function'>

Is it expected behavior? Then can someone explain me why?
Or this is a bug?

Activity

  1. stefanseefeld commented on Jun 20, 2025

    @stefanseefeld
    Member

    I wouldn't be surprised if this behaviour is the result of expression templates at work.
    Try using a temporary variable to prevent lazy evaluation of the expression on the right-hand side.
    Also, to confirm: what is the result of calling the function you got ? That is, what is the output of
    py::exec("print(type(mol()))", globals); ?

  2. sadseeker commented on Jun 20, 2025

    @sadseeker
    Author

    Thanks for answer.
    I can fix this by using simple if-else or casting dict and list to py::object explicitly.
    But I wonder if this is expected behavior or bug


    py::exec("print(type(mol()))", globals); ?

    Probably <class 'list'> because I saw in debugger that &object::ptr would be written to globals["mol"].
    Although I can't test right now


    PS:

    py::exec("print(type(mol()))", globals); ?

    output:

    PythonException:
    Type: ArgumentError
    Value: Python argument types in
    None.None()
    did not match C++ signature:
    None(class boost::python::api::object {lvalue})
    Traceback:
     <string> : 1
    
  3. e-kwsm commented on Oct 24, 2025

    @e-kwsm
    Contributor
    globals["mol"] = condition ? dict : list;

    Here dict and list must have the same type.

    Try the folowing code

      globals["foo"] = true ? false : 123;  // false is converted to (int)0
      globals["bar"] = false;
      boost::python::exec("print(foo, bar)", globals);

    which prints

    0 False
    

    See https://stackoverflow.com/a/8535301.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions