[Python-ideas] Should __builtins__ have some kind of pass-through print function, for debugging?

Chris Barker chris.barker at noaa.gov
Fri Apr 27 12:38:34 EDT 2018


When I teach decorators, I start with a "logged" decorator example:

https://uwpce-pythoncert.github.io/PythonCertDevel/modules/Decorators.html#an-example

def logged_func(func):
    def logged(*args, **kwargs):
        print("Function {} called".format(func.__name__))
        if args:
            print("\twith args: {}".format(args))
        if kwargs:
            print("\twith kwargs: {}".format(kwargs))
        result = func(*args, **kwargs)
        print("\t Result --> {}".format(result))
        return result
    return logged

Interestingly, I don't actually use such a thing in any kind of production,
but it's could be a way to ackomplish what's been proposed here.

As a decorator, we usually would expect to use it with the decoration
syntax:

@logged
def a_new_func():
   ...

But it would also be used to re-bind a already defined function for
testing. using the original example:


while (func1() + 2 * func2()) < func3():

could become "logged" by adding:

func2 = logged(func2)
while (func1() + 2 * func2()) < func3():


I actually like that better than inserting extra code into the line you
want to test.

And I"m pretty clueless about what yu can to with inspect -- but maybe some
more magic could be added in the decorator if you wanted that.

-CHB





On Fri, Apr 27, 2018 at 6:27 AM, Eric Fahlgren <ericfahlgren at gmail.com>
wrote:

> I've had a 'dprint' in sitecustomize for years.  It clones 'print' and
> adds a couple of keyword parameters, 'show_stack' and 'depth', which give
> control over traceback output (walks back up sys._getframe for 'depth'
> entries).  It returns the final argument if there is one, otherwise None.
> It can be used anywhere and everywhere that builtin print is used, plus
> anywhere in any expression just passing a single argument.
>
> I thought about replacing standard print with it, but I like the
> greppability of 'dprint' when it comes time to clean things.
>
>
> On Fri, Apr 27, 2018 at 6:05 AM, Steven D'Aprano <steve at pearwood.info>
> wrote:
>
>> Actually, I think I can think of a way to make this work, if we're
>> willing to resurrect some old syntax.
>>
>> On Fri, Apr 27, 2018 at 09:27:34PM +1000, Steven D'Aprano wrote:
>> > I think that this is either a great idea or pointless, depending on
>> what
>> > the built-in actually does.
>> >
>> > If all it does is literally the debug print function you give:
>> >
>> > > # "debug print": prints and then returns its argument
>> > > def dp(obj):
>> > >     print(repr(obj))
>> > >     return obj
>> >
>> > then it is just a trivial helper as you say, and in my opinion too
>> > trivial to bother making a builtin.
>>
>> I changed my mind... let's add this as a builtin, under the name
>> debugprint. It is a completely normal, non-magical function, which takes
>> four (not one) arguments:
>>
>>
>> def debugprint(obj, lineno=None, module=None, source=None):
>>     out = []
>>     if module is not None:
>>         if lineno is None:
>>             lineno = "?"
>>         out.append(f"Line {lineno} of {module}")
>>     if source is not None:
>>         out.append(ascii(source))
>>     out.append(f"result {repr(obj)}")
>>     print(', '.join(out))
>>     return obj
>>
>>
>> Now let's put all the magic into some syntax. I'm going to suggest
>> resurrecting the `` backtick syntax from Python 2. If that's not
>> visually distinct enough, we could double them: ``expression``.
>>
>> When the compiler sees an expression inside backticks, it grabs the name
>> of the module, the line number, and the expression source, and compiles
>> a call to:
>>
>>     debugprint(expression, lineno, module, source)
>>
>> in its place. That's the only magic needed, and since it is entirely at
>> compile-time, all that information should be easily available. (I hope.)
>> If not, then simply replace the missing values with None.
>>
>> If the caller shadows debugprint, it is their responsibility to either
>> give it the correct signature, or not to use the backticks. Since it's
>> just a normal function call, the worst that happens is that a mismatch
>> in arguments gives you a TypeError.
>>
>> Shadowing debugprint would be an easy way to disable backticks on a
>> per-module basis, at runtime. Simply define:
>>
>> def debugprint(obj, *args):
>>     return obj
>>
>> and Bob's yer uncle.
>>
>>
>>
>> --
>> Steve
>> _______________________________________________
>> Python-ideas mailing list
>> Python-ideas at python.org
>> https://mail.python.org/mailman/listinfo/python-ideas
>> Code of Conduct: http://python.org/psf/codeofconduct/
>>
>
>
> _______________________________________________
> Python-ideas mailing list
> Python-ideas at python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>
>


-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker at noaa.gov
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ideas/attachments/20180427/30ee5dcc/attachment-0001.html>


More information about the Python-ideas mailing list