Confused by Namespace vs app.name and app.label

I opened this now invalid ticket, it turns out I just don’t understand the django way. Having used django for 3 years, I thought I did.

When using reverse(), or {% url '....' %}, I have always passed in the apps.py → AppConfig.name. Now reading up a bit, I think one is supposed to pass in a namespace. However what is a namespace, where does it come from? The docs talk about it, but dont explain how one sets it.

When including urls, historically I have been doing this:
path('foo/', include('applib.foo.urls')),

And it can successfully be reversed using applib.foo as the namespace (which is the AppConfig.name I was passing in).

Should it be:
path('foo/', include('applib.foo.urls', namespace='foo')),
And hence use foo as the namespace?

Are namespaces independant of AppConfig.names? I always thought they were the same thing. If they area different, why does using the app.name work instead of the namespace?