YBadiss: Very useful to us, and it fixes my issue #66 ! 👍 
lovasoa: Hello ! I like the idea of being able to handle custom serialization of collections. However, I don't really like the overhead the new parameter adds. Do you think we could use the existing `base_schema.TYPE_MAPPING` for this ?
lovasoa: Great ! Let's just rename `generic_type_mapping` to `type_mapping` (since it does not contain only generics), and we'll merge.
diff --git a/marshmallow_dataclass/__init__.py b/marshmallow_dataclass/__init__.py
index 9b223a5..d6f1554 100644
--- a/marshmallow_dataclass/__init__.py
+++ b/marshmallow_dataclass/__init__.py
@@ -351,6 +351,7 @@ def field_for_schema(
     """
 
     metadata = {} if metadata is None else dict(metadata)
+
     if default is not marshmallow.missing:
         metadata.setdefault("default", default)
         # 'missing' must not be set for required fields.
@@ -383,16 +384,22 @@ def field_for_schema(
     origin = typing_inspect.get_origin(typ)
     if origin:
         arguments = typing_inspect.get_args(typ, True)
+        # Override base_schema.TYPE_MAPPING to change the class used for generic types below
+        type_mapping = base_schema.TYPE_MAPPING if base_schema else {}
+
         if origin in (list, List):
             child_type = field_for_schema(arguments[0], base_schema=base_schema)
-            return marshmallow.fields.List(child_type, **metadata)
+            list_type = type_mapping.get(List, marshmallow.fields.List)
+            return list_type(child_type, **metadata)
         if origin in (tuple, Tuple):
             children = tuple(
                 field_for_schema(arg, base_schema=base_schema) for arg in arguments
             )
-            return marshmallow.fields.Tuple(children, **metadata)
+            tuple_type = type_mapping.get(Tuple, marshmallow.fields.Tuple)
+            return tuple_type(children, **metadata)
         elif origin in (dict, Dict):
-            return marshmallow.fields.Dict(
+            dict_type = type_mapping.get(Dict, marshmallow.fields.Dict)
+            return dict_type(
                 keys=field_for_schema(arguments[0], base_schema=base_schema),
                 values=field_for_schema(arguments[1], base_schema=base_schema),
                 **metadata,

Use NewType for derived List class
Hi there!

Coming from vanilla marshmallow, I had a `List` class that was deriving from `marshmallow.fields.List` and was adding some logic to how it was reading the input data on `_deserialize`.

Now, I am trying to integrate this with `marshmallow_dataclass` and hence create a new type. I have created a few other types that were not lists and it worked well, but I can't get it to work for lists. Here is what I have tried so far:

```python3
import typing

import marshmallow
from marshmallow_dataclass import dataclass, NewType


class MyList(marshmallow.fields.List):
    """A list field type that properly handles lists in MultiDict"""

    def _deserialize(self, value, attr, data, **kwargs):
        # removed the code, just checking if this is called
        raise Exception("Finally Called")


ListType = NewType("ListType", typing.List, field=MyList)


@dataclass 
class TestDataClass1:
    """
    This is the one I was expecting would work, as I thought that it would pass
    `int` to `MyList` which would come back to something similar to vanilla
    marshmallow i.e. `values = MyList(Int())`
    """
    values: ListType(int)

# fails with 'Not a valid integer.'
TestDataClass1.Schema().load({"values": [1,2,3]})

# Second try!
@dataclass 
class TestDataClass2: 
    values: ListType(typing.List[int])

# list is properly loaded, but that means MyList._deserialize was not called
TestDataClass2.Schema().load({"values": [1,2,3]})
```

I looked in the doc and example but could not find a reference for this use case, could you help me figure it out?

diff --git a/tests/test_field_for_schema.py b/tests/test_field_for_schema.py
index c597e87..699bd55 100644
--- a/tests/test_field_for_schema.py
+++ b/tests/test_field_for_schema.py
@@ -2,7 +2,7 @@ import inspect
 import typing
 import unittest
 from enum import Enum
-from typing import Dict, Optional, Union, Any
+from typing import Dict, Optional, Union, Any, List, Tuple
 
 from marshmallow import fields, Schema
 
@@ -117,6 +117,26 @@ class TestFieldForSchema(unittest.TestCase):
             fields.Nested(NewDataclass.Schema),
         )
 
+    def test_override_container_type_with_type_mapping(self):
+        type_mapping = [
+            (List, fields.List, List[int]),
+            (Dict, fields.Dict, Dict[str, int]),
+            (Tuple, fields.Tuple, Tuple[int, str, bytes]),
+        ]
+        for base_type, marshmallow_field, schema in type_mapping:
+
+            class MyType(marshmallow_field):
+                ...
+
+            self.assertIsInstance(field_for_schema(schema), marshmallow_field)
+
+            class BaseSchema(Schema):
+                TYPE_MAPPING = {base_type: MyType}
+
+            self.assertIsInstance(
+                field_for_schema(schema, base_schema=BaseSchema), MyType
+            )
+
 
 if __name__ == "__main__":
     unittest.main()

pip install -e .[dev]
parse_log_pytest
requirements.txt
3.7
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
aspy.yaml==1.3.0
Babel==2.14.0
certifi @ file:///croot/certifi_1671487769961/work/certifi
cfgv==3.3.1
charset-normalizer==3.4.1
decorator==5.1.1
distlib==0.3.9
docutils==0.19
exceptiongroup==1.2.2
filelock==3.12.2
identify==2.5.24
idna==3.10
imagesize==1.4.1
importlib-metadata==6.7.0
iniconfig==2.0.0
Jinja2==3.1.6
MarkupSafe==2.1.5
marshmallow==3.19.0
-e git+https://github.com/lovasoa/marshmallow_dataclass.git@c57a440198de020073c5291e872bdb08ce247292#egg=marshmallow_dataclass
marshmallow-enum==1.5.1
marshmallow-union==0.1.15.post1
mypy==1.4.1
mypy-extensions==1.0.0
nodeenv==1.9.1
packaging==24.0
platformdirs==4.0.0
pluggy==1.2.0
pre-commit==1.21.0
Pygments==2.17.2
pytest==7.4.4
pytest-mypy-plugins==2.0.0
pytz==2025.2
PyYAML==6.0.1
regex==2024.4.16
requests==2.31.0
six==1.17.0
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
toml==0.10.2
tomli==2.0.1
typed-ast==1.5.5
typing-inspect==0.9.0
typing_extensions==4.7.1
urllib3==2.0.7
virtualenv==20.26.6
zipp==3.15.0

name: marshmallow_dataclass
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
  - certifi=2022.12.7=py37h06a4308_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=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - aspy-yaml==1.3.0
      - babel==2.14.0
      - cfgv==3.3.1
      - charset-normalizer==3.4.1
      - decorator==5.1.1
      - distlib==0.3.9
      - docutils==0.19
      - exceptiongroup==1.2.2
      - filelock==3.12.2
      - identify==2.5.24
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - jinja2==3.1.6
      - markupsafe==2.1.5
      - marshmallow==3.19.0
      - marshmallow-dataclass==7.5.2
      - marshmallow-enum==1.5.1
      - marshmallow-union==0.1.15.post1
      - mypy==1.4.1
      - mypy-extensions==1.0.0
      - nodeenv==1.9.1
      - packaging==24.0
      - platformdirs==4.0.0
      - pluggy==1.2.0
      - pre-commit==1.21.0
      - pygments==2.17.2
      - pytest==7.4.4
      - pytest-mypy-plugins==2.0.0
      - pytz==2025.2
      - pyyaml==6.0.1
      - regex==2024.4.16
      - requests==2.31.0
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - toml==0.10.2
      - tomli==2.0.1
      - typed-ast==1.5.5
      - typing-extensions==4.7.1
      - typing-inspect==0.9.0
      - urllib3==2.0.7
      - virtualenv==20.26.6
      - zipp==3.15.0
prefix: /opt/conda/envs/marshmallow_dataclass

tests/test_field_for_schema.py::TestFieldForSchema::test_override_container_type_with_type_mapping
tests/test_field_for_schema.py::TestFieldForSchema::test_any tests/test_field_for_schema.py::TestFieldForSchema::test_builtin_dict tests/test_field_for_schema.py::TestFieldForSchema::test_builtin_list tests/test_field_for_schema.py::TestFieldForSchema::test_dict_from_typing tests/test_field_for_schema.py::TestFieldForSchema::test_enum tests/test_field_for_schema.py::TestFieldForSchema::test_explicit_field tests/test_field_for_schema.py::TestFieldForSchema::test_int tests/test_field_for_schema.py::TestFieldForSchema::test_marshmallow_dataclass tests/test_field_for_schema.py::TestFieldForSchema::test_newtype tests/test_field_for_schema.py::TestFieldForSchema::test_optional_str tests/test_field_for_schema.py::TestFieldForSchema::test_str tests/test_field_for_schema.py::TestFieldForSchema::test_union
marshmallow_dataclass/__init__.py
marshmallow_dataclass/__init__.py