Hokay, this is pretty much my response to the string vs int stuff, slammed into one email. First clarifying the assumption I'm after a max test for eapi testing; not the case- stated so already in this thread. Restating it again, for stable, a check of if it's > 0 (with int conversion failures being knocked up to 1 fex) is effectively the same thing as if str(portage_const.EAPI) in ("", "0"). Stated also that for rewrite, this approach won't work, and you're stuck specifying either a range of supported EAPI (max *and* min), or specifying every single individual eapi identifier, which I'll clarify before is going to burn any maintainer of such code. On Wed, Aug 31, 2005 at 12:52:53PM +0200, Marius Mauch wrote: > On 08/30/05 Brian Harring wrote: > > > Why am I being so damned stubborn about numbers for this? Cause I > > don't want users having to dink around with knowing that eapi="really > > cool version" somehow maps out to 3.1. Further, eapi version *likely* > > will wind up as the slotting for any split out portage-ebuild package, > > and slots traditionally have always been ints. > > Thanks for that last comment, it actually prooves our point ;) > Yes, SLOTs are *generally* numeric strings, as they are generally tied > to major versions. But as soon as more than the major part of the > version is important ints don't work anymore (and never ever mention > float again, version numbers aren't floats), and in some cases you find > non-version data in SLOT (like $CTARGET). Summation of string based failings. First off, a modifier of an EAPI, say EAPI=3-strict isn't valid; why? strict is most likely a restriction, a specific negation of some aspect of eapi3. Restrict is the place for it, or a similar metadata key. Yes this doesn't hold across all cases (someone could've just decided 3-strict was a cool name fex), but throwing it out there to point out that eapi is ebuild templates, not restrictions. Further, any deviation where loss of backwards compatibility would occur (limiting or extending bash syntax) is implicitly another format, thus beyond eapi's keen. EAPI is ebuild (the format) spec/api *only*, see comments below re: format support for further explanation. Re: tagging EAPI at the top of a file, infra would probably shoot me for doing such- till a live, fully compatible and *roughly* equivalent parser is available, portage would have to do a bit of grepping, jacking up the regen times. One thing I'm going to clarify also, is that the rewrite *does not* make it hard to tag new formats in. There's no reason to jam everything into ebuilds, especially considering we are bound by existing definitions, and a body of 20,000 live ebuilds users/devs would get rather pissed off about if we forced a change across it. If it's not an adjustment, a tweak, an extension/subtraction of ebuild functionality, eapi isn't applicable imo, and a seperate format is the route to go (one that could easily live alongside in the tree). EAPI is just for ebuild format. alt formats (whether sh based or otherwise) would be wise to version their version also. Either way, getting to the point of why strings suck badly in the point where it matters- as format version identifiers for the code that does the actual work. Example code for numeric, say we have eapi 0-5 at this point. def configure(self): if self.pkg.eapi > 0: ...call configure phase... return example code for strings def configure(self): if self.pkg.eapi in ("0", "1", "2", "3", "4", "5"): ...call configure phase... return This sucks. the response is "well, stick it into a list somewhere". Can do, but you have to mangle each list everytime you add a new eapi. That's a good way to lead to dumb ass bugs when tinkering with a new eapi level. or... capabilities, as suggested. capabilities = {"0":["configure"], "1":["configure"], "2":["configure"], "3":["configure"], "4":["configure"], "5":["configure"],} def has_capability(eapi, capability): try: return capability in capabilities[eapi]: except KeyError: return False def configure(self): if has_capability(self.pkg.eapi, "configure"): ...call configure phase... return or (slightly nastier example) # eapi5 being eapi4, just with bash side changes. implicit is that # their is bash side changes between each eapi, just stating it # explicitly to avoid the 'wtf' capabilities = {"0":["configure"], "1":["configure", "test_src_uri"], "2":["configure", "test_src_uri"], "3":["configure", "test_src_uri", "full_depriving"], "4":["configure", "test_src_uri", "full_depriving", "user_management"], "5":["configure", "test_src_uri", "full_depriving", "user_management"],} def configure(self): if "configure" in capabilities.get(eapi, []): ...call configure phase... return Suggestions regarding using enumerations still dodge that point that via strings, you're building a finite set of matching strings to execute a block of code under, rather then establishing a min/max during which an int eapi should execute a block of code. Latter's a helluva lot simpler then the former. The arguement here is that it's somehow cleaner; it's not really. You still have magic strings ("configure"), and a massive table of capabilities. I used a single capability; if you're doing "has_capability" for every logic check, you're going to get into some very ugly terrain of magic const's all over the place. Further, if attempting to map out what has changed between each eapi version, it's the wrong place to do so; that's implementation right there, specifically python side knowledge of how to support that version. Proper design would actually use a magic constant at the top of the file, CONFIGURE_REQUIRED = 1 or something of the sort. If I want to work on the next extension of eapi, I create an ebuild that has the new incremented #, and I can *already* have that eapi up and running, usurping the previous eapi definition. No forced manual redefinition of stuff that is an easy way to induce bugs (increased manual work == bugs). I can start extending the previous definition, tweaking it to I want without having to gut half of the controlling code. Yes, I'm talking about it from the code perspective, but remember that this is the area that ultimately *matters*; control of the ebuild env is via the python side of things. Keeping that as bug free, and clean as possible is what matters from where I sit; we can extend the ebuild env/template without issue, but swiveling from template to template is totally controlled by python side portage, which means that bit of code best be clean and robust. That said, if you dig through my earlier patch, and comments about needing to handle int conversion better rather then flattening it to 0, the code *is* forwards compatible if someone decides to stick strings into EAPI. In other words, it's a moot debate due to the fact that the internal representation of eapi (is it a string, or is it an int?) is specific to that portage version; whatever version supports an eapi with strings tagged into has the fun of addressing the issues I've brought up above. So basically the debate over string vs int can be left to when someone tries to add a non int eapi; forewarning: I'll bring up these points again when it's raised. It's a Bad Idea (tm), and there is a damn good reason you don't see it elsewhere when dealing with versions of something :) Final comment on this; there's a reason pkgs are release with major/minor as numeric; detection of capabilities, handling capabilities is *much* cleaner via such an approach. ~harring