jon_two
jon_two

Reputation: 1238

Can you pass a None argument when docstring requires a string?

Ok, this question has probably been answered somewhere but my Google-fu hasn't found the right combination of keywords yet.

I have a function that accepts a string, but when I pass None, Pycharm's inspection is flagging a type error. Is this an error in the linter? Does None count as a string? I know I can call the function with an empty string, but I think I should be able to use None as well.

def my_func(some_str):
""" does something
Arguments:
some_str (str): a string
"""
    # do something

...

my_func(None)  <-- throws Expected type 'str', got 'None' instead

Upvotes: 5

Views: 5810

Answers (4)

Joooeey
Joooeey

Reputation: 3886

To answer the question in your title: Yes, you can pass None instead of a string. The docstring is ignored at runtime.

The linter just checks if your docstrings match how you use the function. Pycharm rightfully complains that None is not a string. Examples of strings would be "astring", "None" or "". None however is different from a string, it's a specific singleton defined in Python.

However, whether your function will exit successfully or raise an error if you pass in None depends on its source code. E.g. some_str.upper() won't work if you pass in None because the NoneType doesn't have a method called upper.

Finally, if you use docstrings, you should keep them accurate. If you're not willing to do that, you might as well not have docstrings at all. I can't find the exact syntax for this docstring style but something along the lines of the following should work:

""" does something
Arguments:
some_str (str|None): a string
"""

Upvotes: 0

OLIVER.KOO
OLIVER.KOO

Reputation: 6023

First to answer your question None is not a str It is the sole value of type.Nonetype it is a python Built in Contstant. Read about it here. And there are many ways to get around/handle possible None input

1. To get around it, not going to handle None:

is expecting str so of course, it throws an error. just pass in "" instead. but in this case calling my_func(None) would still give you an error.

my_func("") 

2. To Handle possible None input:

if you want to handle None as one of possible input parameter then set your parameter to optional parameter with * that way you can input None and not get an error

def my_func(*some_str):

OR

Default your input to None if the value user pass in is not None then you know user pass in something else: This allows you do to my_func(None) and not get an error

def my_func(some_str = None):
  if some_str:
    #do something

Note: this also allows you treat None and '' equally (thanks to Stael for pointing out)

Upvotes: 3

Stael
Stael

Reputation: 2689

As a dissenting opinion, Python is not strongly typed so for pycharm's linter to highlight that as an error seems a little odd to me.

Of course there are many functions which legitimately need a string, but I'm sure i saw somewhere that 'good practice' for that was a function that looked more like this:

def myfunct(s):
    try:
        s = str(s)
    except TypeError:
        raise TypeError('message explaining function usage')
    # actual function

This works with anything that can be coerced into a string, which seems more sensible than requiring literally a string.

Am I nuts?

Upvotes: 1

BoarGules
BoarGules

Reputation: 16941

None does not count as a string. None is the sole member of the class NoneType.

To do what you want, arrange for your function to accept an optional string argument.

def my_func(some_str: str = None):

Then don't pass it None, pass it nothing:

a = my_func()

Upvotes: 1

Related Questions