Best Python code snippet using pandera_python
decorators.py
Source:decorators.py
...30Schemas = Union[schemas.DataFrameSchema, schemas.SeriesSchema]31InputGetter = Union[str, int]32OutputGetter = Union[str, int, Callable]33F = TypeVar("F", bound=Callable)34def _get_fn_argnames(fn: Callable) -> List[str]:35 """Get argument names of a function.36 :param fn: get argument names for this function.37 :returns: list of argument names to be matched with the positional38 args passed in the decorator.39 .. note::40 Excludes first positional "self" or "cls" arguments if needed:41 - exclude self:42 - if fn is a method (self being an implicit argument)43 - exclude cls:44 - if fn is a decorated classmethod in Python 3.9+45 - if fn is declared as a regular method on a metaclass46 For functions decorated with ``@classmethod``, cls is excluded only in Python 3.9+47 because that is when Python's handling of classmethods changed and wrapt mirrors it.48 See: https://github.com/GrahamDumpleton/wrapt/issues/18249 """50 arg_spec_args = inspect.getfullargspec(fn).args51 first_arg_is_self = arg_spec_args[0] == "self"52 is_py_newer_than_39 = sys.version_info[:2] >= (3, 9)53 # Exclusion criteria54 is_regular_method = inspect.ismethod(fn) and first_arg_is_self55 is_decorated_cls_method = (56 is_decorated_classmethod(fn) and is_py_newer_than_3957 )58 is_cls_method_from_meta_method = is_classmethod_from_meta(fn)59 if (60 is_regular_method61 or is_decorated_cls_method62 or is_cls_method_from_meta_method63 ):64 # Don't include "self" / "cls" argument65 arg_spec_args = arg_spec_args[1:]66 return arg_spec_args67def _handle_schema_error(68 decorator_name,69 fn: Callable,70 schema: Union[schemas.DataFrameSchema, schemas.SeriesSchema],71 arg_df: pd.DataFrame,72 schema_error: errors.SchemaError,73) -> NoReturn:74 """Reraise schema validation error with decorator context.75 :param fn: check the DataFrame or Series input of this function.76 :param schema: dataframe/series schema object77 :param arg_df: dataframe/series we are validating.78 :param schema_error: original exception.79 :raises SchemaError: when ``DataFrame`` violates built-in or custom80 checks.81 """82 msg = f"error in {decorator_name} decorator of function '{fn.__name__}': {schema_error}"83 raise errors.SchemaError(84 schema,85 arg_df,86 msg,87 failure_cases=schema_error.failure_cases,88 check=schema_error.check,89 check_index=schema_error.check_index,90 ) from schema_error91def check_input(92 schema: Schemas,93 obj_getter: Optional[InputGetter] = None,94 head: Optional[int] = None,95 tail: Optional[int] = None,96 sample: Optional[int] = None,97 random_state: Optional[int] = None,98 lazy: bool = False,99 inplace: bool = False,100) -> Callable[[F], F]:101 # pylint: disable=duplicate-code102 """Validate function argument when function is called.103 This is a decorator function that validates the schema of a dataframe104 argument in a function.105 :param schema: dataframe/series schema object106 :param obj_getter: (Default value = None) if int, obj_getter refers to the107 the index of the pandas dataframe/series to be validated in the args108 part of the function signature. If str, obj_getter refers to the109 argument name of the pandas dataframe/series in the function signature.110 This works even if the series/dataframe is passed in as a positional111 argument when the function is called. If None, assumes that the112 dataframe/series is the first argument of the decorated function113 :param head: validate the first n rows. Rows overlapping with `tail` or114 `sample` are de-duplicated.115 :param tail: validate the last n rows. Rows overlapping with `head` or116 `sample` are de-duplicated.117 :param sample: validate a random sample of n rows. Rows overlapping118 with `head` or `tail` are de-duplicated.119 :param random_state: random seed for the ``sample`` argument.120 :param lazy: if True, lazily evaluates dataframe against all validation121 checks and raises a ``SchemaErrors``. Otherwise, raise122 ``SchemaError`` as soon as one occurs.123 :param inplace: if True, applies coercion to the object of validation,124 otherwise creates a copy of the data.125 :returns: wrapped function126 :example:127 Check the input of a decorated function.128 >>> import pandas as pd129 >>> import pandera as pa130 >>>131 >>>132 >>> schema = pa.DataFrameSchema({"column": pa.Column(int)})133 >>>134 >>> @pa.check_input(schema)135 ... def transform_data(df: pd.DataFrame) -> pd.DataFrame:136 ... df["doubled_column"] = df["column"] * 2137 ... return df138 >>>139 >>> df = pd.DataFrame({140 ... "column": range(5),141 ... })142 >>>143 >>> transform_data(df)144 column doubled_column145 0 0 0146 1 1 2147 2 2 4148 3 3 6149 4 4 8150 See :ref:`here<decorators>` for more usage details.151 """152 @wrapt.decorator153 def _wrapper(154 fn: Callable,155 instance: Union[None, Any],156 args: Tuple[Any, ...],157 kwargs: Dict[str, Any],158 ):159 # pylint: disable=unused-argument160 """Check pandas DataFrame or Series before calling the function.161 :param fn: check the DataFrame or Series input of this function162 :param instance: the object to which the wrapped function was bound163 when it was called. Only applies to methods.164 :param args: the list of positional arguments supplied when the165 decorated function was called.166 :param kwargs: the dictionary of keyword arguments supplied when the167 decorated function was called.168 """169 args = list(args)170 validate_args = (head, tail, sample, random_state, lazy, inplace)171 if isinstance(obj_getter, int):172 try:173 args[obj_getter] = schema.validate(args[obj_getter])174 except IndexError as exc:175 raise IndexError(176 f"error in check_input decorator of function '{fn.__name__}': the "177 f"index '{obj_getter}' was supplied to the check but this "178 f"function accepts '{len(_get_fn_argnames(fn))}' arguments, so the maximum "179 f"index is 'max(0, len(_get_fn_argnames(fn)) - 1)'. The full error is: '{exc}'"180 ) from exc181 elif isinstance(obj_getter, str):182 if obj_getter in kwargs:183 kwargs[obj_getter] = schema.validate(184 kwargs[obj_getter], *validate_args185 )186 else:187 arg_spec_args = _get_fn_argnames(fn)188 args_dict = OrderedDict(zip(arg_spec_args, args))189 args_dict[obj_getter] = schema.validate(190 args_dict[obj_getter], *validate_args191 )192 args = list(args_dict.values())193 elif obj_getter is None and args:194 try:195 args[0] = schema.validate(args[0], *validate_args)196 except errors.SchemaError as e:197 _handle_schema_error("check_input", fn, schema, args[0], e)198 elif obj_getter is None and kwargs:199 # get the first key in the same order specified in the200 # function argument.201 args_names = _get_fn_argnames(fn)202 try:203 kwargs[args_names[0]] = schema.validate(204 kwargs[args_names[0]], *validate_args205 )206 except errors.SchemaError as e:207 _handle_schema_error(208 "check_input", fn, schema, kwargs[args_names[0]], e209 )210 else:211 raise TypeError(212 f"obj_getter is unrecognized type: {type(obj_getter)}"213 )214 return fn(*args, **kwargs)215 return _wrapper...
Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!