weird isinstance/issubclass behavior?

Discussion in 'Python' started by lars van gemerden, Nov 29, 2012.

  1. Hi,

    I have encountered some strange behavior of isinstance(/issubclass): depending on the import path used for classes i get different output, while the classes i compare are in the same file.

    Basically if i import a class as:

    from mod1.mod2 import A

    or:

    from mod0.mod1.mod2 import A

    which both result in importing the same class, a call to isinstance(inst, A) in another module can have a different output. In this module

    print type(inst), A, isinstance(inst, A), issubclass(type(inst), A)

    gives:

    <class 'mod0.mod1.mod2.A'> <class 'mod1.mod2.A'> False False

    resp.

    <class 'mod0.mod1.mod2.A'> <class 'mod0.mod1.mod2.A'> True True

    which seems somewhat logical, but in my case a strange gotcha. My question is:
    Is this intended, inevitable or a bug?

    Cheers, Lars

    PS: this is somewhat simpler than the actual case i've encountered, and i haven't tested this exact case, but for now i hope this is enough to get some of your insight.
    lars van gemerden, Nov 29, 2012
    #1
    1. Advertising

  2. On Fri, Nov 30, 2012 at 1:59 AM, lars van gemerden <> wrote:
    > Basically if i import a class as:
    >
    > from mod1.mod2 import A
    >
    > or:
    >
    > from mod0.mod1.mod2 import A
    >
    > which both result in importing the same class, a call to isinstance(inst, A) in another module can have a different output.


    What you may be seeing there is that you've imported the module twice.
    There are two entirely separate module objects, taken from the same
    file. Something instantiated from one class isn't an instance of the
    other class even if they're indistinguishable classes; a little
    monkeypatching might show you what's going on (fiddle with one class,
    check the other, fiddle hasn't happened).

    As a general rule, importing a module in different ways is considered
    dangerous. Be consistent, and then this sort of oddity won't occur -
    and you also won't have other oddities, eg with other global state.

    ChrisA
    Chris Angelico, Nov 29, 2012
    #2
    1. Advertising

  3. On Thursday, November 29, 2012 3:59:37 PM UTC+1, lars van gemerden wrote:
    > Hi,
    >
    >
    >
    > I have encountered some strange behavior of isinstance(/issubclass): depending on the import path used for classes i get different output, while the classes i compare are in the same file.
    >
    >
    >
    > Basically if i import a class as:
    >
    >
    >
    > from mod1.mod2 import A
    >
    >
    >
    > or:
    >
    >
    >
    > from mod0.mod1.mod2 import A
    >
    >
    >
    > which both result in importing the same class, a call to isinstance(inst, A) in another module can have a different output. In this module
    >
    >
    >
    > print type(inst), A, isinstance(inst, A), issubclass(type(inst), A)
    >
    >
    >
    > gives:
    >
    >
    >
    > <class 'mod0.mod1.mod2.A'> <class 'mod1.mod2.A'> False False
    >
    >
    >
    > resp.
    >
    >
    >
    > <class 'mod0.mod1.mod2.A'> <class 'mod0.mod1.mod2.A'> True True
    >
    >
    >
    > which seems somewhat logical, but in my case a strange gotcha. My question is:
    >
    > Is this intended, inevitable or a bug?
    >
    >
    >
    > Cheers, Lars
    >
    >
    >
    > PS: this is somewhat simpler than the actual case i've encountered, and i haven't tested this exact case, but for now i hope this is enough to get some of your insight.


    I know for sure that the imports both import the same file, though if i understand you correctly, it creates 2 different module objects? Are module object only created on an import statement?

    The 2 parameters of isinstance() follow a very different import path.

    Anyway, to not spend too much time us this, i'll just file it under 'dangerous' and use the second import statement. It does solve my problem.

    Thanks, Lars
    lars van gemerden, Nov 29, 2012
    #3
  4. lars van gemerden

    Terry Reedy Guest

    On 11/29/2012 9:59 AM, lars van gemerden wrote:
    > Hi,
    >
    > I have encountered some strange behavior of isinstance(/issubclass): depending on the import path used for classes i get different output, while the classes i compare are in the same file.
    >
    > Basically if i import a class as:
    >
    > from mod1.mod2 import A
    > or:
    > from mod0.mod1.mod2 import A
    >
    > which both result in importing the same class,


    As other said, both import the same abstract class but create two
    different concrete class objects.

    > a call to isinstance(inst, A) in another module can have a different

    output.
    > In this module
    > print type(inst), A, isinstance(inst, A), issubclass(type(inst), A)
    > gives:
    > <class 'mod0.mod1.mod2.A'> <class 'mod1.mod2.A'> False False


    Add print id(type(inst)), id(A) and you will see that they are different
    objects. The isinstance and issubclass calls compare the classes by
    identity (the default meaning of ==) and so False, False are correct.

    --
    Terry Jan Reedy
    Terry Reedy, Nov 29, 2012
    #4
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Chris Green

    when does issubclass fail?

    Chris Green, Apr 16, 2004, in forum: Python
    Replies:
    1
    Views:
    289
    =?ISO-8859-1?Q?Walter_D=F6rwald?=
    Apr 20, 2004
  2. Nathan Bullock

    How do you make issubclass work

    Nathan Bullock, Sep 11, 2004, in forum: Python
    Replies:
    4
    Views:
    606
    Alex Martelli
    Sep 11, 2004
  3. Osmo Maatta
    Replies:
    3
    Views:
    466
    Osmo Maatta
    Aug 29, 2010
  4. kj

    issubclass(dict, Mapping)

    kj, Dec 22, 2010, in forum: Python
    Replies:
    10
    Views:
    525
  5. kj
    Replies:
    5
    Views:
    396
Loading...

Share This Page