On Nov 4, 2019, at 00:58, Soni L. <fakedme...@gmail.com> wrote: > > That was meant to be NYI (Not Yet Implemented), sorry. (feel free to treat > "NIY" as "Not Implemented Yet" :P)
Ah. I use NotImplementedError for that, because there are unit testing frameworks that know how to count that differently from other unexpected exceptions—although it can be a problem when what you haven’t finished is an override for an abstract method (so it’s serving a double meaning), that doesn’t come up very often. > It seems useful to me to have the local declared but not defined, because you > haven't got around to implementing what it calls/etc, but you still know what > to do with it. I generally tend to just `foo = None`, but then you run the > risk of that code path actually getting silently taken and messing up program > state. Then you spend hours debugging what went wrong only to find out what > happened. I usually raise NotImplementedError at the very top of the function, because it’s most visible there, and serves as enough of a signal that I don’t need to also add a #TODO comment. And then, I do something like this further down: foo = figure_out_how_to_calculate_from(spam, eggs) Then I don’t need foo = None with a comment saying to figure out how to calculate it from spam and eggs, because the (compiling but not running) code already says that. And if I later think I’ve finished the function and remove the NotImplementedError incorrectly, I’ll get a NameError instead of possibly incorrect values from None. If I needed to test some but not all of the behavior of a partially-written function, I suppose raising in the middle might be helpful. But usually I refactor out the parts I know how to write early when they’re significant enough to be worth testing. But anyway, I appreciate that not everyone works the same way I do, so I can see why you might find foo = raise more useful than me. In particular, if you don’t refactor the function into smaller bits, the raise presumably shows exactly how far you’ve gotten and which part isn’t done yet. > In Rust, for example, one can do `let foo = unimplemented!();`. I actually use this in Rust, but then Rust is pretty different. If you name something figure_out_how_to_calculate without defining it anywhere, you get a compile error rather than a runtime error. You can’t do operations that are guaranteed to be illegal even in code that’s guaranteed not to run. Figuring out the types (which aren’t being inferred for you in half-written code) is sometimes half the work of writing the code. Also, at least for me, bad habits imported from other languages mean I often don’t refactor functions as much (even when it’s easy to prove that the call and moves will get inlined and optimized out, because it’s not easy in C++ I don’t instinctively go there). So for me, that doesn’t transfer into wanting to do the same thing in Python. But again, I can see how for others it might. Anyway, I’m +/-0 on a raise_expr that’s maximally restricted in the way I described, -0 on the same thing but with a rule allowing it to be used on the right side of an assignment (just like yield_expr, so it should be no problem to implement), -0.5 on making it a general expression instead of a heavily restricted one, -1 on making it a magic function (or anything else that’s not backward compatible) instead of syntax, and -0.5 on leaving it as a statement but adding throw to the stdlib somewhere. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-le...@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/T6V3OCWOMLRVEALPLTXDE6RV32LIQYRE/ Code of Conduct: http://python.org/psf/codeofconduct/