diff --git a/barentsz/_discover.py b/barentsz/_discover.py
index c3e915e..4671539 100644
--- a/barentsz/_discover.py
+++ b/barentsz/_discover.py
@@ -25,6 +25,7 @@ from typish import (
 )
 
 from barentsz._attribute import Attribute
+from barentsz._typings import exclude_pred
 from barentsz._here import here
 
 
@@ -165,7 +166,7 @@ def discover_classes(
         include_privates: bool = False,
         in_private_modules: bool = False,
         raise_on_fail: bool = False,
-        exclude: Union[Iterable[type], type] = None
+        exclude: Union[type, exclude_pred, Iterable[Union[type, exclude_pred]]] = None
 ) -> List[type]:
     """
     Discover any classes within the given source and according to the given
@@ -178,8 +179,8 @@ def discover_classes(
         in_private_modules: if True, private modules are explored as well.
         raise_on_fail: if True, raises an ImportError upon the first import
         failure.
-        exclude: a type or multiple types that are to be excluded from the
-        result.
+        exclude: one or more types or predicates that are to be excluded
+        from the result.
 
     Returns: a list of all discovered classes (types).
 
@@ -190,6 +191,9 @@ def discover_classes(
     result = list({cls for cls in elements
                    if (signature is Any or subclass_of(cls, signature))
                    and cls not in exclude_})
+    exclude_predicates = [e for e in exclude_ if inspect.isfunction(e)]
+    for pred in exclude_predicates:
+        result = [cls for cls in result if not pred(cls)]
     result.sort(key=lambda cls: cls.__name__)
     return result
 
diff --git a/barentsz/_typings.py b/barentsz/_typings.py
new file mode 100644
index 0000000..454d94b
--- /dev/null
+++ b/barentsz/_typings.py
@@ -0,0 +1,3 @@
+from typing import Callable
+
+exclude_pred = Callable[[type], bool]

Feature request: filtering out abstract classes
While developing a certain machine learning game, I "discovered" ;) that it would be very useful to have the option to automatically filter out abstract classes when using `discover_classes`. I would imagine a parameter `exclude_abstract` with default value `False`.

I might just write a PR for this myself :)
diff --git a/tests/test_discover_classes.py b/tests/test_discover_classes.py
index c2fc32a..86bf9bc 100644
--- a/tests/test_discover_classes.py
+++ b/tests/test_discover_classes.py
@@ -80,7 +80,7 @@ class TestDiscoverClasses(TestCase):
         with self.assertRaises(ValueError):
             discover_classes(123)
 
-    def test_discover_classes_with_exclusions(self):
+    def test_discover_classes_with_type_exclusions(self):
         # SETUP
         path_to_resources = (Path(__file__).parent.parent / 'test_resources'
                              / 'examples_for_tests')
@@ -94,3 +94,19 @@ class TestDiscoverClasses(TestCase):
         self.assertIn(Class1_level2, classes1)
         self.assertEqual(1, len(classes2))
         self.assertIn(Class1_level2, classes2)
+
+    def test_discover_classes_with_predicate_exclusions(self):
+        # SETUP
+        path_to_resources = (Path(__file__).parent.parent / 'test_resources'
+                             / 'examples_for_tests')
+
+        def _name_is_class1(cls: type) -> bool:
+            return cls.__name__.lower() == 'class1'
+
+        # EXECUTE
+        classes1 = discover_classes(path_to_resources, exclude=_name_is_class1)
+        classes2 = discover_classes(path_to_resources, exclude=[_name_is_class1])
+
+        # VERIFY
+        self.assertEqual(0, len(classes1))
+        self.assertEqual(0, len(classes2))

pip install -e .[test]
parse_log_pytest
pytest
pytest
3.9
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
astroid==3.3.9
autoflake==2.3.1
-e git+https://github.com/ramonhagenaars/barentsz.git@5591825299b4a1c2176f5af28feec89b5e21ad64#egg=barentsz
certifi==2025.1.31
charset-normalizer==3.4.1
colorama==0.4.6
coverage==7.8.0
dill==0.3.9
exceptiongroup @ file:///croot/exceptiongroup_1706031385326/work
idna==3.10
iniconfig @ file:///home/linux1/recipes/ci/iniconfig_1610983019677/work
isort==6.0.1
mando==0.7.1
mccabe==0.7.0
mypy==1.15.0
mypy-extensions==1.0.0
packaging @ file:///croot/packaging_1734472117206/work
platformdirs==4.3.7
pluggy @ file:///croot/pluggy_1733169602837/work
pycodestyle==2.13.0
pyflakes==3.3.1
pylint==3.3.6
pytest @ file:///croot/pytest_1738938843180/work
pytest-cov==6.0.0
PyYAML==6.0.2
radon==6.0.1
requests==2.32.3
SCons==4.9.1
six==1.17.0
tomli @ file:///opt/conda/conda-bld/tomli_1657175507142/work
tomlkit==0.13.2
typing_extensions==4.13.0
typish==1.9.3
urllib3==2.3.0
xenon==0.9.3

name: barentsz
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - exceptiongroup=1.2.0=py39h06a4308_0
  - iniconfig=1.1.1=pyhd3eb1b0_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - packaging=24.2=py39h06a4308_0
  - pip=25.0=py39h06a4308_0
  - pluggy=1.5.0=py39h06a4308_0
  - pytest=8.3.4=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tomli=2.0.1=py39h06a4308_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - astroid==3.3.9
      - autoflake==2.3.1
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - colorama==0.4.6
      - coverage==7.8.0
      - dill==0.3.9
      - idna==3.10
      - isort==6.0.1
      - mando==0.7.1
      - mccabe==0.7.0
      - mypy==1.15.0
      - mypy-extensions==1.0.0
      - platformdirs==4.3.7
      - pycodestyle==2.13.0
      - pyflakes==3.3.1
      - pylint==3.3.6
      - pytest-cov==6.0.0
      - pyyaml==6.0.2
      - radon==6.0.1
      - requests==2.32.3
      - scons==4.9.1
      - six==1.17.0
      - tomlkit==0.13.2
      - typing-extensions==4.13.0
      - typish==1.9.3
      - urllib3==2.3.0
      - xenon==0.9.3
prefix: /opt/conda/envs/barentsz

tests/test_discover_classes.py::TestDiscoverClasses::test_discover_classes_with_predicate_exclusions
tests/test_discover_classes.py::TestDiscoverClasses::test_discover_classes_in_module tests/test_discover_classes.py::TestDiscoverClasses::test_discover_classes_in_path tests/test_discover_classes.py::TestDiscoverClasses::test_discover_classes_in_private_modules tests/test_discover_classes.py::TestDiscoverClasses::test_discover_classes_with_signature tests/test_discover_classes.py::TestDiscoverClasses::test_discover_classes_with_type_exclusions tests/test_discover_classes.py::TestDiscoverClasses::test_discover_classes_with_wrong_argument tests/test_discover_classes.py::TestDiscoverClasses::test_discover_private_classes
barentsz/_typings.py barentsz/_discover.py
barentsz/_typings.py barentsz/_discover.py