Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def test_generate_stub(store, db_file, stdout, stderr):
traces = [
CallTrace(func, {'a': int, 'b': str}, NoneType),
CallTrace(func2, {'a': int, 'b': int}, NoneType),
]
store.add(traces)
ret = cli.main(['stub', func.__module__], stdout, stderr)
expected = """def func(a: int, b: str) -> None: ...
def func2(a: int, b: int) -> None: ...
"""
assert stdout.getvalue() == expected
assert stderr.getvalue() == ''
assert ret == 0
def test_verbose_failed_traces(store, db_file, stdout, stderr):
traces = [
CallTrace(func, {'a': int, 'b': str}, NoneType),
CallTrace(func2, {'a': int, 'b': int}, NoneType),
]
store.add(traces)
with mock.patch("monkeytype.encoding.CallTraceRow.to_trace", side_effect=MonkeyTypeError("the-trace")):
ret = cli.main(['-v', 'stub', func.__module__], stdout, stderr)
assert "WARNING: Failed decoding trace: the-trace" in stderr.getvalue()
assert ret == 0
((int, str, NoneType), Optional[Union[int, str]]),
],
)
def test_shrink_types(self, types, expected_type):
assert shrink_types(types) == expected_type
def test_update_yield_none_and_return(self):
sig = Signature.from_callable(UpdateSignatureHelper.a_class_method)
sig = update_signature_return(sig, return_type=str, yield_type=NoneType)
assert sig == Signature(return_annotation=Generator[NoneType, NoneType, str])
def test_return_none(self, collector):
"""Ensure traces have a return_type of NoneType for functions that return a value of None"""
with trace_calls(collector):
implicit_return_none()
explicit_return_none()
expected = [
CallTrace(implicit_return_none, {}, NoneType),
CallTrace(explicit_return_none, {}, NoneType),
]
assert collector.traces == expected
def test_update_yield_and_return_none(self):
sig = Signature.from_callable(UpdateSignatureHelper.a_class_method)
sig = update_signature_return(sig, return_type=NoneType, yield_type=str)
assert sig == Signature(return_annotation=Iterator[str])
) -> inspect.Signature:
"""Update return annotation with the supplied types"""
anno = sig.return_annotation
if anno is not inspect.Signature.empty:
# If generating a stub to apply and there's already a return type
# annotation, generate a stub with no return type annotation, to avoid
# the possibility of "incompatible annotation" errors.
if existing_annotation_strategy == ExistingAnnotationStrategy.OMIT:
return sig.replace(return_annotation=inspect.Signature.empty)
# Don't change pre-existing annotations unless asked to
if existing_annotation_strategy == ExistingAnnotationStrategy.REPLICATE:
return sig
# NB: We cannot distinguish between functions that explicitly only
# return None and those that do so implicitly. In the case of generator
# functions both are typed as Iterator[]
if (yield_type is not None) and ((return_type is None) or (return_type == NoneType)):
anno = make_iterator(yield_type)
elif (yield_type is not None) and (return_type is not None):
anno = make_generator(yield_type, NoneType, return_type)
elif return_type is not None:
anno = return_type
return sig.replace(return_annotation=anno)
def render_annotation(anno: Any) -> str:
"""Convert an annotation into its stub representation."""
if _is_optional(anno):
elem_type = _get_optional_elem(anno)
rendered = 'Optional[' + render_annotation(elem_type) + ']'
elif hasattr(anno, '__supertype__'):
rendered = anno.__name__
elif is_forward_ref(anno):
rendered = repr(anno.__forward_arg__)
elif getattr(anno, '__module__', None) == 'typing':
rendered = repr(anno).replace('typing.', '')
elif isinstance(anno, NoneType):
rendered = 'None'
elif isinstance(anno, type):
if anno.__module__ in ('builtins',):
rendered = anno.__qualname__
else:
rendered = anno.__module__ + '.' + anno.__qualname__
elif isinstance(anno, str):
rendered = anno
else:
rendered = repr(anno)
# Temporary hacky workaround for #76 to fix remaining NoneType hints by search-replace
return rendered.replace('NoneType', 'None')