diff --git a/pydantic/main.py b/pydantic/main.py
--- a/pydantic/main.py
+++ b/pydantic/main.py
@@ -358,7 +358,12 @@ def parse_obj(cls: Type['Model'], obj: Any) -> 'Model':
                 except (TypeError, ValueError) as e:
                     exc = TypeError(f'{cls.__name__} expected dict not {type(obj).__name__}')
                     raise ValidationError([ErrorWrapper(exc, loc='__obj__')]) from e
-        return cls(**obj)
+
+        m = cls.__new__(cls)
+        values, fields_set, _ = validate_model(m, obj)
+        object.__setattr__(m, '__values__', values)
+        object.__setattr__(m, '__fields_set__', fields_set)
+        return m
 
     @classmethod
     def parse_raw(
@@ -472,14 +477,14 @@ def __get_validators__(cls) -> 'CallableGenerator':
     @classmethod
     def validate(cls: Type['Model'], value: Any) -> 'Model':
         if isinstance(value, dict):
-            return cls(**value)
+            return cls.parse_obj(value)
         elif isinstance(value, cls):
             return value.copy()
         elif cls.__config__.orm_mode:
             return cls.from_orm(value)
         else:
             with change_exception(DictError, TypeError, ValueError):
-                return cls(**dict(value))
+                return cls.parse_obj(value)
 
     @classmethod
     def _decompose_class(cls: Type['Model'], obj: Any) -> GetterDict:

Try `m = Model(self_=“some URL”)` with the rest of the code as is (from the with-alias example).
@dmontagu the problem is deserialization. 
I get a json body in a request with {"self": "someurl"} in it and I can't create a model instance without preparsing the body to replace "self" with "self_"

If pydantic had a way to "preload" like marshmallow does it might help?
Would #624 help? 
@samuelcolvin would having a load alias give you a different function to call that didn’t already have `self` as a parameter? I don’t see that discussed in the linked issue.

Given how frequently the specific field name `self` seems to be desired (I think it has meaning in certain json schema specs), might it make sense to rename `self` to `__self__` or something else equally unlikely to cause conflicts in `BaseModel.__init__` (and perhaps other methods expecting field names as kwargs)? Unless the approach of calling `Model(**data)` to initialize a model becomes discouraged, it feels unfortunate to me to have to change the model initialization code just to support a reasonably-named field (reasonable in a JSON context, rather than a python context anyway).
@samuelcolvin not sure whether splitting out load and dump aliases changes the fact.

Seems to me being able to avoid `Model(**data)` to initialize a model avoids all sorts of possible issues with name clashes. Moving this to a 'marshmallow' style `load(...)` has other advantages for pre-formatting data etc. but I don't really want to suggest any specific approach here not knowing the history and roadmap of the project well enough, rather just if there is a way to handle this.

Regardless, as @dmontagu points out, 'self' and even 'kwargs' should be possible to specify in a schema.
diff --git a/tests/test_edge_cases.py b/tests/test_edge_cases.py
--- a/tests/test_edge_cases.py
+++ b/tests/test_edge_cases.py
@@ -880,3 +880,29 @@ class Spam(BaseModel):
     assert Spam(c=Foo(a='123')).dict() == {'c': {'a': 123}}
     with pytest.raises(ValidationError):
         Spam(c=Bar(b='123'))
+
+
+def test_self():
+    class Model(BaseModel):
+        self: str
+
+    m = Model.parse_obj(dict(self='some value'))
+    assert m.dict() == {'self': 'some value'}
+    assert m.self == 'some value'
+    assert m.schema() == {
+        'title': 'Model',
+        'type': 'object',
+        'properties': {'self': {'title': 'Self', 'type': 'string'}},
+        'required': ['self'],
+    }
+
+
+def test_self_recursive():
+    class SubModel(BaseModel):
+        self: int
+
+    class Model(BaseModel):
+        sm: SubModel
+
+    m = Model.parse_obj({'sm': {'self': '123'}})
+    assert m.dict() == {'sm': {'self': 123}}

How to use a field called "self"
# Question
Is it possible to have a field on a model called "self"?
(Background to the question is JSON-API has links called "self", "related" etc.)

* Python version 3.7.3
* Pydantic version 0.29

```py
from pydantic import BaseModel

class Model(BaseModel):
    self: str

m = Model(self="some URL")
# TypeError: __init__() got multiple values for argument 'self'
```

I tried calling the field "self_" using an alias called "self"

```py
from pydantic import BaseModel, Schema

class Model(BaseModel):
    self_: str = Schema(alias="self")

m = Model(self="some URL")
# TypeError: __init__() got multiple values for argument 'self'
```

tests/test_edge_cases.py::test_self tests/test_edge_cases.py::test_self_recursive
tests/test_edge_cases.py::test_str_bytes tests/test_edge_cases.py::test_str_bytes_none tests/test_edge_cases.py::test_union_int_str tests/test_edge_cases.py::test_union_priority tests/test_edge_cases.py::test_typed_list tests/test_edge_cases.py::test_typed_set tests/test_edge_cases.py::test_dict_dict tests/test_edge_cases.py::test_typed_dict[value0-result0] tests/test_edge_cases.py::test_typed_dict[value1-result1] tests/test_edge_cases.py::test_typed_dict[value2-result2] tests/test_edge_cases.py::test_typed_dict_error[1-errors0] tests/test_edge_cases.py::test_typed_dict_error[value1-errors1] tests/test_edge_cases.py::test_typed_dict_error[value2-errors2] tests/test_edge_cases.py::test_dict_key_error tests/test_edge_cases.py::test_tuple tests/test_edge_cases.py::test_tuple_more tests/test_edge_cases.py::test_tuple_length_error tests/test_edge_cases.py::test_tuple_invalid tests/test_edge_cases.py::test_tuple_value_error tests/test_edge_cases.py::test_recursive_list tests/test_edge_cases.py::test_recursive_list_error tests/test_edge_cases.py::test_list_unions tests/test_edge_cases.py::test_recursive_lists tests/test_edge_cases.py::test_str_enum tests/test_edge_cases.py::test_any_dict tests/test_edge_cases.py::test_infer_alias tests/test_edge_cases.py::test_alias_error tests/test_edge_cases.py::test_annotation_config tests/test_edge_cases.py::test_success_values_include tests/test_edge_cases.py::test_include_exclude_default tests/test_edge_cases.py::test_field_set_ignore_extra tests/test_edge_cases.py::test_field_set_allow_extra tests/test_edge_cases.py::test_field_set_field_name tests/test_edge_cases.py::test_values_order tests/test_edge_cases.py::test_inheritance tests/test_edge_cases.py::test_invalid_type tests/test_edge_cases.py::test_valid_string_types[a tests/test_edge_cases.py::test_valid_string_types[some tests/test_edge_cases.py::test_valid_string_types[value2-foobar] tests/test_edge_cases.py::test_valid_string_types[123-123] tests/test_edge_cases.py::test_valid_string_types[123.45-123.45] tests/test_edge_cases.py::test_valid_string_types[value5-12.45] tests/test_edge_cases.py::test_valid_string_types[True-True] tests/test_edge_cases.py::test_valid_string_types[False-False] tests/test_edge_cases.py::test_valid_string_types[a10-a10] tests/test_edge_cases.py::test_valid_string_types[whatever-whatever] tests/test_edge_cases.py::test_invalid_string_types[value0-errors0] tests/test_edge_cases.py::test_invalid_string_types[value1-errors1] tests/test_edge_cases.py::test_inheritance_config tests/test_edge_cases.py::test_partial_inheritance_config tests/test_edge_cases.py::test_string_none tests/test_edge_cases.py::test_alias_camel_case tests/test_edge_cases.py::test_get_field_schema_inherit tests/test_edge_cases.py::test_return_errors_ok tests/test_edge_cases.py::test_return_errors_error tests/test_edge_cases.py::test_optional_required tests/test_edge_cases.py::test_invalid_validator tests/test_edge_cases.py::test_unable_to_infer tests/test_edge_cases.py::test_get_validator tests/test_edge_cases.py::test_multiple_errors tests/test_edge_cases.py::test_pop_by_alias tests/test_edge_cases.py::test_validate_all tests/test_edge_cases.py::test_ignore_extra_true tests/test_edge_cases.py::test_ignore_extra_false tests/test_edge_cases.py::test_allow_extra tests/test_edge_cases.py::test_ignore_extra_allow_extra tests/test_edge_cases.py::test_force_extra tests/test_edge_cases.py::test_illegal_extra_value tests/test_edge_cases.py::test_multiple_inheritance_config tests/test_edge_cases.py::test_multiple_inheritance_config_legacy_extra tests/test_edge_cases.py::test_submodel_different_type