1

I want to create a function that will be called whenever the caller gets arguments of wrong instance, that will print caller's __doc__ attribute and exit. The function is the following:

def checktype(objects,instances):
    if not all([isinstance(obj,instance) for
                obj,instance in zip(objects,instances)]):
      print 'Type Error'
      #Get __doc__ from caller
      print __doc__
      exit()

I got stuck in the step, where I have to get the __doc__ attribute. I know that inspect module can do it, in a way like the following:

name=inspect.stack()[1][3]
possibles=globals().copy()
__doc__= possibles.get(name).__doc__

(you can suggest another one that is compatible with every Python version, including 3.5)

but I think there must be another way. The reason for my scepticism is that the built-in return statement returns something to the caller in an immediate way, so that means there must be a "hook" or a "pipe" accessible by the child function, which is being used as a medium for information exchange with the parent.So an initial question that triggered my interest was:

Is this pipe send-only and no information can be send backwards?

I have not been able to answer this, as the return statement is only briefly explained in the sites I searched. Apart from this, the inspect module, as far as I can tell, saves multiple frames in a stack and runs constantly in the background. For me, this is like I am trying to kill a fly with a minigun. I just need the caller function's name, not the function 10 frames before. If there is not any way to accomplish this, this is, in my opinion, a feature that Python must have. My question is:

What would be the pythonic-programmatic way to get caller's attributes in Python, with universal support ? Excuse me if there is ignorance in my question, I am open to any corrections and "mind-openings". Thank you all for your answers.

Vasilis Lemonidis
  • 636
  • 1
  • 7
  • 25
  • 1
    I think a decorator would be appropriate for that. – polku Dec 08 '16 at 14:05
  • @polku I would be interested to know how you would pass the function arguments inside the decorator. A wrapper is a nice idea, if I have a signal handler set, but I think this might be suitable only for a Linux distro. – Vasilis Lemonidis Dec 08 '16 at 14:41
  • IDK how familiar you are with decorators but you don't pass it the function arguments. My understanding is that you want a mechanism of type checking reusable for different functions, that's what I'd use (that and a custom exception instead of a print and exit) but maybe I'm getting it wrong. – polku Dec 08 '16 at 15:00

1 Answers1

1

I have a few functions that may be related to your issue

import sys

def position(level = 0):
    """return a tuple (code, lasti, lineno) where this function is called

    If level > 0, go back up to that level in the calling stack.
    """
    frame = sys._getframe(level + 1)
    try:
        return (frame.f_code, frame.f_lasti, frame.f_lineno)
    finally:
        del frame

def line(level = 0):
    """return a tuple (lineno, filename, funcname) where this function is called

    If level > 0, go back up to that level in the calling stack.

    The filename is the name in python's co_filename member
    of code objects.
    """
    code, lasti, lineno = position(level=level+1)
    return (lineno, code.co_filename, code.co_name)

def _globals(level = 0):
    """return the globals() where this function is called

    If level > 0, go back up to that level in the calling stack.

    """
    frame = sys._getframe(level + 1)
    try:
        return frame.f_globals
    finally:
        del frame
Gribouillis
  • 2,230
  • 1
  • 9
  • 14