Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

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

1,742 views
Skip to first unread message

Satish ML

unread,
Aug 7, 2014, 2:44:28 AM8/7/14
to
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.

Peter Otten

unread,
Aug 7, 2014, 3:00:23 AM8/7/14
to pytho...@python.org
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 ;)

Roy Smith

unread,
Aug 7, 2014, 7:49:05 AM8/7/14
to
In article <mailman.12720.1407394...@python.org>,
Peter Otten <__pet...@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.

Steven D'Aprano

unread,
Aug 7, 2014, 12:56:56 PM8/7/14
to
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

Rustom Mody

unread,
Aug 8, 2014, 1:19:27 AM8/8/14
to
On Thursday, August 7, 2014 10:26:56 PM UTC+5:30, Steven D'Aprano wrote:
> Roy Smith wrote:
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

Rustom Mody

unread,
Aug 8, 2014, 1:35:30 AM8/8/14
to
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

Steven D'Aprano

unread,
Aug 8, 2014, 1:48:17 AM8/8/14
to
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

Rustom Mody

unread,
Aug 8, 2014, 3:17:25 AM8/8/14
to
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...

Chris Angelico

unread,
Aug 8, 2014, 3:32:54 AM8/8/14
to pytho...@python.org
On Fri, Aug 8, 2014 at 5:17 PM, Rustom Mody <rusto...@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
0 new messages