I added a hypothesis test to cog, and it caused an error inside Hypothesis. This is kind of my fault, and kind of yours. Cog adds a SimpleNamespace object to sys.modules (for import cog), then you try to make a set of all the "modules".
@hypothesis.given(st.lists(st.text(max_size=100), max_size=50))
> def test_common_prefix(strings):
^^^
cogapp/test_whiteutils.py:103:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/engine.py:967: in run
self._run()
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/engine.py:1540: in _run
self.generate_new_examples()
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/engine.py:1245: in generate_new_examples
prefix = self.generate_novel_prefix()
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/engine.py:760: in generate_novel_prefix
return self.tree.generate_novel_prefix(self.random)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/datatree.py:781: in generate_novel_prefix
node_value = self._draw(
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/datatree.py:892: in _draw
value = draw_choice(choice_type, constraints, random=random)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/data.py:1354: in draw_choice
return cast(ChoiceT, getattr(cd.provider, f"draw_{choice_type}")(**constraints))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/providers.py:938: in draw_string
constant := self._maybe_draw_constant(
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/providers.py:739: in _maybe_draw_constant
assert self._local_constants is not None
^^^^^^^^^^^^^^^^^^^^^
/usr/local/pyenv/pyenv/versions/3.13.12/lib/python3.13/functools.py:1025: in __get__
val = self.func(instance)
^^^^^^^^^^^^^^^^^^^
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/providers.py:722: in _local_constants
return _get_local_constants()
^^^^^^^^^^^^^^^^^^^^^^
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
def _get_local_constants() -> Constants:
global _sys_modules_len, _local_constants
if sys.platform == "emscripten": # pragma: no cover
# pyodide builds bundle the stdlib in a nonstandard location, like
# `/lib/python312.zip/heapq.py`. To avoid identifying the entirety of
# the stdlib as local code and slowing down on emscripten, instead return
# that nothing is local.
#
# pyodide may provide some way to distinguish stdlib/third-party/local
# code. I haven't looked into it. If they do, we should correctly implement
# ModuleLocation for pyodide instead of this.
return _local_constants
count_constants = len(_local_constants)
# We call this function once per HypothesisProvider instance, i.e. once per
# input, so it needs to be performant. The logic here is more complicated
# than necessary because of this.
#
# First, we check whether there are any new modules with a very cheap length
# check. This check can be fooled if a module is added while another module is
# removed, but the more correct check against tuple(sys.modules.keys()) is
# substantially more expensive. Such a new module would eventually be discovered
# if / when the length changes again in the future.
#
# If the length has changed, we find just modules we haven't seen before. Of
# those, we find the ones which correspond to local modules, and extract their
# constants.
# careful: store sys.modules length when we first check to avoid race conditions
# with other threads loading a module before we set _sys_modules_len.
if (sys_modules_len := len(sys.modules)) != _sys_modules_len:
# set(_seen_modules) shouldn't typically be required, but I have run into
# a "set changed size during iteration" error here when running
# test_provider_conformance_crosshair.
> new_modules = set(sys.modules.values()) - set(_seen_modules)
^^^^^^^^^^^^^^^^^^^^^^^^^
E TypeError: unhashable type: 'types.SimpleNamespace'
.tox/py313/lib/python3.13/site-packages/hypothesis/internal/conjecture/providers.py:316: TypeError
I added a hypothesis test to cog, and it caused an error inside Hypothesis. This is kind of my fault, and kind of yours. Cog adds a SimpleNamespace object to sys.modules (for
import cog), then you try to make a set of all the "modules".