From: Michael R. Crusoe <crusoe@debian.org>
Subject: Use pytest instead of the Py3.11 incompatible nose
Forwarded: https://github.com/daler/gffutils/pull/200

"Nose" is no longer developed for many years now.
--- python-gffutils.orig/gffutils/test/parser_test.py
+++ python-gffutils/gffutils/test/parser_test.py
@@ -1,10 +1,11 @@
 import tempfile
-from nose.tools import assert_raises
 from gffutils import parser, create, feature, iterators, constants, helpers, exceptions
 from gffutils import example_filename, create_db
 from . import attr_test_cases
 from textwrap import dedent
 
+import pytest
+
 TEST_FILENAMES = [
     example_filename(i)
     for i in [
@@ -88,10 +89,10 @@
     reconstructing attributes with incomplete information returns empty string
     """
     assert parser._reconstruct(None, constants.dialect) == ""
-    assert_raises(
-        exceptions.AttributeStringError, parser._reconstruct, dict(ID="asdf"), None
-    )
-    assert_raises(exceptions.AttributeStringError, parser._reconstruct, None, None)
+    with pytest.raises(exceptions.AttributeStringError):
+        parser._reconstruct(dict(ID="asdf"), None)
+    with pytest.raises(exceptions.AttributeStringError):
+        parser._reconstruct(None, None)
 
 
 def test_empty_split_keyvals():
--- python-gffutils.orig/gffutils/test/test_issues.py
+++ python-gffutils/gffutils/test/test_issues.py
@@ -10,8 +10,8 @@
 import gffutils
 from gffutils import feature
 from gffutils import merge_criteria as mc
-from nose.tools import assert_raises
 
+import pytest
 
 def test_issue_79():
     gtf = gffutils.example_filename("keep-order-test.gtf")
@@ -324,9 +324,12 @@
     #   TypeError: merge() got an unexpected keyword argument 'ignore_strand'
     #
     # Now changing to ValueError and suggesting a fix. 
-    assert_raises(ValueError, db.children_bp, gene, child_featuretype='exon', merge=True, ignore_strand=True)
-    assert_raises(ValueError, db.children_bp, gene, ignore_strand=True, nonexistent=True)
-    assert_raises(TypeError, db.children_bp, gene, nonexistent=True)
+    with pytest.raises(ValueError):
+        db.children_bp(gene, child_featuretype='exon', merge=True, ignore_strand=True)
+    with pytest.raises(ValueError):
+        db.children_bp(gene, ignore_strand=True, nonexistent=True)
+    with pytest.raises(TypeError):
+        db.children_bp(gene, nonexistent=True)
 
     # The way to do it now is the following (we can omit the mc.feature_type
     # since we're preselecting for exons anyway):
@@ -393,7 +396,8 @@
     introns = db.create_introns()
 
     # This now warns that the provided ID key has multiple values.
-    assert_raises(ValueError, db.update, introns)
+    with pytest.raises(ValueError):
+        db.update(introns)
 
     # The fix is to provide a custom intron ID converter.
     def intron_id(f):
--- python-gffutils.orig/gffutils/test/test.py
+++ python-gffutils/gffutils/test/test.py
@@ -1,7 +1,7 @@
 import warnings
 from textwrap import dedent
 from . import expected
-from gffutils import example_filename, create, parser, feature
+from gffutils import example_filename, create, feature
 import gffutils
 import gffutils.helpers as helpers
 import gffutils.gffwriter as gffwriter
@@ -13,8 +13,6 @@
 import shutil
 import threading
 import tempfile
-from textwrap import dedent
-from nose.tools import assert_raises
 from six.moves import SimpleHTTPServer
 
 if sys.version_info.major == 3:
@@ -24,11 +22,10 @@
 
 import multiprocessing
 import json
-import tempfile
-import shutil
-import glob
 import difflib
 
+import pytest
+
 testdbfn_gtf = ":memory:"
 testdbfn_gff = ":memory:"
 
@@ -631,17 +628,16 @@
     x = db["fake"]
     y = db["fake_1"]
 
-    assert_raises(
-        ValueError,
-        gffutils.create_db,
-        gtfdata,
-        ":memory:",
-        from_string=True,
-        merge_strategy="merge",
-        id_spec="gene_id",
-        force_merge_fields=["start"],
-        keep_order=True,
-    )
+    with pytest.raises(ValueError):
+        gffutils.create_db(
+            gtfdata,
+            ":memory:",
+            from_string=True,
+            merge_strategy="merge",
+            id_spec="gene_id",
+            force_merge_fields=["start"],
+            keep_order=True,
+            )
 
     # test that warnings are raised because of strand and frame
     with warnings.catch_warnings(record=True) as w:
@@ -750,7 +746,8 @@
     fn = tempfile.NamedTemporaryFile(delete=False).name
     a = open(fn, "w")
     a.close()
-    assert_raises(gffutils.exceptions.EmptyInputError, gffutils.create_db, fn, fn + ".db")
+    with pytest.raises(gffutils.exceptions.EmptyInputError):
+        gffutils.create_db(fn, fn + ".db")
 
 
 def test_false_function():
@@ -1107,23 +1104,21 @@
     return
 
     # TODO: when infer_gene_extent actually gets deprecated, test here.
-    assert_raises(
-        ValueError,
-        gffutils.create_db,
-        gffutils.example_filename("FBgn0031208.gtf"),
-        ":memory:",
-        infer_gene_extent=False,
-    )
+    with pytest.raises(ValueError):
+        gffutils.create_db(
+            gffutils.example_filename("FBgn0031208.gtf"),
+            ":memory:",
+            infer_gene_extent=False,
+            )
 
 
 def test_nonsense_kwarg():
-    assert_raises(
-        TypeError,
-        gffutils.create_db,
-        gffutils.example_filename("FBgn0031208.gtf"),
-        ":memory:",
-        asdf=True,
-    )
+    with pytest.raises(TypeError):
+        gffutils.create_db(
+            gffutils.example_filename("FBgn0031208.gtf"),
+            ":memory:",
+            asdf=True,
+            )
 
 
 def test_infer_gene_extent():
--- /dev/null
+++ python-gffutils/gffutils/test/conftest.py
@@ -0,0 +1 @@
+collect_ignore=["data"]
--- python-gffutils.orig/gffutils/test/performance_evaluation.py
+++ python-gffutils/gffutils/test/performance_evaluation.py
@@ -1,8 +1,8 @@
 """
-Performance testing. Run them with https://github.com/mahmoudimus/nose-timer:
+Performance testing. Run them with https://pypi.org/project/pytest-timer/:
 
 ```
-nosetests --nocapture -a slow --with-timer
+pytest --capture=no -m slow --with-timer
 ```
 
 WARNING: These tests can take about 1.5 hours to run!
@@ -15,7 +15,7 @@
 import unittest
 import os
 
-from nose.plugins import attrib
+import pytest
 
 import gffutils
 
@@ -187,7 +187,7 @@
         )
 
 
-@attrib.attr("slow")
+@pytest.mark.slow
 class TestPerformanceOnSacCer(PerformanceTestFeatureDB, unittest.TestCase):
     """
     Test frequent scenarios on medium size genome of yeast.
@@ -205,7 +205,7 @@
     )
 
 
-@attrib.attr("slow")
+@pytest.mark.slow
 class TestPerformanceOnMouse(PerformanceTestFeatureDB, unittest.TestCase):
     """
     Test frequent scenarios on large genome of mouse.
