One:
Library A takes a callback function, and catches “request.HttpError” when invoking that callback.
The callback throws an exception from a differing version of “request”, which is missing an attribute that the exception handler requires.
What happens? How?
Two:
Library A has a function that returns a “request.Response” object.
Library B has a function that accepts a “request.Response” object, and performs “isinstance”/type equality on the object.
Library A and library B have differing and incompatible dependencies on “request”.
What version of the request object is sent to library B from library A, and how does “isinstance”/“type” interact with it?
Both of these resolve around class identities. In Python they are intrinsically linked to the defining module. Either you break this invariant and have two incompatible/different types have the same identity and introduce all kinds of bugs, or you don’t and also introduce all kinds of bugs - “yes, this is a request.Response object, but this method doesn’t exist on this request.Response object”, or “yes this is someone’s request.Response object, but it’s not your request.Response object”
Getting different module imports to succeed is more than possible, getting them to work together is another thing entirely.
One solution to this is the concept of visibility, which in Python is famously “not really a thing”. It’s safe to use incompatible versions of a library as long as the types are not visible - I.e no method returns a request.Response object, so the module is essentially a completely private implementation detail. This is how Rust handles this, I think.
However is obviously fucked by exceptions, so it seems pretty intractable.