Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.python > #75836 > unrolled thread

AttributeError: 'module' object has no attribute 'fork'

Started bySatish ML <satishmlwizpro@gmail.com>
First post2014-08-06 23:44 -0700
Last post2014-08-08 17:32 +1000
Articles 9 — 6 participants

Back to article view | Back to comp.lang.python


Contents

  AttributeError: 'module' object has no attribute 'fork' Satish ML <satishmlwizpro@gmail.com> - 2014-08-06 23:44 -0700
    Re: AttributeError: 'module' object has no attribute 'fork' Peter Otten <__peter__@web.de> - 2014-08-07 09:00 +0200
      Re: AttributeError: 'module' object has no attribute 'fork' Roy Smith <roy@panix.com> - 2014-08-07 07:49 -0400
        Re: AttributeError: 'module' object has no attribute 'fork' Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-08-08 02:56 +1000
          Re: AttributeError: 'module' object has no attribute 'fork' Rustom Mody <rustompmody@gmail.com> - 2014-08-07 22:19 -0700
            Re: AttributeError: 'module' object has no attribute 'fork' Rustom Mody <rustompmody@gmail.com> - 2014-08-07 22:35 -0700
            Re: AttributeError: 'module' object has no attribute 'fork' Steven D'Aprano <steve+comp.lang.python@pearwood.info> - 2014-08-08 15:48 +1000
              Re: AttributeError: 'module' object has no attribute 'fork' Rustom Mody <rustompmody@gmail.com> - 2014-08-08 00:17 -0700
                Re: AttributeError: 'module' object has no attribute 'fork' Chris Angelico <rosuav@gmail.com> - 2014-08-08 17:32 +1000

#75836 — AttributeError: 'module' object has no attribute 'fork'

FromSatish ML <satishmlwizpro@gmail.com>
Date2014-08-06 23:44 -0700
SubjectAttributeError: 'module' object has no attribute 'fork'
Message-ID<7bd83ac7-17e6-49c2-b5c7-3236c900d005@googlegroups.com>
Hi,

Code:
import os, time
def child(pipeout):
    zzz = 0
    while True:
        time.sleep(zzz)
        msg = ('Spam %03d' % zzz).encode()
        os.write(pipeout, msg)
        zzz = (zzz+1) % 5
def parent():
    pipein, pipeout = os.pipe()
    if os.fork() == 0:
        child(pipeout)
    else:
        while True:
            line = os.read(pipein, 32)
            print('Parent %d got [%s] at %s' % (os.getpid(), line, time.time()))
parent()

Output:
Traceback (most recent call last):
  File "C:/Python34/pipe1.py", line 17, in <module>
    parent()
  File "C:/Python34/pipe1.py", line 11, in parent
    if os.fork() == 0:
AttributeError: 'module' object has no attribute 'fork'

Why does this error appear? Module os provides fork(). How to solve this problem? Kindly help.

[toc] | [next] | [standalone]


#75837

FromPeter Otten <__peter__@web.de>
Date2014-08-07 09:00 +0200
Message-ID<mailman.12720.1407394838.18130.python-list@python.org>
In reply to#75836
Satish ML wrote:

> Hi,
> 
> Code:
> import os, time
> def child(pipeout):
>     zzz = 0
>     while True:
>         time.sleep(zzz)
>         msg = ('Spam %03d' % zzz).encode()
>         os.write(pipeout, msg)
>         zzz = (zzz+1) % 5
> def parent():
>     pipein, pipeout = os.pipe()
>     if os.fork() == 0:
>         child(pipeout)
>     else:
>         while True:
>             line = os.read(pipein, 32)
>             print('Parent %d got [%s] at %s' % (os.getpid(), line,
>             time.time()))
> parent()
> 
> Output:
> Traceback (most recent call last):
>   File "C:/Python34/pipe1.py", line 17, in <module>
>     parent()
>   File "C:/Python34/pipe1.py", line 11, in parent
>     if os.fork() == 0:
> AttributeError: 'module' object has no attribute 'fork'
> 
> Why does this error appear? Module os provides fork(). How to solve this
> problem? Kindly help.

Quoting <https://docs.python.org/dev/library/os.html#os.fork>:

"""
os.fork()
Fork a child process.
...
Availability: Unix.
"""

You are using the wrong operating system ;)

[toc] | [prev] | [next] | [standalone]


#75843

FromRoy Smith <roy@panix.com>
Date2014-08-07 07:49 -0400
Message-ID<roy-496ACC.07490507082014@news.panix.com>
In reply to#75837
In article <mailman.12720.1407394838.18130.python-list@python.org>,
 Peter Otten <__peter__@web.de> wrote:

> os.fork()
> Fork a child process.
> ...
> Availability: Unix.
> """
> 
> You are using the wrong operating system ;)

To be honest, this could be considered a buglet in the os module.  It 
really should raise:

NotImplementedError("fork() is only available on unix")

or perhaps even, as Peter suggests:

NotImplementedError("You are using the wrong operating system")

either of those would be better than AttributeError.

[toc] | [prev] | [next] | [standalone]


#75854

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-08-08 02:56 +1000
Message-ID<53e3afd9$0$29970$c3e8da3$5496439d@news.astraweb.com>
In reply to#75843
Roy Smith wrote:

> In article <mailman.12720.1407394838.18130.python-list@python.org>,
>  Peter Otten <__peter__@web.de> wrote:
> 
>> os.fork()
>> Fork a child process.
>> ...
>> Availability: Unix.
>> """
>> 
>> You are using the wrong operating system ;)
> 
> To be honest, this could be considered a buglet in the os module.  It
> really should raise:
> 
> NotImplementedError("fork() is only available on unix")
> 
> or perhaps even, as Peter suggests:
> 
> NotImplementedError("You are using the wrong operating system")
> 
> either of those would be better than AttributeError.


I disagree. How would you tell if fork is implemented? With the current
behaviour, telling whether fork is implemented or not is simple:

is_implemented = hasattr(os, "fork")


With your suggestion:

try:
    pid = os.fork()
except NotImplementedError:
    is_implemented = False
else:
    if pid == 0:
        # In the child process.
        os._exit(0)  # Unconditionally exit, right now, no excuses.
    is_implemented = True


which is not obvious, simple or cheap.


-- 
Steven

[toc] | [prev] | [next] | [standalone]


#75863

FromRustom Mody <rustompmody@gmail.com>
Date2014-08-07 22:19 -0700
Message-ID<f865db66-8cb8-4796-a8f0-bedfb2ef5079@googlegroups.com>
In reply to#75854
On Thursday, August 7, 2014 10:26:56 PM UTC+5:30, Steven D'Aprano wrote:
> Roy Smith wrote:

> >  Peter Otten  wrote:
> >> os.fork()
> >> Fork a child process.
> >> ...
> >> Availability: Unix.
> >> """
> >> You are using the wrong operating system ;)
> > To be honest, this could be considered a buglet in the os module.  It
> > really should raise:
> > NotImplementedError("fork() is only available on unix")
> > or perhaps even, as Peter suggests:
> > NotImplementedError("You are using the wrong operating system")
> > either of those would be better than AttributeError.

> I disagree. How would you tell if fork is implemented? With the current
> behaviour, telling whether fork is implemented or not is simple:

> is_implemented = hasattr(os, "fork")

> With your suggestion:

> try:
>     pid = os.fork()
> except NotImplementedError:
>     is_implemented = False
> else:
>     if pid == 0:
>         # In the child process.
>         os._exit(0)  # Unconditionally exit, right now, no excuses.
>     is_implemented = True

> which is not obvious, simple or cheap.

Surely I am missing something but why not check os.fork before 
checking os.fork() ?

Something along these lines

>>> try:
...   os.fork
... except AttributeError:
...   ii = False
... else:
...   ii = True


Of course more appropriate would be something along the lines:
catch AttributeError and re-raise NotImplementedError

[toc] | [prev] | [next] | [standalone]


#75864

FromRustom Mody <rustompmody@gmail.com>
Date2014-08-07 22:35 -0700
Message-ID<baf02866-34d3-4411-93f8-c3e8e0ef9d04@googlegroups.com>
In reply to#75863
On Friday, August 8, 2014 10:49:27 AM UTC+5:30, Rustom Mody wrote:
> On Thursday, August 7, 2014 10:26:56 PM UTC+5:30, Steven D'Aprano wrote:
> > Roy Smith wrote:

> > >  Peter Otten  wrote:
> > >> os.fork()
> > >> Fork a child process.
> > >> ...
> > >> Availability: Unix.
> > >> """
> > >> You are using the wrong operating system ;)
> > > To be honest, this could be considered a buglet in the os module.  It
> > > really should raise:
> > > NotImplementedError("fork() is only available on unix")
> > > or perhaps even, as Peter suggests:
> > > NotImplementedError("You are using the wrong operating system")
> > > either of those would be better than AttributeError.

> > I disagree. How would you tell if fork is implemented? With the current
> > behaviour, telling whether fork is implemented or not is simple:

> > is_implemented = hasattr(os, "fork")

> > With your suggestion:

> > try:
> >     pid = os.fork()
> > except NotImplementedError:
> >     is_implemented = False
> > else:
> >     if pid == 0:
> >         # In the child process.
> >         os._exit(0)  # Unconditionally exit, right now, no excuses.
> >     is_implemented = True

> > which is not obvious, simple or cheap.

> Surely I am missing something but why not check os.fork before 
> checking os.fork() ?

> Something along these lines

> >>> try:
> ...   os.fork
> ... except AttributeError:
> ...   ii = False
> ... else:
> ...   ii = True

> Of course more appropriate would be something along the lines:
> catch AttributeError and re-raise NotImplementedError

Thinking about this a bit more I see that NotImplemented is under RuntimeError.
Probably a subclass of AttributeError -- PortabilityError?? Cant think of a
good name -- is what is desired

[toc] | [prev] | [next] | [standalone]


#75865

FromSteven D'Aprano <steve+comp.lang.python@pearwood.info>
Date2014-08-08 15:48 +1000
Message-ID<53e464a3$0$30003$c3e8da3$5496439d@news.astraweb.com>
In reply to#75863
Rustom Mody wrote:

> On Thursday, August 7, 2014 10:26:56 PM UTC+5:30, Steven D'Aprano wrote:
>> Roy Smith wrote:
> 
>> >  Peter Otten  wrote:
>> >> os.fork()
>> >> Fork a child process.
>> >> ...
>> >> Availability: Unix.
>> >> """
>> >> You are using the wrong operating system ;)
>> > To be honest, this could be considered a buglet in the os module.  It
>> > really should raise:
>> > NotImplementedError("fork() is only available on unix")
>> > or perhaps even, as Peter suggests:
>> > NotImplementedError("You are using the wrong operating system")
>> > either of those would be better than AttributeError.
> 
>> I disagree. How would you tell if fork is implemented? With the current
>> behaviour, telling whether fork is implemented or not is simple:
> 
>> is_implemented = hasattr(os, "fork")
[...]
> Surely I am missing something but why not check os.fork before
> checking os.fork() ?

Yes, you're missing something. That's what hasattr does.

But with Roy's suggestion, testing for the existence of os.fork is not
sufficient, because it will exist even on platforms where fork doesn't
exist. So testing that os.fork exists is not sufficient to tell whether or
not you can actually fork.

Let's put it another way: code should, when possible, use feature detection
rather than version (or platform) detection:

# No, bad:
if os.name.startswith('linux'):
    pid = os.fork()
else:
    do_something_else()

That's harmful, because:

- perhaps there are other OSes apart from Linux which allow forking;
- maybe some day even Windows;
- and hypothetically there could even be a kind of Linux that doesn't
  allow forking.

Feature detection is much more reliable and future-proof:

if hasattr(os, 'fork'):
    # we don't care what OS, so long as it allows forking
    pid = os.fork()
else:
    do_something_else()


provided os.fork only exists when it does something. Roy's suggestion means
that os.fork will exist even when useless.

Now, many times you can avoid the Look Before You Leap test:

try:
    pid = os.fork()
except AttributeError:  # Or NotImplementedError, in Roy's suggestion.
    do_something_else()


and that's fine too. In this specific scenario, catching NotImplementedError
is no harder than catching AttributeError. But sometimes you want to know
up front whether you can fork later, without committing to forking right
now, and that's where Roy's suggestion becomes painful:

>> try:
>>     pid = os.fork()
>> except NotImplementedError:
>>     is_implemented = False
>> else:
>>     if pid == 0:
>>         # In the child process.
>>         os._exit(0)  # Unconditionally exit, right now, no excuses.
>>     is_implemented = True


Eight lines of tricky, potentially expensive code, versus a cheap hasattr
test.


> Something along these lines
> 
>>>> try:
> ...   os.fork
> ... except AttributeError:
> ...   ii = False
> ... else:
> ...   ii = True

That's just a much more verbose way of writing ii = hasattr(os, 'fork').



-- 
Steven

[toc] | [prev] | [next] | [standalone]


#75868

FromRustom Mody <rustompmody@gmail.com>
Date2014-08-08 00:17 -0700
Message-ID<ca10fd68-16c7-45dc-b281-8a84e83d0b23@googlegroups.com>
In reply to#75865
On Friday, August 8, 2014 11:18:17 AM UTC+5:30, Steven D'Aprano wrote:
> Rustom Mody wrote:

> > On Thursday, August 7, 2014 10:26:56 PM UTC+5:30, Steven D'Aprano wrote:
> >> Roy Smith wrote:
> >> >  Peter Otten  wrote:
> >> >> os.fork()
> >> >> Fork a child process.
> >> >> ...
> >> >> Availability: Unix.
> >> >> """
> >> >> You are using the wrong operating system ;)
> >> > To be honest, this could be considered a buglet in the os module.  It
> >> > really should raise:
> >> > NotImplementedError("fork() is only available on unix")
> >> > or perhaps even, as Peter suggests:
> >> > NotImplementedError("You are using the wrong operating system")
> >> > either of those would be better than AttributeError.
> >> I disagree. How would you tell if fork is implemented? With the current
> >> behaviour, telling whether fork is implemented or not is simple:
> >> is_implemented = hasattr(os, "fork")
> [...]
> > Surely I am missing something but why not check os.fork before
> > checking os.fork() ?

> Yes, you're missing something. That's what hasattr does.

> But with Roy's suggestion, testing for the existence of os.fork is not
> sufficient, because it will exist even on platforms where fork doesn't
> exist. So testing that os.fork exists is not sufficient to tell whether or
> not you can actually fork.

Windows:

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
Type "copyright", "credits" or "license()" for more information.
>>> import os
>>> os.fork

Traceback (most recent call last):
  File "<pyshell#1>", line 1, in <module>
    os.fork
AttributeError: 'module' object has no attribute 'fork'


Linux:

$ python
Python 2.7.8 (default, Jul  4 2014, 13:08:34) 
[GCC 4.9.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> os.fork
<built-in function fork>
>>> 


So yes, I continue to miss something...

[toc] | [prev] | [next] | [standalone]


#75869

FromChris Angelico <rosuav@gmail.com>
Date2014-08-08 17:32 +1000
Message-ID<mailman.12741.1407483183.18130.python-list@python.org>
In reply to#75868
On Fri, Aug 8, 2014 at 5:17 PM, Rustom Mody <rustompmody@gmail.com> wrote:
>> But with Roy's suggestion, testing for the existence of os.fork is not
>> sufficient, because it will exist even on platforms where fork doesn't
>> exist. So testing that os.fork exists is not sufficient to tell whether or
>> not you can actually fork.
>
> Windows:
>
> Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32
> Type "copyright", "credits" or "license()" for more information.
>>>> import os
>>>> os.fork
>
> Traceback (most recent call last):
>   File "<pyshell#1>", line 1, in <module>
>     os.fork
> AttributeError: 'module' object has no attribute 'fork'
>
>
> Linux:
>
> $ python
> Python 2.7.8 (default, Jul  4 2014, 13:08:34)
> [GCC 4.9.0] on linux2
> Type "help", "copyright", "credits" or "license" for more information.
>>>> import os
>>>> os.fork
> <built-in function fork>
>>>>
>
>
> So yes, I continue to miss something...

I think the bit you're missing is the "with Roy's suggestion" bit, at
which os.fork() would be callable and would raise a different error.

It's of course possible for fork() to fail (no memory, ulimit hit, etc
etc etc), but I would expect that the presence of os.fork should
correspond perfectly to the API's availability (at least as detected
by Python's compilation testing).

ChrisA

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.python


csiph-web