I'm using Python 3's type hinting syntax, and I'm writing a small AWS application that uses SQS. I'm trying to hint the type of the Queue. This is how I obtain the type of the Queue:
>>> import boto3
>>> session = boto3.session.Session(
>>> aws_access_key_id=AWS_ACCESS_KEY,
>>> aws_secret_access_key=AWS_SECRET_KEY,
>>> region_name='us-west-2'
>>> )
>>> sqs = session.resource('sqs')
>>> queue=sqs.Queue(AWS_QUEUE_URL)
>>>
>>> type(queue)
<class 'boto3.resources.factory.sqs.Queue'>
And I write my type-hinted function like this:
def get_session() -> boto3.resources.factory.sqs.Queue:
...
But I get an error:
AttributeError: module 'boto3.resources.factory' has no attribute 'sqs'
I've looked through the package myself using dir(...)
. It seems that factory
does not contain sqs
, indeed. Thus, I have two questions:
type
returning this nonexistent class?The class of sqs.Queue
appears to be generated on the fly every time it's called:
>>> import boto3
>>> session = boto3.session.Session(aws_access_key_id='foo', aws_secret_access_key='bar', region_name='us-west-2')
>>> sqs = session.resource('sqs')
>>> sqs.Queue
<bound method sqs.ServiceResource.Queue of sqs.ServiceResource()>
>>> q = sqs.Queue('blah')
>>> type(q)
<class 'boto3.resources.factory.sqs.Queue'>
>>> q2 = sqs.Queue('bluh')
>>> type(q) == type(q2)
False
So that's kind of a bad design choice on boto's end. I think it means it's not possible to reasonably type annotate it, even with forward references.
Your best bet is to give a type hint for the common base class of all these dynamic classes, boto3.resources.base.ServiceResource
:
>>> type(q).__bases__
(<class 'boto3.resources.base.ServiceResource'>,)