classification
Title: Howto detect if an object is of type os.DirEntry
Type: Stage:
Components: Versions: Python 3.5
process
Status: closed Resolution: out of date
Dependencies: Superseder:
Assigned To: Nosy List: brett.cannon, eryksun, josh.r, r.david.murray, stephan
Priority: normal Keywords:

Created on 2016-10-25 15:46 by stephan, last changed 2016-10-31 23:53 by eryksun. This issue is now closed.

Messages (7)
msg279415 - (view) Author: stephan (stephan) Date: 2016-10-25 15:46
I have a small problem with python 3.5.2 64bit on win7 64 bit:

I cannot check if an object is of type DirEntry 
(os.DirEntry or nt.DirEntry).

Did I misunderstand something or what is wrong?

Here is a log of my console:
-----------------------------------------
In [63]: sd = os.scandir(".")

In [64]: de = next(sd)

In [65]: type(de)
Out[65]: nt.DirEntry

In [66]: import nt

In [67]: nt.DirEntry
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-67-bb02e8263344> in <module>()
----> 1 nt.DirEntry

AttributeError: module 'nt' has no attribute 'DirEntry'

In [68]: os.DirEntry
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-68-5aa7495652fa> in <module>()
----> 1 os.DirEntry

AttributeError: module 'os' has no attribute 'DirEntry'

In [69]:

------------------------------------------
msg279426 - (view) Author: R. David Murray (r.david.murray) * (Python committer) Date: 2016-10-25 17:47
Out of curiosity, what is your use case?

You can grab an object you know is a DirEntry and take its type to get a type object to use in, for example, isinstance.

posix.DirEntry is exposed...either nt.DirEntry should be too, or the posix one shouldn't be, and/or there should be an os.DirEntry superclass.  So, something isn't quite right here no matter how you look at it, IMO.
msg279432 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2016-10-25 17:59
os.DirEntry exists in 3.6, but the change wasn't backported to 3.5. See issue 27038. As a workaround, you can scan a non-empty directory to get a reference to the DirEntry type, e.g.:

    import os
    import tempfile

    with tempfile.NamedTemporaryFile() as f:
        path = os.path.dirname(f.name)
        DirEntry = type(next(os.scandir(path)))
msg279485 - (view) Author: Josh Rosenberg (josh.r) * (Python triager) Date: 2016-10-26 02:34
Eryk: With the fixes for issue25994 and issue26603, you'd want to use a with statement for the scandir; the use pattern in that example is guaranteed to cause a ResourceWarning on any directory with more than one entry.
msg279498 - (view) Author: stephan (stephan) Date: 2016-10-26 12:34
Some questions:
 - if posix.DirEntry is exposed I think nt.DirEntry
   and os.DirEntry (this one is mentioned in the documentation)
   should be exposed
 - will this bw backported to 3.5 lets say 3.5.3?
msg279804 - (view) Author: Brett Cannon (brett.cannon) * (Python committer) Date: 2016-10-31 16:45
As mentioned, this issue is fixed in Python 3.6 by exposing os.DirEntry which is just a direct import of what is in the posix module (which is the same thing as the nt module; name changes depending on the OS so just ignore the posix/nt part of all of this). And we can't backport the addition to the os module as that would break backwards-compatibility in a bug fix release. So I'm closing this as out of date.
msg279840 - (view) Author: Eryk Sun (eryksun) * (Python triager) Date: 2016-10-31 23:53
To clarify, DirEntry is only exposed in the posix/nt and os modules starting in 3.6. To get a reference to it in 3.5 you have to fall back on something like the following:

    import os

    try:
        from os import DirEntry
    except ImportError:
        import tempfile
        with tempfile.NamedTemporaryFile() as ftemp:
            scan = os.scandir(os.path.dirname(ftemp.name))
            DirEntry = type(next(scan))
        del scan, ftemp, tempfile

In 3.5 os.scandir does not support the with statement or raise a resource warning. That behavior was added in 3.6, for which the workaround shouldn't be required.
History
Date User Action Args
2016-10-31 23:53:31eryksunsetmessages: + msg279840
2016-10-31 16:45:03brett.cannonsetstatus: open -> closed

nosy: + brett.cannon
messages: + msg279804

resolution: out of date
2016-10-26 12:34:08stephansetmessages: + msg279498
2016-10-26 02:34:00josh.rsetnosy: + josh.r
messages: + msg279485
2016-10-25 17:59:04eryksunsetnosy: + eryksun
messages: + msg279432
2016-10-25 17:47:33r.david.murraysetnosy: + r.david.murray
messages: + msg279426
2016-10-25 15:46:16stephancreate