Numpy: Terkadang, supress_warnings melewatkan salah satu atributnya

Dibuat pada 23 Des 2016  ·  60Komentar  ·  Sumber: numpy/numpy

Saat mencoba mengompilasi skimage, terkadang saya mendapatkan error berikut:

Traceback (most recent call last):
  File "/usr/lib/python2.7/dist-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/build/skimage-0.12.3/debian/tmp/usr/lib/python2.7/dist-packages/skimage/transform/tests/test_integral.py", line 46, in test_vectorized_integrate
    assert_equal(expected, integrate(s, r0, c0, r1, c1))  # test deprecated
  File "/build/skimage-0.12.3/debian/tmp/usr/lib/python2.7/dist-packages/skimage/transform/integral.py", line 86, in integrate
    warn("The syntax 'integrate(ii, r0, c0, r1, c1)' is "
  File "/build/skimage-0.12.3/debian/tmp/usr/lib/python2.7/dist-packages/skimage/_shared/_warnings.py", line 16, in warn
    warnings.warn(message, stacklevel=stacklevel)
  File "/usr/lib/python2.7/dist-packages/numpy/testing/utils.py", line 2199, in _showwarning
    self._orig_show(message, category, filename, lineno,
AttributeError: 'suppress_warnings' object has no attribute '_orig_show'

Saya menganggap ini adalah masalah numpy, tapi saya tidak yakin.

00 - Bug numpy.testing

Semua 60 komentar

Hmmm, agak aneh. Apakah ada ulir (aneh) yang terjadi dalam tes skimage? Hal itu akan sangat merusak pengujian peringatan, karena penanganan peringatan tidak aman untuk thread di python. Saya memiliki sedikit kesulitan untuk melihat bagaimana lagi ini bisa terjadi, tetapi mungkin harus melihat kode yang tepat saat pengujian dijalankan.

Karena tidak ada assert_warns atau lebih di sini kurasa. Anda seharusnya hanya memiliki satu konteks suppress_warnings akan hidup (yang akan menjadi cakupan terluar dan dibuat oleh runner uji numpy, dengan asumsi skimage akhirnya menggunakannya). Sekarang mengapa saya bingung, adalah bahwa _orig_show tidak didefinisikan seharusnya hanya mungkin jika konteksnya sudah keluar. Pada saat itu warnings.showwarning seharusnya sudah disetel ulang ke nilai lama.

Tentu saja seluruh hal peringatan rusak jika Anda memiliki utas. Sebagai contoh:

thread1: memasuki konteks peringatan -> menggantikan pencetakan peringatan normal
thread2: memasuki konteks peringatan -> menggantikan penanganan peringatan thread1
thread1: keluar dari konteks peringatan -> mengatur ulang ke pencetakan peringatan normal
thread2: ada konteks peringatan -> setel ulang ke penanganan peringatan thread1 -> kaboom.

Btw. Saya melihat Anda memiliki "mencoba untuk membersihkan setelah __warning_registry__ barang dalam skimage, peringatan penekan adalah manajer konteks yang mencoba untuk memecahkan masalah serupa (dan menambahkan beberapa hal lain), mungkin atau mungkin tidak menarik.

Saya baru saja mendapat masalah saat mencoba membuat skimage untuk Debian, dan saya tidak tahu di sini. Namun, saya membuka scikit-image / scikit-image # 2412 agar mereka terlibat.

Hanya untuk kelengkapan: Terkadang, saya bahkan mendapatkan stacktrace tanpa melibatkan skimage:

ERROR: test suite for <module 'skimage.transform.tests' from '/build/skimage-0.12.3/debian/tmp/usr/lib/python3/dist-packages/skimage/transform/tests/__init__.py'>
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/nose/suite.py", line 229, in run
    self.tearDown()
  File "/usr/lib/python3/dist-packages/nose/suite.py", line 352, in tearDown
    self.teardownContext(ancestor)
  File "/usr/lib/python3/dist-packages/nose/suite.py", line 368, in teardownContext
    try_run(context, names)
  File "/usr/lib/python3/dist-packages/nose/util.py", line 453, in try_run
    inspect.getargspec(func)
  File "/usr/lib/python3.5/inspect.py", line 1040, in getargspec
    stacklevel=2)
  File "/usr/lib/python3/dist-packages/numpy/testing/utils.py", line 2199, in _showwarning
    self._orig_show(message, category, filename, lineno,
AttributeError: 'suppress_warnings' object has no attribute '_orig_show'

Versi python, numpy, dll., Yang Anda kompilasi?

Numpy 1.12 ~ RC ~ beta 1, Python 2.7 dan 3.5
(maaf, kesalahan saya: belum memeriksa RC)

Hmm, saya bingung .... Saya tidak dapat melihat mengapa akan ada masalah threading, tetapi juga tidak dapat benar-benar memahami kesalahan ini yang terjadi tanpa kondisi balapan atau penumpukan yang salah dari catch_warning seperti barang (termasuk suppress_warning ).

Saya juga berpikir ini adalah kondisi balapan, karena itu tidak selalu terjadi. Menjalankan build dua kali di bawah lingkungan yang persis sama memungkinkan masalah muncul di tempat yang berbeda (atau bahkan tidak sama sekali).

@olebole bagaimana tepatnya Anda menjalankan tes setelan?

Disalin dari rangkaian pengujian kami:

#!/bin/sh
set -efu

pys="$(pyversions -rv 2>/dev/null)"
pkgbuild=${pkgbuild:-no}

srcdir=$PWD

for py in $pys; do
    echo "=== python$py ==="
    if [ "$pkgbuild" = "yes" ]; then
        export PYTHONPATH="$srcdir/debian/tmp/usr/lib/python$py/dist-packages"
        cd "$srcdir/build/"
    else
        cd "$ADTTMP"
    fi

    xvfb-run -a python$py /usr/bin/nosetests -s -v --exclude test_tools.py skimage 2>&1
done

xvfb-run ada di sana karena pengujian perlu dijalankan di lingkungan X11.

Hmmmpf, ada yang tahu apa yang sebenarnya terjadi di bawah kap ketika hidung mulai menguji modul? Hidung membingungkan saya, dan saya tidak bisa melihat mengapa itu akan berakhir juga bermain-main dengan peringatan .... Atau itu adalah bug dalam peringatan penekan, tetapi tidak bisa benar-benar melihatnya, heh.

Di halaman manual nosetests saya, saya punya

       --processes=NUM
              Spread  test run among this many processes. Set a number equal to the number of processors or cores in your machine for best results. Pass a negative
              number to have the number of processes automatically set to the number of cores. Passing 0 means to disable parallel testing.  Default  is  0  unless
              NOSE_PROCESSES is set. [NOSE_PROCESSES]

Tampaknya tidak ada pengujian paralel secara default. Setidaknya, kondisi balapan seharusnya tidak ada.

Apakah ada kemungkinan kecil bahwa hidung menjalankan teardownContext berdasarkan hal-hal pengumpulan sampah ?!

Tidak, saya mungkin konyol. Konteks peringatan penekanan mereset warnings.showwarning sebelum menghapus atribut jadi keraguan bahkan gc yang menendang tidak dapat benar-benar membuat apa pun tanpa sesuatu yang lain terjadi. Baru saja tidak tahu apa lagi :).

Yah, saya melihat 33 kesalahan dengan skimage-0.9.3, sebagian besar dari PIL atau pengindeksan, tetapi tidak ada yang bisa ditekan. Bagaimana Anda menangani semua kesalahan lainnya?

@charris Masalah ini dilaporkan untuk 0.12.3, bukan 0.9.3. :)

Oke, akhirnya ditarik ke bawah dari hulu, sekarang ada 39 kesalahan dan banyak sekali penghentian. Sebagian besar peringatan muncul karena fakta bahwa tes mengira mereka berjalan di QT dan bukan Wayland, mungkin menjadi masalah konfigurasi di sini. Saya juga perlu menjalankan tes sebagai

python -c'import skimage; skimage.test()'

karena nosetests tidak berfungsi sama sekali.

Penghentian itu normal. Kami masih memeriksa API lama kami, meskipun diperkirakan akan ada penghentian. Soal kesalahan, itu tidak normal. Maukah Anda melaporkannya di pelacak bug (scikit-image) kami?

@sciunto Dokumen dapat menggunakan instruksi untuk pengujian secara lokal.

Oke, saya melihatnya di tempat yang sama. Ujiannya adalah

def test_vectorized_integrate():
    r0 = np.array([12, 0, 0, 10, 0, 10, 30])
    c0 = np.array([10, 0, 10, 0, 0, 10, 31])
    r1 = np.array([23, 19, 19, 19, 0, 10, 49])
    c1 = np.array([19, 19, 19, 19, 0, 10, 49])

    expected = np.array([x[12:24, 10:20].sum(),
                         x[:20, :20].sum(),
                         x[:20, 10:20].sum(),
                         x[10:20, :20].sum(),
                         x[0,0],
                         x[10, 10],
                         x[30:, 31:].sum()])
    start_pts = [(r0[i], c0[i]) for i in range(len(r0))]
    end_pts = [(r1[i], c1[i]) for i in range(len(r0))]
    assert_equal(expected, integrate(s, r0, c0, r1, c1))  # test deprecated
    assert_equal(expected, integrate(s, start_pts, end_pts))

Komentar # test deprecated menyarankan kepada saya bahwa mungkin pengujian perlu diperbaiki, tetapi suppress_warnings harus gagal dengan lebih baik.

Sedikit lebih banyak informasi, lakukan

$ python skimage/transform/tests/test_integral.py

Yang menggunakan NumPy run_module_suite sepertinya tidak gagal, tetapi mengeluarkan peringatan

======================================================================
ERROR: skimage.transform.tests.test_integral.test_vectorized_integrate
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
    self.test(*self.arg)
  File "/home/charris/Workspace/scikit-image/skimage/transform/tests/test_integral.py", line 46, in test_vectorized_integrate
    assert_equal(expected, integrate(s, r0, c0, r1, c1))  # test deprecated
  File "/home/charris/Workspace/scikit-image/skimage/transform/integral.py", line 86, in integrate
    warn("The syntax 'integrate(ii, r0, c0, r1, c1)' is "
  File "/home/charris/Workspace/scikit-image/skimage/_shared/_warnings.py", line 16, in warn
    warnings.warn(message, stacklevel=stacklevel)
UserWarning: The syntax 'integrate(ii, r0, c0, r1, c1)' is deprecated, and will be phased out in release 0.14. The new syntax is 'integrate(ii, (r0, c0), (r1, c1))'.

Perhatikan bahwa scikit-image memiliki pengelola konteksnya sendiri untuk peringatan di skimage/_shared/_warnings.py . Itu mungkin bertentangan dengan suppress_warnings .

Karena penasaran, saya bertanya-tanya apakah ada bedanya untuk secara eksplisit menentukan DeprecationWarning daripada menggunakan default UserWarning .

Jadi saya tidak melihat kesalahan dengan

$ nosetests-2.7 skimage/transform/tests/test_integral.py |& grep orig_show

Sedangkan

$ nosetests-2.7 skimage/transform/tests/ |& grep orig_show

Tunjukkan sekitar 25% dari waktu. Itu menunjukkan bahwa sumber kesalahan terletak di tempat lain dan pengujian yang gagal hanya akan mengeksposnya.

Secara khusus, skimage/transform/tests/test_geometric.py berisi pengelola konteks peringatan expected_warnings dan itu membuat saya curiga.

Oke, sekarang saya mencurigai test_parallel decorator, https://github.com/scikit-image/scikit-image/blob/master/skimage/_shared/testing.py . Defaultnya adalah dua utas.

Jika saya menghapus tiga file yang mengimpor test_parallel , tidak ada masalah lagi.

EDIT: Dan sekarang saya tidak bisa mereproduksi masalah sama sekali. Hmm ... Mungkin juga tergantung pada apa lagi yang berjalan di mesin.

Hmmm, saya rasa test_parallel mungkin saja, meskipun melihat-lihat kode, tidak ada fungsi yang jelas menggunakan konteks peringatan, meskipun bukan tidak mungkin saya kira.

sesuatu di test_hough_transform.py tampaknya menjadi pemrakarsa. Dengan file itu dihapus tidak ada kesalahan.

EDIT: Mungkin karena mendahului modul test_integral.py ?

Masalahnya adalah tes ini di test_hough_transform.py

@test_parallel()
def test_hough_circle():
    # Prepare picture
    img = np.zeros((120, 100), dtype=int)
    radius = 20
    x_0, y_0 = (99, 50)
    y, x = circle_perimeter(y_0, x_0, radius)
    img[x, y] = 1

    out1 = tf.hough_circle(img, radius)
    out2 = tf.hough_circle(img, [radius])
    assert_equal(out1, out2)
    out = tf.hough_circle(img, np.array([radius], dtype=np.intp))
    assert_equal(out, out1)
    x, y = np.where(out[0] == out[0].max())
    assert_equal(x[0], x_0)
    assert_equal(y[0], y_0)

secara khusus, salah satu dari dua garis

    assert_equal(out1, out2)

# or

    assert_equal(out, out1)

Akan mengaktifkan kesalahan.

Demikian pula, menghapus dekorator @parallel memperbaiki kesalahan. Jadi hasilnya adalah bahwa utas dalam kombinasi dengan assert_equal dipanggil dengan vektor menyebabkan masalah.

Masuk akal, fungsi assert equal menggunakannya untuk menyaring ".*NAT ==" peringatan, kita mungkin bisa mencoba untuk menghapusnya dari fungsi itu karena tidak terlalu jelas bahwa assert_equal melakukan penindasan peringatan (dan karenanya tidak sepenuhnya dukungan threading).

Bagus melacak Chuck!

Mencoba menghapusnya akan menjadi hal yang baik.

Saya ingin tahu apakah ada fungsi numpy lain yang tidak aman untuk thread?

Tidak yakin, saya pikir kami hanya menggunakan barang peringatan dalam setelan tes. Dan np.errstate mungkin threadsafe?

terima kasih banyak atas investigasi yang bagus ini @charris dan @seberg

Hmmm, menurutku agak mengganggu. Menghapus penindasan dari tempatnya mungkin mengubah perilaku untuk hilir, itu mungkin baik-baik saja (bahkan mungkin lebih bersih), tetapi tidak yakin itu bagus untuk rilis perbaikan bug. Bisa juga mengunci mutex pada tes jenis perbandingan, yang mungkin tidak selalu baik-baik saja pada prinsipnya, tetapi saya tidak bisa benar-benar memikirkan bagaimana itu bisa rusak.

Saya pikir itu akan cukup untuk hanya memperbaiki assert_equal , itu perlu diperbaiki di masa depan untuk perbandingan NaT dalam hal apapun. Perhatikan bahwa NaT dapat diubah menjadi int64 dan memiliki nilai min_int64.

Oh, benar, kami sebenarnya hanya dapat mendukung NaT secara eksplisit, agak mengganggu saat ini (karena tidak ada fungsi untuk melakukan pengecekan NaT secara khusus), tetapi tidak sulit. Ada hal lain dari hal-hal ini di sekitar perbandingan array lainnya, tapi saya rasa itu tidak banyak digunakan (dan tidak yakin untuk apa).

Menambahkan logika NaT ke asserts tampaknya bekerja dengan cukup baik untuk master, meskipun saya tidak yakin itu akan berhasil untuk backporting. Saya pikir meskipun suppress_warnings mungkin baru, kondisi balapannya sendiri sudah ada di rilis terakhir.

Kami masih membutuhkan fungsi isnat atau mungkin mendukung datetime/timedelta dalam isnan .

Ya, setujui tentang fungsi isnat . Ada juga dua jenis di mana terkutuk: timedelta64 dan datetime64 . Perhatikan bahwa nilai NaT juga tidak terekspos di mana pun, kami mungkin juga dapat menggunakan np.nat . Definisi sebenarnya adalah ndarraytypes.h .

@charris , Chuck, apa pendapat Anda tentang itu, lebih baik buat np.isnat atau lebih tepatnya izinkan datetime dan timedelta di isnan ?

Hmm, memasukkan semuanya ke dalam isnan adalah pemikiran yang menarik tapi saya curiga mungkin akan menimbulkan masalah saat ini, mungkin nanti? @njuliant @juliantlor Thoughts?

@oyer mungkin punya pendapat juga.

Saya baru saja mengimplementasikan isnat , tapi saya tidak yakin tentang semua hal waktu sehubungan dengan rilis. Jika kita harus mencoba untuk memperbaikinya dalam versi minimal, pilihan yang lebih baik mungkin untuk memasukkan versi python isnat ke dalam setelan pengujian, meskipun memperbaikinya mungkin menjadi sedikit rumit dalam hal apapun ( setidaknya orang lain akan mendapatkan lebih banyak peringatan daripada sebelumnya, meskipun mungkin sedikit 1. menggunakan barang-barang setelan pengujian kami dan 2. benar-benar menguji peringatan dengan hati-hati).

Saya tidak menganggap kegagalan itu terlalu parah, tetapi alangkah baiknya jika diperbaiki. Versi python (pribadi?) Dari isnat akan baik-baik saja dengan saya untuk 1.12.

suppress_warnings docstring juga harus menyebutkan bahwa itu tidak aman untuk thread.

Itu memang :)

terima kasih banyak teman-teman karena telah membahas masalah ini selama liburan dan untuk debug yang menyeluruh

apakah ada yang bisa saya lakukan untuk menerapkan / menguji solusi untuk ini? debian sangat ingin memperbaikinya :)

@sandrotosi , sayangnya ini agak rumit mungkin, perbaikan paling sederhana mungkin dengan tidak menggunakan hal-hal pengujian paralel dalam skimage, tetapi itu agak mengalahkan tujuan. Kita cukup melakukan sesuatu seperti pada isnat saya (menggunakan versi python pribadi dari isnat). Namun, saya tidak begitu yakin bahwa ini mungkin tidak membuat regresi pengujian di tempat lain: /.

Menambahkan mutex untuk kedua kasus tersebut mungkin sebenarnya merupakan peretasan yang masuk akal yang seharusnya menghilangkan masalah dan tampaknya tidak akan menjadi buruk (karena Anda tidak akan memanggil assert_equal atau serupa dari dalam assert_equal ). Saya tidak akan benar-benar menggunakannya di numpy master, tetapi sebagai perbaikan bug minimal untuk 1.12 ini mungkin merupakan opsi nyata. Dan itu tidak akan mengganggu tes skimage itu sendiri.

@olebole akan menonaktifkan pengujian paralel di skimage menjadi solusi sementara yang dapat diterima?

@seberg ya saya pikir targetnya mungkin memiliki perbaikan minimal untuk 1,12 dan akhirnya mengatasinya dengan cara yang lebih lengkap / komprehensif di master - yang setidaknya akan membiarkan rilis debian berikutnya menjadi numpy tanpa masalah ini

@sandrotosi Saya mencoba pendekatan kunci di gh-8427. Saya bukan apakah pikiran itu gila atau tidak, tetapi jika seseorang ingin mencobanya ....

Adakah cara agar kita dapat memodifikasi suppress_warnings agar berperilaku tidak terdefinisi tetapi tidak macet saat digunakan dalam mode multi-thread?

(Saya punya beberapa ide, tapi saya masih memikirkan bagaimana tepatnya itu bisa berhasil.)

Tentu, kita tidak bisa menghapus atributnya, tapi itu mungkin membuat bug dalam pengujian nanti ... Meskipun saya kira sebagian besar setelan pengujian tidak serampangan tentang peringatan pengujian, jadi ....

Saya telah mengunggah 1.12.0rc2 (yang berisi https://github.com/numpy/numpy/pull/8427) ke debian dan membangun kembali skimage 3 kali (versi paket debian yang sedikit lama, tanpa rangkaian pengujian sepenuhnya dinonaktifkan) dan semua waktu berhasil dibangun.

terima kasih banyak teman-teman untuk mengerjakan ini selama liburan!

Sekarang, ada rencana untuk rilis final 1.12.0? :)

Saya berencana membuat rilis final pada 15 Januari.

Saya dapat mengonfirmasi bahwa ini berfungsi dengan rc2. Terima kasih banyak atas usaha Anda!

Saya membiarkan ini terbuka sampai diperbaiki di master.

Hmm, tidak diperbaiki di master. @seberg Apakah benar bahwa # 8421 akan menutup ini?

Diperbaiki oleh # 8421.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat