This behaviour has been known of course for quite long time. I suppose
this is not intentional so I've played a bit with this and I hope you'll
consider some little change.
Currently, if a ZIP archive contains some subdirectories then
zipfile.ZipFile.extract()/extractall() will create files instead of
directories in the target location. This of course will lead some
scripts to crash (unless any work-around has been done) because files
from the subdirectories couldn't be created.
Attached is a patch against current 2.7 tree. Applied, will make
extractall() extract properly all the contents of the archive with
proper tree structure. If a directory name is passed to the extract(),
it will only create the directory itself without the contents (I guess
it is obvious).

I'm no expert, but is it possible for ZIP files to have Windows-style
path seperators ('\') as well?
And is this new behavior desirable for existing code as well? It might
break existing applications, so perhaps a new extractrecursive()
function is more intuitive.
Finally, I've noticed that the patch does not add any tests to test for
the new/old behavior.

I'm not sure if it would make sense to save current
extract()/extractall() behaviour and implement new with another function
because current one is simply faulty. And if it's about BC breaks then
well... it may be introduced in 3.0 line, I think that leaving faulty
behaviour and introducing another with another function misses the point.
AFAIK there'd be no problem with Windows-style paths but to be sure I
revised my patch.
Yes, I'm sorry for the lack of tests, it is my first patch and I forgot
about this. I'll write them in a couple of hours.

Here is a revised version of the patch with directories support for
write(). It works like UNIX zip program so if a directory path is passed
to the function, it stores only the directory itself (without the contents).
This time without tests as well because I don't want to mess up with
them until I finish my patch completely.

Your usage of os.sep is incorrect, both when reading and writing
directories.
Zip files are (more-or-less) platform independent. The specification
*requires* forward slashes in paths [1], and the zipfile module
already writes them that way. Checking for os.sep is wrong - at least
on Windows.
I've never encountered malformed entries of that kind (like "directory
\" instead of "directory/") but if you want to suport such beasts,
check for "/" *and* os.sep explicitely.
[1] See APPNOTE.TXT (there is a link near the top of zipfile.py)