# Buggy code
def validator(
    *fields,
    pre: bool = False,
    whole: bool = False,
    always: bool = False,
    check_fields: bool = True,
):
    """
    Decorate methods on the class indicating that they should be used to validate fields
    :param fields: which field(s) the method should be called on
    :param pre: whether or not this validator should be called before the standard validators (else after)
    :param whole: for complex objects (sets, lists etc.) whether to validate individual elements or the whole object
    :param always: whether this method and other validators should be called even if the value is missing
    :param check_fields: whether to check that the fields actually exist on the model
    """
    if not fields:
        raise ConfigError("validator with no fields specified")
    elif isinstance(fields[0], FunctionType):
        raise ConfigError(
            "validators should be used with fields and keyword arguments, not bare. "
            "E.g. usage should be `@validator('<field_name>', ...)`"
        )

    def dec(f):
        ref = f.__module__ + "." + f.__qualname__
        if ref in _FUNCS:
            raise ConfigError(f'duplicate validator function "{ref}"')
        _FUNCS.add(ref)
        f_cls = classmethod(f)
        f_cls.__validator_config = (
            fields,
            Validator(f, pre, whole, always, check_fields),
        )
        return f_cls

    return dec


# Traceback (ConfigError)
Config ip=IPv4Address('123.0.0.200') name='asdf' port=2392
when the cell is called first and raises

ConfigError Traceback (most recent call last)
in ()
3 from ipaddress import ip_address
4
----> 5 class Config(BaseModel):
6 ip: str
7 name: str

in Config()
8 port: int
9
---> 10 @validator("ip")
11 def check_ip(cls, value):
12 return ip_address(value)

~/anaconda3/lib/python3.7/site-packages/pydantic/main.py in dec(f)
449 ref = f.module + '.' + f.qualname
450 if ref in _FUNCS:
--> 451 raise ConfigError(f'duplicate validator function "{ref}"')
452 _FUNCS.add(ref)
453 f_cls = classmethod(f)

ConfigError: duplicate validator function "main.Config.check_ip"

# Fixed code
def validator(
    *fields,
    pre: bool = False,
    whole: bool = False,
    always: bool = False,
    check_fields: bool = True,
):
    """
    Decorate methods on the class indicating that they should be used to validate fields
    :param fields: which field(s) the method should be called on
    :param pre: whether or not this validator should be called before the standard validators (else after)
    :param whole: for complex objects (sets, lists etc.) whether to validate individual elements or the whole object
    :param always: whether this method and other validators should be called even if the value is missing
    :param check_fields: whether to check that the fields actually exist on the model
    """
    if not fields:
        raise ConfigError("validator with no fields specified")
    elif isinstance(fields[0], FunctionType):
        raise ConfigError(
            "validators should be used with fields and keyword arguments, not bare. "
            "E.g. usage should be `@validator('<field_name>', ...)`"
        )

    def dec(f):
        # avoid validators with duplicated names since without this validators can be overwritten silently
        # which generally isn't the intended behaviour, don't run in ipython - see #312
        if not in_ipython():  # pragma: no branch
            ref = f.__module__ + "." + f.__qualname__
            if ref in _FUNCS:
                raise ConfigError(f'duplicate validator function "{ref}"')
            _FUNCS.add(ref)
        f_cls = classmethod(f)
        f_cls.__validator_config = (
            fields,
            Validator(f, pre, whole, always, check_fields),
        )
        return f_cls

    return dec