python / python/cpython

mock.seal has infinite recursion with mutually recursive class references

Abierto
#91,710 5 comentarios 1 reacción 0 asignados Ver en GitHub

Nadie ha tomado este issue todavía.

stdlib type-bug
Lenguaje dominante
Python
Estrellas
77.2k
Forks
36k
Métricas de merge de PR
Métricas de PR pendientes

Descripción

Bug report

This code seems to cause infinite recursion in unittest.mock.seal:

from unittest import mock
class Foo:
  pass
class Bar:
  foo = Foo
Foo.bar = Bar
foo = mock.create_autospec(Foo)
mock.seal(foo)
$ python3 foo.py 
Traceback (most recent call last):
  File "/tmp/tmp.yKOznvlUIG/foo.py", line 8, in <module>
    mock.seal(foo)
  File "/usr/lib/python3.9/unittest/mock.py", line 2874, in seal
    seal(m)
  File "/usr/lib/python3.9/unittest/mock.py", line 2874, in seal
    seal(m)
  File "/usr/lib/python3.9/unittest/mock.py", line 2874, in seal
    seal(m)
  [Previous line repeated 973 more times]
  File "/usr/lib/python3.9/unittest/mock.py", line 2866, in seal
    m = getattr(mock, attr)
  File "/usr/lib/python3.9/unittest/mock.py", line 655, in __getattr__
    result = create_autospec(
  File "/usr/lib/python3.9/unittest/mock.py", line 2627, in create_autospec
    mock = Klass(parent=_parent, _new_parent=_parent, _new_name=_new_name,
  File "/usr/lib/python3.9/unittest/mock.py", line 2034, in __init__
    _safe_super(MagicMixin, self).__init__(*args, **kw)
  File "/usr/lib/python3.9/unittest/mock.py", line 1074, in __init__
    _safe_super(CallableMixin, self).__init__(
  File "/usr/lib/python3.9/unittest/mock.py", line 437, in __init__
    self._mock_add_spec(spec, spec_set, _spec_as_instance, _eat_self)
  File "/usr/lib/python3.9/unittest/mock.py", line 500, in _mock_add_spec
    res = _get_signature_object(spec,
  File "/usr/lib/python3.9/unittest/mock.py", line 107, in _get_signature_object
    return func, inspect.signature(sig_func)
  File "/usr/lib/python3.9/inspect.py", line 3113, in signature
    return Signature.from_callable(obj, follow_wrapped=follow_wrapped)
  File "/usr/lib/python3.9/inspect.py", line 2862, in from_callable
    return _signature_from_callable(obj, sigcls=cls,
  File "/usr/lib/python3.9/inspect.py", line 2333, in _signature_from_callable
    wrapped_sig = _get_signature_of(obj.func)
  File "/usr/lib/python3.9/inspect.py", line 2329, in _signature_from_callable
    return _signature_from_builtin(sigcls, obj,
  File "/usr/lib/python3.9/inspect.py", line 2149, in _signature_from_builtin
    return _signature_fromstr(cls, func, s, skip_bound_arg)
  File "/usr/lib/python3.9/inspect.py", line 2009, in _signature_fromstr
    _signature_strip_non_python_syntax(s)
  File "/usr/lib/python3.9/inspect.py", line 1962, in _signature_strip_non_python_syntax
    for t in token_stream:
  File "/usr/lib/python3.9/tokenize.py", line 525, in _tokenize
    pseudomatch = _compile(PseudoToken).match(line, pos)
  File "/usr/lib/python3.9/tokenize.py", line 99, in _compile
    return re.compile(expr, re.UNICODE)
  File "/usr/lib/python3.9/re.py", line 252, in compile
    return _compile(pattern, flags)
  File "/usr/lib/python3.9/re.py", line 292, in _compile
    flags = flags.value
  File "/usr/lib/python3.9/types.py", line 178, in __get__
    return self.fget(instance)
RecursionError: maximum recursion depth exceeded

Your environment

  • CPython versions tested on: 3.9.9
  • Operating system and architecture: Debian testing, amd64

Guía de contribución

Abrir la guía de contribución

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Línea de trabajo

Comienza con unittest.mock.seal y create_autospec en unittest/mock.py, utilizando el reproductor Foo/Bar proporcionado para rastrear la ruta recursiva. El trabajo estará terminado cuando las referencias de clase mutuamente recursivas ya no provoquen una recursión infinita ni un RecursionError al ejecutarse mock.seal(foo).

Escrito por el modelo de indexación a partir del texto del issue.

Evaluación

Stack tecnológico
python
Área
testing
Tipo de issue
Error
Dificultad
3/5
Tiempo estimado
1-2 días
Estado de actividad
Estancado
Claridad
Bastante claro
Aptitud para principiantes
38/100

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.