Skip to content

mp_ prefix collision #704

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

Closed
eblot opened this issue Jun 19, 2014 · 21 comments
Closed

mp_ prefix collision #704

eblot opened this issue Jun 19, 2014 · 21 comments
Labels
rfc Request for Comment

Comments

@eblot
Copy link
Contributor

eblot commented Jun 19, 2014

FWIW, there are many libraries out there that use the mp_ prefix. For example, ctaocrypt, a library with big number primitives used for cryptography and SSL implementation from CyaSSL/WolfSSL dedicated to embedded targets. A quick search on Google shows that mp_ is used in many libraries.

On embedded targets, especially with static linking, this creates name collision at link time.
Maybe it would be worth using a less common prefix, such as mpy_?

It is likely that micropython becomes highly popular as it deserves to. Linking with other 3rd party libraries - hence collision occurences would grow.

@pfalcon
Copy link
Contributor

pfalcon commented Jun 19, 2014

Why don't you submit requests to those libraries asking them to change their prefixes?

@eblot
Copy link
Contributor Author

eblot commented Jun 19, 2014

I think that would be fair.

Trouble is many users already use them, so it would require to change a large code base, whereas micropython is fairly new, so there is a small opportunity window it does not bother to many people - yet.

It will be the same issue with micropython in a couple of weeks/months.

This was just an early warning, I do not mind that much as I already locally changed some of the micropython's mp_ prefix to get a working installation, but it is likely I will not be the only one to get collision.

@dpgeorge
Copy link
Member

What particular libraries clashed with your build of uPy?

Ultimately, with C, there is no proper solution to this problem. We could wrap all externally exported identifiers in some macro, which prefixes some long (and configurable) name to all ids. Some projects do this (I think...) but it's a pretty extreme solution.

Else, we choose a longer (and more unique) name. But one day it will clash again.

A different solution is to provide a script which renames the source automagically.

@eblot
Copy link
Contributor Author

eblot commented Jun 19, 2014

ctaocrypt, from WolfSSL http://www.yassl.com/yaSSL/Products-cyassl.html
I think it comes from the LibTom projects (http://libtom.org), which provides cryptography and big number library, with many mp_ prefixes.

I agree there is no universal solution :-(

The shorter it is, the more likely the collisions. For ex, "googling" mp_init give 94K results, mpy_init gives 72, but none with this lower case syntax.

The script/renaming is a solution can make upstream merges/diffs a nightmare.

@pfalcon
Copy link
Contributor

pfalcon commented Jun 19, 2014

We could wrap all externally exported identifiers in some macro

Why we, they should do it! ;-)

Seriously, I agree that this is an issue, and it would be nice to resolve it. I comment in such way because IMHO we already made some naming choices with look-back at the other projects, which restrained uPy. And now this potential change breaking "git blame" usage all around, while, as @dpgeorge says, sooner or later someone won't be satisfied again anyway.

@dhylands
Copy link
Contributor

Another approach would be to just create a header which #defines the mp_foo
to something else. No other changes to micropython would be required (other
than ensuring each upy source file included the renaming header).

There are linker games that can be played as well.
On Jun 19, 2014 8:46 AM, "Damien George" notifications@github.com wrote:

What particular libraries clashed with your build of uPy?

Ultimately, with C, there is no proper solution to this problem. We could
wrap all externally exported identifiers in some macro, which prefixes some
long (and configurable) name to all ids. Some projects do this (I think...)
but it's a pretty extreme solution.

Else, we choose a longer (and more unique) name. But one day it will clash
again.

A different solution is to provide a script which renames the source
automagically.


Reply to this email directly or view it on GitHub
#704 (comment)
.

@dpgeorge
Copy link
Member

Why we, they should do it! ;-)

All projects that aim to be embedded should do it this way :)

Options:

  1. No change. People will have to change the prefix, probably lots of people.
  2. Change to mpy_. Less people will have to change the prefix, but over time it will eventually clash with more and more projects.
  3. Change to micropython_. A more long term solution, but means that our code will be terribly long on the line.
  4. Wrap in a macro, eg #define MPP(id) micropython_prefix_ ## id. Then you have the issue that MPP clashes...! And it makes for pretty damn ugly code.

I'm thinking that you need to wrap everything: functions, global vars (not many of those), types, constants, macros, etc. But maybe we can get away with just function names and global vars??

@pfalcon
Copy link
Contributor

pfalcon commented Jun 19, 2014

We can also switch to C++ sooner rather than later (hey, we're going to switch to C++, right? ;-) ). So, we could start with just using namespaces. One problem is that the stupid thing doesn't support named structure initializers...

@pfalcon pfalcon added the rfc label Jun 21, 2014
pfalcon referenced this issue Jun 30, 2014
Such mechanism is important to get stable Python functioning, because Python
function calling is handled with C stack. The idea is to sprinkle
STACK_CHECK() calls in places where there can be C recursion.

TODO: Add more STACK_CHECK()'s.
@pfalcon
Copy link
Contributor

pfalcon commented Dec 13, 2014

I give this good thought-over these months, and think that this request makes sense after all. We should support uPy embedding in other projects, and make people's like who doing this as easy as possible. So, if some prefix is indeed reported to be used by many different projects, up to causing real-world collisions, we should do something about that.

But we indeed cannot flip name prefixes again and again, so some planning is required:

  1. Think whether it's worth doing change at all - hopefully, we had enough time for that, so let's collect votes (+1 from me).
  2. Choose good alternative prefix, requirements: similar to existing, still short, yet minimizing chance of collision. I think "mpy_" is good candidate, but we need to do more research for possible collisions.
  3. Set timeline for the change - like, announce that it will happen in a month, to let everyone interested to submit their pending code changes, to minimize following conflict resolution work.

Thoughts?

@dpgeorge
Copy link
Member

+1 from me.

How about a macro wrapper around all public API functions and types so that the prefix can be configured by a #define? Eg:

MICROPY_TYPE(int) val = MICROPY_API(obj_get_int, obj_in);
if (MICROPY_API(obj_is_list, obj_in)) { ... }

Yes, it's a pain to write it out for every call, but that's the price you pay for a 100% bullet-proof solution (except for name-collision of macros...). Additional benefit of wrapping every call is that we then have the option to use macro-magic to change the calling conventions (to some extent). For example, adding a global/thread state argument to each function. This could be a compile time option, enabled for ports that need it.

Otherwise I would suggest using micropy_ as the prefix.

@pfalcon
Copy link
Contributor

pfalcon commented Dec 13, 2014

How about a macro wrapper around all public API functions and types

I would call it over-engineering at this stage ;-I.

change the calling conventions (to some extent). For example, adding a global/thread state argument to each function.

That's tempting, but I still think it's premature at this stage. If/when we'd come to that, that may be a separate change.

But anyway, you have better outlook, so if you think that's the right way to go right away, feel free to. But MICROPY_API(obj_is_list, obj_in) doesn't even look like C, so it will make threshold to understand uPy and contribute higher.

Otherwise I would suggest using micropy_ as the prefix.

Yes, apparently that's more robust than mpy_.

@dpgeorge
Copy link
Member

How about a macro wrapper around all public API functions and types

I would call it over-engineering at this stage ;-I.

Agree... actually, it doesn't improve the situation more than prefixing with micropy_: if functions starting with micropy_ clash with some other code, then likely macros beginning with MICROPY_ will also clash. So using MICROPY_API to wrap all calls is no more future proof than just prefixing with micropy_.

Otherwise I would suggest using micropy_ as the prefix.

Yes, apparently that's more robust than mpy_.

It is, and maybe we should just go for the long version from the beginning, so we don't run into this issue again. But then it's going to get ugly, eg:

micropy_obj_t micropy_obj_list_sort(micropy_uint_t n_args, const micropy_obj_t *args, micropy_map_t *kwargs);

@pfalcon
Copy link
Contributor

pfalcon commented Dec 13, 2014

micropy_obj_t micropy_obj_list_sort(micropy_uint_t n_args, const micropy_obj_t *args, micropy_map_t *kwargs);

Well, I've been thinking mostly about symbols, but yes, there're types too... Well, the above certainly looks long (as a line) and micropy_uint_t looks funny, but it's not something which cannot be gotten used to.

Bute we should collect more opinions from other folks.

@dhylands, @stinos : FYI

@stinos
Copy link
Contributor

stinos commented Dec 13, 2014

It's a tough one.
The micropy_ prefix is really uneasy on the eyes, almost to the point where it becomes unreadable. Which is also a bit of a problem with the macro approach.
A c++ namespace which is selected using a macro is usually the approach but I'm not sure all platforms micropython targets now, or will ever target, have a suitable c++ compiler. And there's the lack of designated initializer as mentioned (has been proposed though but it will take a while if it even ever gets accepted, there are workarounds like using appropriate constructors or putting the code in an extern "C" scope).
If you'd pick upy_ for instance, micropython will likely be the first to have it. Or at least it will be even less common than mpy_. Which sort of makes any future clashes which would turn up the problem of the other lib, not micropython :]
Summary: I definitely think this issue is worth solving but I wouldn't give up code readability and go with a short prefix. Unless the c++ approach seems feasible but that's maybe too big of a step to take just to solve this particular issue, a bit like hitting a nail with a bazooka.

@pfalcon
Copy link
Contributor

pfalcon commented Dec 13, 2014

Yes, I don't think we should mix C++ into this. I'd love to see C++ being used, but for template metaprogramming to achieve super-efficiency, rather than aux hacks like namespaces. We're long way from that though, and getting C code right (like we discuss here) is on critical path to it. And switching to C++ makes to become FUD target from unwise people, like http://harmful.cat-v.org/software/c++/linus

Other ideas are good, except make @dpgeorge's choice even harder ;-).

@dhylands
Copy link
Contributor

My take on this is that the only place we really have to worry about conflicts is with the linker.

If we switch to traditional headers, and turf the plan-9 stuff then it essentially becomes trivial to have a header file which maps all/some/just the conflicting symbols into something else.

Once you can map the symbols to be arbitrary, then I think we should just stick with what we have.

Has anybody embedded micropython yet, let alone had conflicts?

If it ain't broke don't fix it.

@eblot
Copy link
Contributor Author

eblot commented Dec 14, 2014

I had conflicts, with CyaSSL/ctaocrypt (now WolfSSL).

The issue can be "fixed" with macros or linker rules, but it usually makes the code harder to read at debug time.

micropython seems quite obtrusive, upy_ seems unique (in C language)

@dpgeorge
Copy link
Member

My take on this is that the only place we really have to worry about conflicts is with the linker.

I think we should be "conservative" and provide a better solution than linker/macro tricks. For example, if someone wants to use both uPy and some other library (which has mp_ prefix) in the same file, then macro tricks are going to be messy: include macro convertor file, then include uPy files, then include macro undefine file (since you want to use the other library and not redefine that one), then include other library.

Options so far:

  1. mpy_ -- this is short and similar to current code (so code-feel doesn't change much), and much less likely to conflict than mp_, but still possible to have conflicts.
  2. upy_ -- short and possibly less common than mpy_, but a big change in the "feel" of the code (upy_obj_t, upy_obj_get_int, ...).
  3. micropy_ -- "impossible" to ever clash, but very long, cumbersome, and difficult to read code.

We should do a survey of code to see if mpy_ is more/less common than upy_. How does one scrape all github projects? :)

@dpgeorge
Copy link
Member

dpgeorge commented Jan 1, 2015

Note: we should probably rename the py/ directory to match the chosen prefix.

dpgeorge referenced this issue Feb 24, 2015
Also, reword purpose to avoid impression that uPy supports just one
microcontroller.
@hauptmech
Copy link

upy_. It seems like many here use uPy to refer to the project. (upython was my first google search for this project when someone told me verbally that I should check it out.)

tannewt pushed a commit to tannewt/circuitpython that referenced this issue Mar 29, 2018
This appears to have a relatively small impact on flash usage but
fixes some pathological slow behavior putting floats in dicts or sets.

Closes: micropython#704
@jonnor
Copy link
Contributor

jonnor commented Jul 2, 2024

Nearly 10 years have passed, and the practical problems from this seem to have been pretty small. Perhaps it is OK the way it is? :)

@projectgus projectgus closed this as not planned Won't fix, can't repro, duplicate, stale Jul 5, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
rfc Request for Comment
Projects
None yet
Development

No branches or pull requests

8 participants