problem with global scope after package import via __init__.py

Mark Frazer mark at somanetworks.com
Tue Aug 13 11:23:41 EDT 2002


I'd like to build a package out of several files as the individual files
are large and become inwieldy.  Generally, I want a package user to
import package
only, and not worry about the individual files, so the __init__.py for
the package does
from file import *
for all the files in the package.

However, there seems to be a problem accessing scalars when the package
is imported in this fashion.  The package files themselves can access the
scalar properly, but the package user cannot.  Is this a bug?

I've checked the FAQ and the documentation and googled a bit, but can't
really find a description of this problem elsewhere.

The following shar file will create four tests on a simple package to
illustrate the problem.  You can also grab a tar file from
http://mjfrazer.org/~mark/py.tar if you won't trust a shar.

1) run the shar file or extract everything from the tar file.
2) p/a.py p/b.py and p/c.py all run as expected (cd p and run them)
3) ./pass.py imports part 'a' of the package directly and all runs fine
4) ./fail.py imports the package via the package name, p.  The __init__ for
   the package brings in a.  Referencing a scalar through the package fails.

BTW:  I'm using python2-2.2-16 RPM from the RedHat 7.3 distro.
-mark
-- 
I'm going to continue never washing this cheek again. - Fry

-- CUT HERE --
#!/bin/sh
# This is a shell archive (produced by GNU sharutils 4.2.1).
# To extract the files from this archive, save it to some FILE, remove
# everything before the `!/bin/sh' line above, then type `sh FILE'.
#
# Made on 2002-08-13 11:20 EDT by <mjfrazer at frogger>.
# Source directory was `/export/home/mjfrazer/pytest'.
#
# Existing files will *not* be overwritten unless `-c' is specified.
#
# This shar contains:
# length mode       name
# ------ ---------- ------------------------------------------
#    165 -rwxr-xr-x fail.py
#    181 -rwxr-xr-x pass.py
#     34 -rw-r--r-- p/__init__.py
#    214 -rwxr-xr-x p/a.py
#    196 -rwxr-xr-x p/b.py
#    134 -rwxr-xr-x p/c.py
#
save_IFS="${IFS}"
IFS="${IFS}:"
gettext_dir=FAILED
locale_dir=FAILED
first_param="$1"
for dir in $PATH
do
  if test "$gettext_dir" = FAILED && test -f $dir/gettext \
     && ($dir/gettext --version >/dev/null 2>&1)
  then
    set `$dir/gettext --version 2>&1`
    if test "$3" = GNU
    then
      gettext_dir=$dir
    fi
  fi
  if test "$locale_dir" = FAILED && test -f $dir/shar \
     && ($dir/shar --print-text-domain-dir >/dev/null 2>&1)
  then
    locale_dir=`$dir/shar --print-text-domain-dir`
  fi
done
IFS="$save_IFS"
if test "$locale_dir" = FAILED || test "$gettext_dir" = FAILED
then
  echo=echo
else
  TEXTDOMAINDIR=$locale_dir
  export TEXTDOMAINDIR
  TEXTDOMAIN=sharutils
  export TEXTDOMAIN
  echo="$gettext_dir/gettext -s"
fi
if touch -am -t 200112312359.59 $$.touch >/dev/null 2>&1 && test ! -f 200112312359.59 -a -f $$.touch; then
  shar_touch='touch -am -t $1$2$3$4$5$6.$7 "$8"'
elif touch -am 123123592001.59 $$.touch >/dev/null 2>&1 && test ! -f 123123592001.59 -a ! -f 123123592001.5 -a -f $$.touch; then
  shar_touch='touch -am $3$4$5$6$1$2.$7 "$8"'
elif touch -am 1231235901 $$.touch >/dev/null 2>&1 && test ! -f 1231235901 -a -f $$.touch; then
  shar_touch='touch -am $3$4$5$6$2 "$8"'
else
  shar_touch=:
  echo
  $echo 'WARNING: not restoring timestamps.  Consider getting and'
  $echo "installing GNU \`touch', distributed in GNU File Utilities..."
  echo
fi
rm -f 200112312359.59 123123592001.59 123123592001.5 1231235901 $$.touch
#
if mkdir _sh30408; then
  $echo 'x -' 'creating lock directory'
else
  $echo 'failed to create lock directory'
  exit 1
fi
# ============= fail.py ==============
if test -f 'fail.py' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'fail.py' '(file already exists)'
else
  $echo 'x -' extracting 'fail.py' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'fail.py' &&
#!/usr/bin/env python2
X
import p
X
val = 10
p.set_a (val)
X
print "p.get_a() is ", p.get_a ()
assert p.get_a () == val
print "p.aval is ", p.aval
assert p.aval == val
SHAR_EOF
  (set 20 02 08 13 11 11 55 'fail.py'; eval "$shar_touch") &&
  chmod 0755 'fail.py' ||
  $echo 'restore of' 'fail.py' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'fail.py:' 'MD5 check failed'
9eac9c4d21fb224148fbad6766abcca5  fail.py
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'fail.py'`"
    test 165 -eq "$shar_count" ||
    $echo 'fail.py:' 'original size' '165,' 'current size' "$shar_count!"
  fi
fi
# ============= pass.py ==============
if test -f 'pass.py' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'pass.py' '(file already exists)'
else
  $echo 'x -' extracting 'pass.py' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'pass.py' &&
#!/usr/bin/env python2
X
import p.a
X
val = 10
p.a.set_a (val)
X
print "p.a.get_a() is ", p.a.get_a ()
assert p.a.get_a () == val
print "p.a.aval is ", p.a.aval
assert p.a.aval == val
SHAR_EOF
  (set 20 02 08 13 11 11 33 'pass.py'; eval "$shar_touch") &&
  chmod 0755 'pass.py' ||
  $echo 'restore of' 'pass.py' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'pass.py:' 'MD5 check failed'
8ff0024598ae43847825558ef4a37767  pass.py
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'pass.py'`"
    test 181 -eq "$shar_count" ||
    $echo 'pass.py:' 'original size' '181,' 'current size' "$shar_count!"
  fi
fi
# ============= p/__init__.py ==============
if test ! -d 'p'; then
  $echo 'x -' 'creating directory' 'p'
  mkdir 'p'
fi
if test -f 'p/__init__.py' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'p/__init__.py' '(file already exists)'
else
  $echo 'x -' extracting 'p/__init__.py' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'p/__init__.py' &&
#__all__ = ['a']
X
from a import *
SHAR_EOF
  (set 20 02 08 13 11 20 06 'p/__init__.py'; eval "$shar_touch") &&
  chmod 0644 'p/__init__.py' ||
  $echo 'restore of' 'p/__init__.py' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'p/__init__.py:' 'MD5 check failed'
a3846160ba2d4711eab1f6446a17b2fd  p/__init__.py
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'p/__init__.py'`"
    test 34 -eq "$shar_count" ||
    $echo 'p/__init__.py:' 'original size' '34,' 'current size' "$shar_count!"
  fi
fi
# ============= p/a.py ==============
if test -f 'p/a.py' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'p/a.py' '(file already exists)'
else
  $echo 'x -' extracting 'p/a.py' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'p/a.py' &&
#!/usr/bin/env python2
X
aval = -999
X
def set_a (val):
X	global aval
X	aval = val
def get_a ():
X	global aval
X	return aval
X
if __name__ == "__main__":
X	val = 10
X	set_a (val)
X	assert get_a () == val
X	assert aval == val
SHAR_EOF
  (set 20 02 08 13 10 19 26 'p/a.py'; eval "$shar_touch") &&
  chmod 0755 'p/a.py' ||
  $echo 'restore of' 'p/a.py' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'p/a.py:' 'MD5 check failed'
ecb1c6ef77a47926660d2d1002004862  p/a.py
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'p/a.py'`"
    test 214 -eq "$shar_count" ||
    $echo 'p/a.py:' 'original size' '214,' 'current size' "$shar_count!"
  fi
fi
# ============= p/b.py ==============
if test -f 'p/b.py' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'p/b.py' '(file already exists)'
else
  $echo 'x -' extracting 'p/b.py' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'p/b.py' &&
#!/usr/bin/env python2
X
import a
X
def set_a2 (val):
X	a.aval = val
X
def get_a2 ():
X	return a.aval
X
if __name__ == "__main__":
X	val = 10
X	set_a2 (val)
X	assert get_a2 () == val
X	assert a.aval == val
SHAR_EOF
  (set 20 02 08 13 11 02 17 'p/b.py'; eval "$shar_touch") &&
  chmod 0755 'p/b.py' ||
  $echo 'restore of' 'p/b.py' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'p/b.py:' 'MD5 check failed'
b47de8f7d6dd2151b18e2509d96457c7  p/b.py
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'p/b.py'`"
    test 196 -eq "$shar_count" ||
    $echo 'p/b.py:' 'original size' '196,' 'current size' "$shar_count!"
  fi
fi
# ============= p/c.py ==============
if test -f 'p/c.py' && test "$first_param" != -c; then
  $echo 'x -' SKIPPING 'p/c.py' '(file already exists)'
else
  $echo 'x -' extracting 'p/c.py' '(text)'
  sed 's/^X//' << 'SHAR_EOF' > 'p/c.py' &&
#!/usr/bin/env python2
X
import a
X
if __name__ == "__main__":
X	val = 10
X	a.set_a (val)
X	assert a.get_a () == val
X	assert a.aval == val
SHAR_EOF
  (set 20 02 08 13 11 02 37 'p/c.py'; eval "$shar_touch") &&
  chmod 0755 'p/c.py' ||
  $echo 'restore of' 'p/c.py' 'failed'
  if ( md5sum --help 2>&1 | grep 'sage: md5sum \[' ) >/dev/null 2>&1 \
  && ( md5sum --version 2>&1 | grep -v 'textutils 1.12' ) >/dev/null; then
    md5sum -c << SHAR_EOF >/dev/null 2>&1 \
    || $echo 'p/c.py:' 'MD5 check failed'
5ba41c6f1fb89fa2fb5115832aaced58  p/c.py
SHAR_EOF
  else
    shar_count="`LC_ALL= LC_CTYPE= LANG= wc -c < 'p/c.py'`"
    test 134 -eq "$shar_count" ||
    $echo 'p/c.py:' 'original size' '134,' 'current size' "$shar_count!"
  fi
fi
rm -fr _sh30408
exit 0




More information about the Python-list mailing list