Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

py/obj: Fix mp_obj_is_integer() recognition of bool. #5557

Closed

Conversation

andrewleech
Copy link
Contributor

The function mp_obj_is_integer() implementation // returns true if o is bool, small int or long int

The optimisation of True & False in d96cfd1 breaks the detection of bool however.

This PR restores the existing functionality by also checking for the new MP_ROM_FALSE and MP_ROM_TRUE.

@dpgeorge
Copy link
Member

See #5538 for discussion, and tests.

@dpgeorge dpgeorge added the py-core Relates to py/ directory in source label Jan 22, 2020
@@ -721,7 +721,8 @@ bool mp_obj_is_true(mp_obj_t arg);
bool mp_obj_is_callable(mp_obj_t o_in);
bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2);

static inline bool mp_obj_is_integer(mp_const_obj_t o) { return mp_obj_is_int(o) || mp_obj_is_type(o, &mp_type_bool); } // returns true if o is bool, small int or long int
static inline bool mp_obj_is_bool(mp_const_obj_t o) { return (o == MP_ROM_FALSE) || (o == MP_ROM_TRUE) || mp_obj_is_type(o, &mp_type_bool); } // returns true if o is bool
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This probably doesn't need the mp_obj_is_type() test at all, just the test against the 2 possible values.

But, for builds where MICROPY_OBJ_IMMEDIATE_OBJS is disabled, it might be simpler (smaller code) to just have the mp_obj_is_type() test (which will work fine).

And for object representation A this function could do just: return (uintptr_t)o & 0xf == 0xe;

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason for choosing MP_ROM_XXX over mp_const_xxx ?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not particularly no, I fairly naively picked them from the commit that broke my code (part of the openmv codebase that uses mp_obj_is_integer()).
I didn't fully inspect the changes in the commit to properly understand what was going one, this was kind of a commit and run once I tested the end use functionality as working. I hadn't seen the other issue tracking this at this stage.

@dpgeorge
Copy link
Member

@Jongy @stinos do you have any comments on the approach here, to add a mp_obj_is_bool() (inline) function? So mp_obj_is_type() remains unchanged and just no longer works for bool.

@Jongy
Copy link
Contributor

Jongy commented Jan 22, 2020

This looks okay. I agree with your comment on mp_obj_is_bool.

And like I said in #5338, I have an idea about how to change mp_obj_is_type to prevent such errors in the future, I'll just check it and add a separate PR.

@@ -812,6 +813,7 @@ size_t mp_obj_dict_len(mp_obj_t self_in);
mp_obj_t mp_obj_dict_get(mp_obj_t self_in, mp_obj_t index);
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value);
mp_obj_t mp_obj_dict_delete(mp_obj_t self_in, mp_obj_t key);
mp_obj_t mp_obj_dict_copy(mp_obj_t self_in);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Leftover from another commit

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ouch... that possibly means it didn't make it into my other pr if it was left uncommitted in this file :-(

@stinos
Copy link
Contributor

stinos commented Jan 22, 2020

Should work for me, I have to review the type conversion code in which I used this anyway so as long as there's a working detection it's ok.

I would extend the comment on mp_obj_is_type though to clarify care should be taken when using it, listing all cases for which it might not work. And add the unit/coverage tests shown in corresponding issue. Maybe even tests proving all mp_obj_is_xxx work as expected.

@dpgeorge
Copy link
Member

Should work for me, I have to review the type conversion code in which I used this anyway so as long as there's a working detection it's ok.

I'm curious how your code handles bool explicitly. Naively I would have thought that using mp_obj_is_true(o) and mp_obj_get_int(o) would be enough (ie no need to know if the object is a bool or an int).

@stinos
Copy link
Contributor

stinos commented Jan 22, 2020

To retrieve values I'm indeed using those most of the time, but for legacy reasons we also have a C++ collection of 'parameters' which are essentially key-value pairs where the value is a templated object. So originally we'd use this in C++ only and would do e.g. Register<bool>("someKey"). Now I wanted to bind this to MicroPython and register parameters which correspond to an actual object in MicroPython, but instead of rewriting the backend and get rid of templates there and use a MicroPython object instead (which in hindsight would have been better, but back then it wasn't 100% clear where I'd go with it) I made an adaptation layer meaning the need for code which given a MicroPython object maps it to a C++ type at compile time. Leading to code like if(mp_obj_is_type(&mp_type_float)){Register<double>(...);} else if(mp_obj_is_type(&mp_type_bool)){Register<bool>(...);} and so on.

@dpgeorge
Copy link
Member

Thanks @stinos for the explanation, makes sense!

This PR is superseded by #5559

@pi-anl
Copy link
Contributor

pi-anl commented Jan 23, 2020

And the extra points go to @Jongy for actually adding unit tests to cover the fix, nice!

@dpgeorge
Copy link
Member

Fixed by d9433d3

@dpgeorge dpgeorge closed this Jan 24, 2020
tannewt pushed a commit to tannewt/circuitpython that referenced this pull request Nov 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
py-core Relates to py/ directory in source
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants