(First, let me apologize for diving into a bike shed discussion.) There are two proposed ways to handle custom __format__ methods:
> class MyInt: > def __format__(self, spec): > if int.is_int_specifier(spec): > return int(self).__format__(spec) > return "MyInt instance with custom specifier " + spec > def __int__(self): > return <some local state> and > class MyInt: > def __format__(self, spec): > if is_custom_spec(spec): > return "MyInt instance with custom specifier " + spec > return NotImplemented > def __int__(self): > return <some local state> I think this would be more straightforward as: class MyInt: def __format__(self, spec): if is_MyInt_specific_spec(spec): return "MyInt instance with custom specifier " + spec else: return int(self).__format__(spec) def __int__(self): return <some local state> The makers of the MyInt class should be the ones responsible for knowing that MyInt can be converted to int as needed for output. If they want MyInt to handle all the same format spec options as MyInt, it's up to them to either implement them all in their __format__ or to cast the instance object to int then call its __format__ object by themselves. I don't see the point in having format guess what MyInt should be converted to if it can't handle the options passed to it. If we go too far down this road, if MyInt craps out when given ":MM-DD-YY", then format will be obliged to try casting to Date just to see if it will work. No, I think the format function should be somewhat dumb, since dumb makes more sense to __format__ implementers than clever. Let them figure out what their type can be cast into. In the case that regular int can't handle the given format spec either, int.__format__ will raise (return?) NotImplemented, in which case the format function will try string conversion, and then if that also pukes, a runtime exception should be raised. I also like the idea of using "!r" for calling repr and agree that it should be listed first. The syntax seems to be calling out for a little bit of extension though. Might it be nice to be able to do something like this? s = "10" print("{0!i:+d}".format(s)) #prints "+10" The !i attempts to cast the string to int. If it fails, then an exception is raised. If it succeeds, then the int.__format__ method is used on the remainder of the spec string. The logic is that ! commands are abbreviated functions that are applied to the input before other formatting options are given. On the one hand, this does risk a descent into "line noise" if too many ! options are provided. On the other hand, I think that providing ! options for just repr, str, int, and float probably wouldn't be too bad, and might save some tedious writing of int(s), etc. in spots. It seems like if we're going to have a weird syntax for repr anyway, we might as well use it to make things more convenient in other ways. Or is this too TMTOWTDI-ish, since one could just write int(s) instead? (But by that logic, one could write repr (s) too…) The format function would end up looking like this: def format(obj, spec): if spec[0] == "!": switch statement for applying obj = repr(obj), obj = int (obj), etc. spec = spec[2:] if obj.__format__ and type(obj) is not str: try: #if spec contains letters not understood, __format__ raises NI return obj.__format__(spec) except NotImplemented: pass #everything gets put through str as a last resort return str(obj).__format__(spec) #last chance before throwing exception Does this make sense to anyone else? --Carl Johnson _______________________________________________ Python-3000 mailing list Python-3000@python.org http://mail.python.org/mailman/listinfo/python-3000 Unsubscribe: http://mail.python.org/mailman/options/python-3000/archive%40mail-archive.com