Repository: pydantic/pydantic

Issue:
Allow extra keyword arguments in MetaModel.__new__
# Bug
`pydantic.main.ModelMetaclass.__new__` should include `**kwargs` at the end of the method definition and pass them on to the `super` call at the end in order to allow the special method [`__init_subclass__`](https://docs.python.org/3/reference/datamodel.html#object.__init_subclass__) to be defined with custom parameters on extended `BaseModel` classes. 

Environment:
* OS: Ubuntu 1804
* Python version `import sys; print(sys.version)`: `3.7.3 (default, Apr  3 2019, 19:16:38) \n[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]`
* Pydantic version `import pydantic; print(pydantic.VERSION)`: 0.31

For example:
```py
import pydantic
class CustomBaseModel(pydantic.BaseModel):
    def __init_subclass__(cls, special_parameter):
        # do something with special_parameter
        ...

class NewModel(CustomBaseModel, special_parameter=42):
    # model definition here
    ...
```
should not raise any exceptions. But:
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    class NewModel(CustomBaseModel, special_parameter=42):
  File "pydantic/main.py", line 178, in pydantic.main.ModelMetaclass.__new__
TypeError: __new__() got an unexpected keyword argument 'special_parameter'
```
I can (and will) submit a PR for this if you accept it; it is an extremely simple fix (plus not-so-simple tests because metaclasses).
Allow extra keyword arguments in MetaModel.__new__
# Bug
`pydantic.main.ModelMetaclass.__new__` should include `**kwargs` at the end of the method definition and pass them on to the `super` call at the end in order to allow the special method [`__init_subclass__`](https://docs.python.org/3/reference/datamodel.html#object.__init_subclass__) to be defined with custom parameters on extended `BaseModel` classes. 

Environment:
* OS: Ubuntu 1804
* Python version `import sys; print(sys.version)`: `3.7.3 (default, Apr  3 2019, 19:16:38) \n[GCC 8.0.1 20180414 (experimental) [trunk revision 259383]]`
* Pydantic version `import pydantic; print(pydantic.VERSION)`: 0.31

For example:
```py
import pydantic
class CustomBaseModel(pydantic.BaseModel):
    def __init_subclass__(cls, special_parameter):
        # do something with special_parameter
        ...

class NewModel(CustomBaseModel, special_parameter=42):
    # model definition here
    ...
```
should not raise any exceptions. But:
```
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
    class NewModel(CustomBaseModel, special_parameter=42):
  File "pydantic/main.py", line 178, in pydantic.main.ModelMetaclass.__new__
TypeError: __new__() got an unexpected keyword argument 'special_parameter'
```
I can (and will) submit a PR for this if you accept it; it is an extremely simple fix (plus not-so-simple tests because metaclasses).


Discussion:

Resolving patch:
diff --git a/pydantic/main.py b/pydantic/main.py
--- a/pydantic/main.py
+++ b/pydantic/main.py
@@ -130,7 +130,7 @@ def validate_custom_root_type(fields: Dict[str, ModelField]) -> None:
 
 class ModelMetaclass(ABCMeta):
     @no_type_check  # noqa C901
-    def __new__(mcs, name, bases, namespace):
+    def __new__(mcs, name, bases, namespace, **kwargs):
         fields: Dict[str, ModelField] = {}
         config = BaseConfig
         validators: 'ValidatorListDict' = {}
@@ -220,7 +220,7 @@ def __new__(mcs, name, bases, namespace):
             '__custom_root_type__': _custom_root_type,
             **{n: v for n, v in namespace.items() if n not in fields},
         }
-        return super().__new__(mcs, name, bases, new_namespace)
+        return super().__new__(mcs, name, bases, new_namespace, **kwargs)
 
 
 class BaseModel(metaclass=ModelMetaclass):


Test patch:
diff --git a/tests/test_main.py b/tests/test_main.py
--- a/tests/test_main.py
+++ b/tests/test_main.py
@@ -1001,3 +1001,19 @@ class Bar(BaseModel):
     assert m.dict() == {'c': 3, 'd': {'a': 1, 'b': 2}}
     assert list(m) == [('c', 3), ('d', Foo())]
     assert dict(m) == {'c': 3, 'd': Foo()}
+
+
+def test_custom_init_subclass_params():
+    class DerivedModel(BaseModel):
+        def __init_subclass__(cls, something):
+            cls.something = something
+
+    # if this raises a TypeError, then there is a regression of issue 867:
+    # pydantic.main.MetaModel.__new__ should include **kwargs at the end of the
+    # method definition and pass them on to the super call at the end in order
+    # to allow the special method __init_subclass__ to be defined with custom
+    # parameters on extended BaseModel classes.
+    class NewModel(DerivedModel, something=2):
+        something = 1
+
+    assert NewModel.something == 2