2

I wish to parse keyword arguments to determine if they also refer to types, such as in the case below:

from inspect import isclass
def convert(converting, **kwargs):
    for key, value in kwargs.items():
        if value and isclass(eval(key[1:])):
            return(eval(key[1:])(converting))
string = "Hello!"
print(convert(string, _list = True))

I am well aware that eval has security concerns for unknown strings, which is why I am looking for a safer method of determining the type from the keyword name.

Built-in types can be checked via import builtins; isclass(getattr(builtins, 'str')), as per a_guest's comment here, but I am still stumped on how to check other classes. Perhaps isclass(getattr(globals(), key[1:]))?

Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
ShadowRylander
  • 361
  • 2
  • 8

1 Answers1

3

Python normally looks up names using LEGB. Since you have no non-locals, you can ignore E. You know that you don't have a local name, so L is gone too. So the equivalent lookup would indeed be a call to globals and a search of builtins.

You don't need a dictionary if all you care about are the keys. That way, you explicitly pass in simple strings and don't need to play games with extra characters:

import builtins
from inspect import isclass

def convert(target, *names):
    for name in names:
        obj = globals().get(name, getattr(builtins, name, None))
        if isclass(obj):
            return obj(target)
    return converting
Mad Physicist
  • 107,652
  • 25
  • 181
  • 264
  • Sorry for the late reply; however, while `__builtins__` could not find `list`, `builtins` the module could. In addition, I had to use `(globals)`. Shall I make the necessary changes and accept this answer? – ShadowRylander Jan 21 '22 at 18:38
  • @ShadowRylander. Please forgive the typos and thanks for the offer to fix. I've fixed the errors. If anything else is missing, please feel free to edit. – Mad Physicist Jan 22 '22 at 00:04
  • Nope; matches up! Thanks for all the help! Accepted! – ShadowRylander Jan 22 '22 at 00:40