We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`builds` fails when used with `attrs` classes containing private attributes
Hi, I think I may have found a bug that occurs when using `builds` with automatic attribute inference from `attrs`-built classes that have required but "private" attributes. The bug is probably due to the fact that the name exposed via the constructor differs from the attribute name in these cases, since `attrs` by default strips the leading underscore. 

Here a minimal example:

```python
from attrs import define
from hypothesis import given, strategies as st


@define
class MyClass:
    _x: int


@given(st.builds(MyClass))
def test_class(my_obj):
    assert isinstance(my_obj, MyClass)
```

The error you get:

```python
AttributeError: 'MyClassAttributes' object has no attribute 'x'
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `hypothesis-python/setup.py`
Content:
```
1 # This file is part of Hypothesis, which may be found at
2 # https://github.com/HypothesisWorks/hypothesis/
3 #
4 # Copyright the Hypothesis Authors.
5 # Individual contributors are listed in AUTHORS.rst and the git log.
6 #
7 # This Source Code Form is subject to the terms of the Mozilla Public License,
8 # v. 2.0. If a copy of the MPL was not distributed with this file, You can
9 # obtain one at https://mozilla.org/MPL/2.0/.
10 
11 import sys
12 import warnings
13 from pathlib import Path
14 
15 import setuptools
16 
17 if sys.version_info[:2] < (3, 8):  # noqa  # "unreachable" sanity check
18     raise Exception(
19         "You are trying to install Hypothesis using Python "
20         f"{sys.version.split()[0]}, but it requires Python 3.8 or later."
21         "Update `pip` and `setuptools`, try again, and you will automatically "
22         "get the latest compatible version of Hypothesis instead.  "
23         "See also https://python3statement.org/practicalities/"
24     )
25 
26 
27 def local_file(name):
28     return Path(__file__).absolute().parent.joinpath(name).relative_to(Path.cwd())
29 
30 
31 SOURCE = str(local_file("src"))
32 
33 setuptools_version = tuple(map(int, setuptools.__version__.split(".")[:1]))
34 
35 if setuptools_version < (42,):
36     # Warning only - very bad if uploading bdist but fine if installing sdist.
37     warnings.warn(
38         "This version of setuptools is too old to handle license_files "
39         "metadata key.  For more info, see:  "
40         "https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#metadata",
41         stacklevel=1,
42     )
43 
44 
45 # Assignment to placate pyflakes. The actual version is from the exec that follows.
46 __version__ = None
47 exec(local_file("src/hypothesis/version.py").read_text(encoding="utf-8"))
48 assert __version__ is not None
49 
50 
51 extras = {
52     "cli": ["click>=7.0", "black>=19.10b0", "rich>=9.0.0"],
53     "codemods": ["libcst>=0.3.16"],
54     "ghostwriter": ["black>=19.10b0"],
55     "pytz": ["pytz>=2014.1"],
56     "dateutil": ["python-dateutil>=1.4"],
57     "lark": ["lark>=0.10.1"],  # probably still works with old `lark-parser` too
58     "numpy": ["numpy>=1.17.3"],  # oldest with wheels for non-EOL Python (for now)
59     "pandas": ["pandas>=1.1"],
60     "pytest": ["pytest>=4.6"],
61     "dpcontracts": ["dpcontracts>=0.4"],
62     "redis": ["redis>=3.0.0"],
63     # zoneinfo is an odd one: every dependency is conditional, because they're
64     # only necessary on old versions of Python or Windows systems.
65     "zoneinfo": [
66         "tzdata>=2023.3 ; sys_platform == 'win32'",
67         "backports.zoneinfo>=0.2.1 ; python_version<'3.9'",
68     ],
69     # We only support Django versions with upstream support - see
70     # https://www.djangoproject.com/download/#supported-versions
71     # We also leave the choice of timezone library to the user, since it
72     # might be zoneinfo or pytz depending on version and configuration.
73     "django": ["django>=3.2"],
74 }
75 
76 extras["all"] = sorted(set(sum(extras.values(), [])))
77 
78 
79 setuptools.setup(
80     name="hypothesis",
81     version=__version__,
82     author="David R. MacIver and Zac Hatfield-Dodds",
83     author_email="david@drmaciver.com",
84     packages=setuptools.find_packages(SOURCE),
85     package_dir={"": SOURCE},
86     package_data={"hypothesis": ["py.typed", "vendor/tlds-alpha-by-domain.txt"]},
87     url="https://hypothesis.works",
88     project_urls={
89         "Source": "https://github.com/HypothesisWorks/hypothesis/tree/master/hypothesis-python",
90         "Changelog": "https://hypothesis.readthedocs.io/en/latest/changes.html",
91         "Documentation": "https://hypothesis.readthedocs.io",
92         "Issues": "https://github.com/HypothesisWorks/hypothesis/issues",
93     },
94     license="MPL-2.0",
95     description="A library for property-based testing",
96     zip_safe=False,
97     extras_require=extras,
98     install_requires=[
99         "attrs>=19.2.0",
100         "exceptiongroup>=1.0.0 ; python_version<'3.11'",
101         "sortedcontainers>=2.1.0,<3.0.0",
102     ],
103     python_requires=">=3.8",
104     classifiers=[
105         "Development Status :: 5 - Production/Stable",
106         "Framework :: Hypothesis",
107         "Framework :: Pytest",
108         "Intended Audience :: Developers",
109         "License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)",
110         "Operating System :: Unix",
111         "Operating System :: POSIX",
112         "Operating System :: Microsoft :: Windows",
113         "Programming Language :: Python",
114         "Programming Language :: Python :: 3",
115         "Programming Language :: Python :: 3 :: Only",
116         "Programming Language :: Python :: 3.8",
117         "Programming Language :: Python :: 3.9",
118         "Programming Language :: Python :: 3.10",
119         "Programming Language :: Python :: 3.11",
120         "Programming Language :: Python :: 3.12",
121         "Programming Language :: Python :: Implementation :: CPython",
122         "Programming Language :: Python :: Implementation :: PyPy",
123         "Topic :: Education :: Testing",
124         "Topic :: Software Development :: Testing",
125         "Typing :: Typed",
126     ],
127     py_modules=["_hypothesis_pytestplugin", "_hypothesis_ftz_detector"],
128     entry_points={
129         "pytest11": ["hypothesispytest = _hypothesis_pytestplugin"],
130         "console_scripts": ["hypothesis = hypothesis.extra.cli:main"],
131     },
132     long_description=local_file("README.rst").read_text(encoding="utf-8"),
133     long_description_content_type="text/x-rst",
134     keywords="python testing fuzzing property-based-testing",
135 )
136
```

Path: `hypothesis-python/src/hypothesis/strategies/_internal/attrs.py`
Content:
```
1 # This file is part of Hypothesis, which may be found at
2 # https://github.com/HypothesisWorks/hypothesis/
3 #
4 # Copyright the Hypothesis Authors.
5 # Individual contributors are listed in AUTHORS.rst and the git log.
6 #
7 # This Source Code Form is subject to the terms of the Mozilla Public License,
8 # v. 2.0. If a copy of the MPL was not distributed with this file, You can
9 # obtain one at https://mozilla.org/MPL/2.0/.
10 
11 from functools import reduce
12 from itertools import chain
13 
14 import attr
15 
16 from hypothesis import strategies as st
17 from hypothesis.errors import ResolutionFailed
18 from hypothesis.internal.compat import get_type_hints
19 from hypothesis.strategies._internal.core import BuildsStrategy
20 from hypothesis.strategies._internal.types import is_a_type, type_sorting_key
21 from hypothesis.utils.conventions import infer
22 
23 
24 def from_attrs(target, args, kwargs, to_infer):
25     """An internal version of builds(), specialised for Attrs classes."""
26     fields = attr.fields(target)
27     kwargs = {k: v for k, v in kwargs.items() if v is not infer}
28     for name in to_infer:
29         kwargs[name] = from_attrs_attribute(getattr(fields, name), target)
30     # We might make this strategy more efficient if we added a layer here that
31     # retries drawing if validation fails, for improved composition.
32     # The treatment of timezones in datetimes() provides a precedent.
33     return BuildsStrategy(target, args, kwargs)
34 
35 
36 def from_attrs_attribute(attrib, target):
37     """Infer a strategy from the metadata on an attr.Attribute object."""
38     # Try inferring from the default argument.  Note that this will only help if
39     # the user passed `...` to builds() for this attribute, but in that case
40     # we use it as the minimal example.
41     default = st.nothing()
42     if isinstance(attrib.default, attr.Factory):
43         if not attrib.default.takes_self:
44             default = st.builds(attrib.default.factory)
45     elif attrib.default is not attr.NOTHING:
46         default = st.just(attrib.default)
47 
48     # Try inferring None, exact values, or type from attrs provided validators.
49     null = st.nothing()  # updated to none() on seeing an OptionalValidator
50     in_collections = []  # list of in_ validator collections to sample from
51     validator_types = set()  # type constraints to pass to types_to_strategy()
52     if attrib.validator is not None:
53         validator = attrib.validator
54         if isinstance(validator, attr.validators._OptionalValidator):
55             null = st.none()
56             validator = validator.validator
57         if isinstance(validator, attr.validators._AndValidator):
58             vs = validator._validators
59         else:
60             vs = [validator]
61         for v in vs:
62             if isinstance(v, attr.validators._InValidator):
63                 if isinstance(v.options, str):
64                     in_collections.append(list(all_substrings(v.options)))
65                 else:
66                     in_collections.append(v.options)
67             elif isinstance(v, attr.validators._InstanceOfValidator):
68                 validator_types.add(v.type)
69 
70     # This is the important line.  We compose the final strategy from various
71     # parts.  The default value, if any, is the minimal shrink, followed by
72     # None (again, if allowed).  We then prefer to sample from values passed
73     # to an in_ validator if available, but infer from a type otherwise.
74     # Pick one because (sampled_from((1, 2)) | from_type(int)) would usually
75     # fail validation by generating e.g. zero!
76     if in_collections:
77         sample = st.sampled_from(list(ordered_intersection(in_collections)))
78         strat = default | null | sample
79     else:
80         strat = default | null | types_to_strategy(attrib, validator_types)
81 
82     # Better to give a meaningful error here than an opaque "could not draw"
83     # when we try to get a value but have lost track of where this was created.
84     if strat.is_empty:
85         raise ResolutionFailed(
86             "Cannot infer a strategy from the default, validator, type, or "
87             f"converter for attribute={attrib!r} of class={target!r}"
88         )
89     return strat
90 
91 
92 def types_to_strategy(attrib, types):
93     """Find all the type metadata for this attribute, reconcile it, and infer a
94     strategy from the mess."""
95     # If we know types from the validator(s), that's sufficient.
96     if len(types) == 1:
97         (typ,) = types
98         if isinstance(typ, tuple):
99             return st.one_of(*map(st.from_type, typ))
100         return st.from_type(typ)
101     elif types:
102         # We have a list of tuples of types, and want to find a type
103         # (or tuple of types) that is a subclass of all of of them.
104         type_tuples = [k if isinstance(k, tuple) else (k,) for k in types]
105         # Flatten the list, filter types that would fail validation, and
106         # sort so that ordering is stable between runs and shrinks well.
107         allowed = [
108             t
109             for t in set(sum(type_tuples, ()))
110             if all(issubclass(t, tup) for tup in type_tuples)
111         ]
112         allowed.sort(key=type_sorting_key)
113         return st.one_of([st.from_type(t) for t in allowed])
114 
115     # Otherwise, try the `type` attribute as a fallback, and finally try
116     # the type hints on a converter (desperate!) before giving up.
117     if is_a_type(getattr(attrib, "type", None)):
118         # The convoluted test is because variable annotations may be stored
119         # in string form; attrs doesn't evaluate them and we don't handle them.
120         # See PEP 526, PEP 563, and Hypothesis issue #1004 for details.
121         return st.from_type(attrib.type)
122 
123     converter = getattr(attrib, "converter", None)
124     if isinstance(converter, type):
125         return st.from_type(converter)
126     elif callable(converter):
127         hints = get_type_hints(converter)
128         if "return" in hints:
129             return st.from_type(hints["return"])
130 
131     return st.nothing()
132 
133 
134 def ordered_intersection(in_):
135     """Set union of n sequences, ordered for reproducibility across runs."""
136     intersection = reduce(set.intersection, in_, set(in_[0]))
137     for x in chain.from_iterable(in_):
138         if x in intersection:
139             yield x
140             intersection.remove(x)
141 
142 
143 def all_substrings(s):
144     """Generate all substrings of `s`, in order of length then occurrence.
145     Includes the empty string (first), and any duplicates that are present.
146 
147     >>> list(all_substrings('010'))
148     ['', '0', '1', '0', '01', '10', '010']
149     """
150     yield s[:0]
151     for n, _ in enumerate(s):
152         for i in range(len(s) - n):
153             yield s[i : i + n + 1]
154
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/hypothesis-python/setup.py b/hypothesis-python/setup.py
--- a/hypothesis-python/setup.py
+++ b/hypothesis-python/setup.py
@@ -96,7 +96,7 @@
     zip_safe=False,
     extras_require=extras,
     install_requires=[
-        "attrs>=19.2.0",
+        "attrs>=22.2.0",
         "exceptiongroup>=1.0.0 ; python_version<'3.11'",
         "sortedcontainers>=2.1.0,<3.0.0",
     ],
diff --git a/hypothesis-python/src/hypothesis/strategies/_internal/attrs.py b/hypothesis-python/src/hypothesis/strategies/_internal/attrs.py
--- a/hypothesis-python/src/hypothesis/strategies/_internal/attrs.py
+++ b/hypothesis-python/src/hypothesis/strategies/_internal/attrs.py
@@ -21,12 +21,38 @@
 from hypothesis.utils.conventions import infer
 
 
+def get_attribute_by_alias(fields, alias, *, target=None):
+    """
+    Get an attrs attribute by its alias, rather than its name (compare
+    getattr(fields, name)).
+
+    ``target`` is used only to provide a nicer error message, and can be safely
+    omitted.
+    """
+    # attrs supports defining an alias for a field, which is the name used when
+    # defining __init__. The init args are what we pull from when determining
+    # what parameters we need to supply to the class, so it's what we need to
+    # match against as well, rather than the class-level attribute name.
+    matched_fields = [f for f in fields if f.alias == alias]
+    if not matched_fields:
+        raise TypeError(
+            f"Unexpected keyword argument {alias} for attrs class"
+            f"{f' {target}' if target else ''}. Expected one of "
+            f"{[f.name for f in fields]}"
+        )
+    # alias is used as an arg in __init__, so it is guaranteed to be unique, if
+    # it exists.
+    assert len(matched_fields) == 1
+    return matched_fields[0]
+
+
 def from_attrs(target, args, kwargs, to_infer):
     """An internal version of builds(), specialised for Attrs classes."""
     fields = attr.fields(target)
     kwargs = {k: v for k, v in kwargs.items() if v is not infer}
     for name in to_infer:
-        kwargs[name] = from_attrs_attribute(getattr(fields, name), target)
+        attrib = get_attribute_by_alias(fields, name, target=target)
+        kwargs[name] = from_attrs_attribute(attrib, target)
     # We might make this strategy more efficient if we added a layer here that
     # retries drawing if validation fails, for improved composition.
     # The treatment of timezones in datetimes() provides a precedent.

{"golden_diff": "diff --git a/hypothesis-python/setup.py b/hypothesis-python/setup.py\n--- a/hypothesis-python/setup.py\n+++ b/hypothesis-python/setup.py\n@@ -96,7 +96,7 @@\n     zip_safe=False,\n     extras_require=extras,\n     install_requires=[\n-        \"attrs>=19.2.0\",\n+        \"attrs>=22.2.0\",\n         \"exceptiongroup>=1.0.0 ; python_version<'3.11'\",\n         \"sortedcontainers>=2.1.0,<3.0.0\",\n     ],\ndiff --git a/hypothesis-python/src/hypothesis/strategies/_internal/attrs.py b/hypothesis-python/src/hypothesis/strategies/_internal/attrs.py\n--- a/hypothesis-python/src/hypothesis/strategies/_internal/attrs.py\n+++ b/hypothesis-python/src/hypothesis/strategies/_internal/attrs.py\n@@ -21,12 +21,38 @@\n from hypothesis.utils.conventions import infer\n \n \n+def get_attribute_by_alias(fields, alias, *, target=None):\n+    \"\"\"\n+    Get an attrs attribute by its alias, rather than its name (compare\n+    getattr(fields, name)).\n+\n+    ``target`` is used only to provide a nicer error message, and can be safely\n+    omitted.\n+    \"\"\"\n+    # attrs supports defining an alias for a field, which is the name used when\n+    # defining __init__. The init args are what we pull from when determining\n+    # what parameters we need to supply to the class, so it's what we need to\n+    # match against as well, rather than the class-level attribute name.\n+    matched_fields = [f for f in fields if f.alias == alias]\n+    if not matched_fields:\n+        raise TypeError(\n+            f\"Unexpected keyword argument {alias} for attrs class\"\n+            f\"{f' {target}' if target else ''}. Expected one of \"\n+            f\"{[f.name for f in fields]}\"\n+        )\n+    # alias is used as an arg in __init__, so it is guaranteed to be unique, if\n+    # it exists.\n+    assert len(matched_fields) == 1\n+    return matched_fields[0]\n+\n+\n def from_attrs(target, args, kwargs, to_infer):\n     \"\"\"An internal version of builds(), specialised for Attrs classes.\"\"\"\n     fields = attr.fields(target)\n     kwargs = {k: v for k, v in kwargs.items() if v is not infer}\n     for name in to_infer:\n-        kwargs[name] = from_attrs_attribute(getattr(fields, name), target)\n+        attrib = get_attribute_by_alias(fields, name, target=target)\n+        kwargs[name] = from_attrs_attribute(attrib, target)\n     # We might make this strategy more efficient if we added a layer here that\n     # retries drawing if validation fails, for improved composition.\n     # The treatment of timezones in datetimes() provides a precedent.\n", "issue": "`builds` fails when used with `attrs` classes containing private attributes\nHi, I think I may have found a bug that occurs when using `builds` with automatic attribute inference from `attrs`-built classes that have required but \"private\" attributes. The bug is probably due to the fact that the name exposed via the constructor differs from the attribute name in these cases, since `attrs` by default strips the leading underscore. \r\n\r\nHere a minimal example:\r\n\r\n```python\r\nfrom attrs import define\r\nfrom hypothesis import given, strategies as st\r\n\r\n\r\n@define\r\nclass MyClass:\r\n    _x: int\r\n\r\n\r\n@given(st.builds(MyClass))\r\ndef test_class(my_obj):\r\n    assert isinstance(my_obj, MyClass)\r\n```\r\n\r\nThe error you get:\r\n\r\n```python\r\nAttributeError: 'MyClassAttributes' object has no attribute 'x'\r\n```\n", "before_files": [{"content": "# This file is part of Hypothesis, which may be found at\n# https://github.com/HypothesisWorks/hypothesis/\n#\n# Copyright the Hypothesis Authors.\n# Individual contributors are listed in AUTHORS.rst and the git log.\n#\n# This Source Code Form is subject to the terms of the Mozilla Public License,\n# v. 2.0. If a copy of the MPL was not distributed with this file, You can\n# obtain one at https://mozilla.org/MPL/2.0/.\n\nimport sys\nimport warnings\nfrom pathlib import Path\n\nimport setuptools\n\nif sys.version_info[:2] < (3, 8):  # noqa  # \"unreachable\" sanity check\n    raise Exception(\n        \"You are trying to install Hypothesis using Python \"\n        f\"{sys.version.split()[0]}, but it requires Python 3.8 or later.\"\n        \"Update `pip` and `setuptools`, try again, and you will automatically \"\n        \"get the latest compatible version of Hypothesis instead.  \"\n        \"See also https://python3statement.org/practicalities/\"\n    )\n\n\ndef local_file(name):\n    return Path(__file__).absolute().parent.joinpath(name).relative_to(Path.cwd())\n\n\nSOURCE = str(local_file(\"src\"))\n\nsetuptools_version = tuple(map(int, setuptools.__version__.split(\".\")[:1]))\n\nif setuptools_version < (42,):\n    # Warning only - very bad if uploading bdist but fine if installing sdist.\n    warnings.warn(\n        \"This version of setuptools is too old to handle license_files \"\n        \"metadata key.  For more info, see:  \"\n        \"https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#metadata\",\n        stacklevel=1,\n    )\n\n\n# Assignment to placate pyflakes. The actual version is from the exec that follows.\n__version__ = None\nexec(local_file(\"src/hypothesis/version.py\").read_text(encoding=\"utf-8\"))\nassert __version__ is not None\n\n\nextras = {\n    \"cli\": [\"click>=7.0\", \"black>=19.10b0\", \"rich>=9.0.0\"],\n    \"codemods\": [\"libcst>=0.3.16\"],\n    \"ghostwriter\": [\"black>=19.10b0\"],\n    \"pytz\": [\"pytz>=2014.1\"],\n    \"dateutil\": [\"python-dateutil>=1.4\"],\n    \"lark\": [\"lark>=0.10.1\"],  # probably still works with old `lark-parser` too\n    \"numpy\": [\"numpy>=1.17.3\"],  # oldest with wheels for non-EOL Python (for now)\n    \"pandas\": [\"pandas>=1.1\"],\n    \"pytest\": [\"pytest>=4.6\"],\n    \"dpcontracts\": [\"dpcontracts>=0.4\"],\n    \"redis\": [\"redis>=3.0.0\"],\n    # zoneinfo is an odd one: every dependency is conditional, because they're\n    # only necessary on old versions of Python or Windows systems.\n    \"zoneinfo\": [\n        \"tzdata>=2023.3 ; sys_platform == 'win32'\",\n        \"backports.zoneinfo>=0.2.1 ; python_version<'3.9'\",\n    ],\n    # We only support Django versions with upstream support - see\n    # https://www.djangoproject.com/download/#supported-versions\n    # We also leave the choice of timezone library to the user, since it\n    # might be zoneinfo or pytz depending on version and configuration.\n    \"django\": [\"django>=3.2\"],\n}\n\nextras[\"all\"] = sorted(set(sum(extras.values(), [])))\n\n\nsetuptools.setup(\n    name=\"hypothesis\",\n    version=__version__,\n    author=\"David R. MacIver and Zac Hatfield-Dodds\",\n    author_email=\"david@drmaciver.com\",\n    packages=setuptools.find_packages(SOURCE),\n    package_dir={\"\": SOURCE},\n    package_data={\"hypothesis\": [\"py.typed\", \"vendor/tlds-alpha-by-domain.txt\"]},\n    url=\"https://hypothesis.works\",\n    project_urls={\n        \"Source\": \"https://github.com/HypothesisWorks/hypothesis/tree/master/hypothesis-python\",\n        \"Changelog\": \"https://hypothesis.readthedocs.io/en/latest/changes.html\",\n        \"Documentation\": \"https://hypothesis.readthedocs.io\",\n        \"Issues\": \"https://github.com/HypothesisWorks/hypothesis/issues\",\n    },\n    license=\"MPL-2.0\",\n    description=\"A library for property-based testing\",\n    zip_safe=False,\n    extras_require=extras,\n    install_requires=[\n        \"attrs>=19.2.0\",\n        \"exceptiongroup>=1.0.0 ; python_version<'3.11'\",\n        \"sortedcontainers>=2.1.0,<3.0.0\",\n    ],\n    python_requires=\">=3.8\",\n    classifiers=[\n        \"Development Status :: 5 - Production/Stable\",\n        \"Framework :: Hypothesis\",\n        \"Framework :: Pytest\",\n        \"Intended Audience :: Developers\",\n        \"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)\",\n        \"Operating System :: Unix\",\n        \"Operating System :: POSIX\",\n        \"Operating System :: Microsoft :: Windows\",\n        \"Programming Language :: Python\",\n        \"Programming Language :: Python :: 3\",\n        \"Programming Language :: Python :: 3 :: Only\",\n        \"Programming Language :: Python :: 3.8\",\n        \"Programming Language :: Python :: 3.9\",\n        \"Programming Language :: Python :: 3.10\",\n        \"Programming Language :: Python :: 3.11\",\n        \"Programming Language :: Python :: 3.12\",\n        \"Programming Language :: Python :: Implementation :: CPython\",\n        \"Programming Language :: Python :: Implementation :: PyPy\",\n        \"Topic :: Education :: Testing\",\n        \"Topic :: Software Development :: Testing\",\n        \"Typing :: Typed\",\n    ],\n    py_modules=[\"_hypothesis_pytestplugin\", \"_hypothesis_ftz_detector\"],\n    entry_points={\n        \"pytest11\": [\"hypothesispytest = _hypothesis_pytestplugin\"],\n        \"console_scripts\": [\"hypothesis = hypothesis.extra.cli:main\"],\n    },\n    long_description=local_file(\"README.rst\").read_text(encoding=\"utf-8\"),\n    long_description_content_type=\"text/x-rst\",\n    keywords=\"python testing fuzzing property-based-testing\",\n)\n", "path": "hypothesis-python/setup.py"}, {"content": "# This file is part of Hypothesis, which may be found at\n# https://github.com/HypothesisWorks/hypothesis/\n#\n# Copyright the Hypothesis Authors.\n# Individual contributors are listed in AUTHORS.rst and the git log.\n#\n# This Source Code Form is subject to the terms of the Mozilla Public License,\n# v. 2.0. If a copy of the MPL was not distributed with this file, You can\n# obtain one at https://mozilla.org/MPL/2.0/.\n\nfrom functools import reduce\nfrom itertools import chain\n\nimport attr\n\nfrom hypothesis import strategies as st\nfrom hypothesis.errors import ResolutionFailed\nfrom hypothesis.internal.compat import get_type_hints\nfrom hypothesis.strategies._internal.core import BuildsStrategy\nfrom hypothesis.strategies._internal.types import is_a_type, type_sorting_key\nfrom hypothesis.utils.conventions import infer\n\n\ndef from_attrs(target, args, kwargs, to_infer):\n    \"\"\"An internal version of builds(), specialised for Attrs classes.\"\"\"\n    fields = attr.fields(target)\n    kwargs = {k: v for k, v in kwargs.items() if v is not infer}\n    for name in to_infer:\n        kwargs[name] = from_attrs_attribute(getattr(fields, name), target)\n    # We might make this strategy more efficient if we added a layer here that\n    # retries drawing if validation fails, for improved composition.\n    # The treatment of timezones in datetimes() provides a precedent.\n    return BuildsStrategy(target, args, kwargs)\n\n\ndef from_attrs_attribute(attrib, target):\n    \"\"\"Infer a strategy from the metadata on an attr.Attribute object.\"\"\"\n    # Try inferring from the default argument.  Note that this will only help if\n    # the user passed `...` to builds() for this attribute, but in that case\n    # we use it as the minimal example.\n    default = st.nothing()\n    if isinstance(attrib.default, attr.Factory):\n        if not attrib.default.takes_self:\n            default = st.builds(attrib.default.factory)\n    elif attrib.default is not attr.NOTHING:\n        default = st.just(attrib.default)\n\n    # Try inferring None, exact values, or type from attrs provided validators.\n    null = st.nothing()  # updated to none() on seeing an OptionalValidator\n    in_collections = []  # list of in_ validator collections to sample from\n    validator_types = set()  # type constraints to pass to types_to_strategy()\n    if attrib.validator is not None:\n        validator = attrib.validator\n        if isinstance(validator, attr.validators._OptionalValidator):\n            null = st.none()\n            validator = validator.validator\n        if isinstance(validator, attr.validators._AndValidator):\n            vs = validator._validators\n        else:\n            vs = [validator]\n        for v in vs:\n            if isinstance(v, attr.validators._InValidator):\n                if isinstance(v.options, str):\n                    in_collections.append(list(all_substrings(v.options)))\n                else:\n                    in_collections.append(v.options)\n            elif isinstance(v, attr.validators._InstanceOfValidator):\n                validator_types.add(v.type)\n\n    # This is the important line.  We compose the final strategy from various\n    # parts.  The default value, if any, is the minimal shrink, followed by\n    # None (again, if allowed).  We then prefer to sample from values passed\n    # to an in_ validator if available, but infer from a type otherwise.\n    # Pick one because (sampled_from((1, 2)) | from_type(int)) would usually\n    # fail validation by generating e.g. zero!\n    if in_collections:\n        sample = st.sampled_from(list(ordered_intersection(in_collections)))\n        strat = default | null | sample\n    else:\n        strat = default | null | types_to_strategy(attrib, validator_types)\n\n    # Better to give a meaningful error here than an opaque \"could not draw\"\n    # when we try to get a value but have lost track of where this was created.\n    if strat.is_empty:\n        raise ResolutionFailed(\n            \"Cannot infer a strategy from the default, validator, type, or \"\n            f\"converter for attribute={attrib!r} of class={target!r}\"\n        )\n    return strat\n\n\ndef types_to_strategy(attrib, types):\n    \"\"\"Find all the type metadata for this attribute, reconcile it, and infer a\n    strategy from the mess.\"\"\"\n    # If we know types from the validator(s), that's sufficient.\n    if len(types) == 1:\n        (typ,) = types\n        if isinstance(typ, tuple):\n            return st.one_of(*map(st.from_type, typ))\n        return st.from_type(typ)\n    elif types:\n        # We have a list of tuples of types, and want to find a type\n        # (or tuple of types) that is a subclass of all of of them.\n        type_tuples = [k if isinstance(k, tuple) else (k,) for k in types]\n        # Flatten the list, filter types that would fail validation, and\n        # sort so that ordering is stable between runs and shrinks well.\n        allowed = [\n            t\n            for t in set(sum(type_tuples, ()))\n            if all(issubclass(t, tup) for tup in type_tuples)\n        ]\n        allowed.sort(key=type_sorting_key)\n        return st.one_of([st.from_type(t) for t in allowed])\n\n    # Otherwise, try the `type` attribute as a fallback, and finally try\n    # the type hints on a converter (desperate!) before giving up.\n    if is_a_type(getattr(attrib, \"type\", None)):\n        # The convoluted test is because variable annotations may be stored\n        # in string form; attrs doesn't evaluate them and we don't handle them.\n        # See PEP 526, PEP 563, and Hypothesis issue #1004 for details.\n        return st.from_type(attrib.type)\n\n    converter = getattr(attrib, \"converter\", None)\n    if isinstance(converter, type):\n        return st.from_type(converter)\n    elif callable(converter):\n        hints = get_type_hints(converter)\n        if \"return\" in hints:\n            return st.from_type(hints[\"return\"])\n\n    return st.nothing()\n\n\ndef ordered_intersection(in_):\n    \"\"\"Set union of n sequences, ordered for reproducibility across runs.\"\"\"\n    intersection = reduce(set.intersection, in_, set(in_[0]))\n    for x in chain.from_iterable(in_):\n        if x in intersection:\n            yield x\n            intersection.remove(x)\n\n\ndef all_substrings(s):\n    \"\"\"Generate all substrings of `s`, in order of length then occurrence.\n    Includes the empty string (first), and any duplicates that are present.\n\n    >>> list(all_substrings('010'))\n    ['', '0', '1', '0', '01', '10', '010']\n    \"\"\"\n    yield s[:0]\n    for n, _ in enumerate(s):\n        for i in range(len(s) - n):\n            yield s[i : i + n + 1]\n", "path": "hypothesis-python/src/hypothesis/strategies/_internal/attrs.py"}], "after_files": [{"content": "# This file is part of Hypothesis, which may be found at\n# https://github.com/HypothesisWorks/hypothesis/\n#\n# Copyright the Hypothesis Authors.\n# Individual contributors are listed in AUTHORS.rst and the git log.\n#\n# This Source Code Form is subject to the terms of the Mozilla Public License,\n# v. 2.0. If a copy of the MPL was not distributed with this file, You can\n# obtain one at https://mozilla.org/MPL/2.0/.\n\nimport sys\nimport warnings\nfrom pathlib import Path\n\nimport setuptools\n\nif sys.version_info[:2] < (3, 8):  # noqa  # \"unreachable\" sanity check\n    raise Exception(\n        \"You are trying to install Hypothesis using Python \"\n        f\"{sys.version.split()[0]}, but it requires Python 3.8 or later.\"\n        \"Update `pip` and `setuptools`, try again, and you will automatically \"\n        \"get the latest compatible version of Hypothesis instead.  \"\n        \"See also https://python3statement.org/practicalities/\"\n    )\n\n\ndef local_file(name):\n    return Path(__file__).absolute().parent.joinpath(name).relative_to(Path.cwd())\n\n\nSOURCE = str(local_file(\"src\"))\n\nsetuptools_version = tuple(map(int, setuptools.__version__.split(\".\")[:1]))\n\nif setuptools_version < (42,):\n    # Warning only - very bad if uploading bdist but fine if installing sdist.\n    warnings.warn(\n        \"This version of setuptools is too old to handle license_files \"\n        \"metadata key.  For more info, see:  \"\n        \"https://setuptools.pypa.io/en/latest/userguide/declarative_config.html#metadata\",\n        stacklevel=1,\n    )\n\n\n# Assignment to placate pyflakes. The actual version is from the exec that follows.\n__version__ = None\nexec(local_file(\"src/hypothesis/version.py\").read_text(encoding=\"utf-8\"))\nassert __version__ is not None\n\n\nextras = {\n    \"cli\": [\"click>=7.0\", \"black>=19.10b0\", \"rich>=9.0.0\"],\n    \"codemods\": [\"libcst>=0.3.16\"],\n    \"ghostwriter\": [\"black>=19.10b0\"],\n    \"pytz\": [\"pytz>=2014.1\"],\n    \"dateutil\": [\"python-dateutil>=1.4\"],\n    \"lark\": [\"lark>=0.10.1\"],  # probably still works with old `lark-parser` too\n    \"numpy\": [\"numpy>=1.17.3\"],  # oldest with wheels for non-EOL Python (for now)\n    \"pandas\": [\"pandas>=1.1\"],\n    \"pytest\": [\"pytest>=4.6\"],\n    \"dpcontracts\": [\"dpcontracts>=0.4\"],\n    \"redis\": [\"redis>=3.0.0\"],\n    # zoneinfo is an odd one: every dependency is conditional, because they're\n    # only necessary on old versions of Python or Windows systems.\n    \"zoneinfo\": [\n        \"tzdata>=2023.3 ; sys_platform == 'win32'\",\n        \"backports.zoneinfo>=0.2.1 ; python_version<'3.9'\",\n    ],\n    # We only support Django versions with upstream support - see\n    # https://www.djangoproject.com/download/#supported-versions\n    # We also leave the choice of timezone library to the user, since it\n    # might be zoneinfo or pytz depending on version and configuration.\n    \"django\": [\"django>=3.2\"],\n}\n\nextras[\"all\"] = sorted(set(sum(extras.values(), [])))\n\n\nsetuptools.setup(\n    name=\"hypothesis\",\n    version=__version__,\n    author=\"David R. MacIver and Zac Hatfield-Dodds\",\n    author_email=\"david@drmaciver.com\",\n    packages=setuptools.find_packages(SOURCE),\n    package_dir={\"\": SOURCE},\n    package_data={\"hypothesis\": [\"py.typed\", \"vendor/tlds-alpha-by-domain.txt\"]},\n    url=\"https://hypothesis.works\",\n    project_urls={\n        \"Source\": \"https://github.com/HypothesisWorks/hypothesis/tree/master/hypothesis-python\",\n        \"Changelog\": \"https://hypothesis.readthedocs.io/en/latest/changes.html\",\n        \"Documentation\": \"https://hypothesis.readthedocs.io\",\n        \"Issues\": \"https://github.com/HypothesisWorks/hypothesis/issues\",\n    },\n    license=\"MPL-2.0\",\n    description=\"A library for property-based testing\",\n    zip_safe=False,\n    extras_require=extras,\n    install_requires=[\n        \"attrs>=22.2.0\",\n        \"exceptiongroup>=1.0.0 ; python_version<'3.11'\",\n        \"sortedcontainers>=2.1.0,<3.0.0\",\n    ],\n    python_requires=\">=3.8\",\n    classifiers=[\n        \"Development Status :: 5 - Production/Stable\",\n        \"Framework :: Hypothesis\",\n        \"Framework :: Pytest\",\n        \"Intended Audience :: Developers\",\n        \"License :: OSI Approved :: Mozilla Public License 2.0 (MPL 2.0)\",\n        \"Operating System :: Unix\",\n        \"Operating System :: POSIX\",\n        \"Operating System :: Microsoft :: Windows\",\n        \"Programming Language :: Python\",\n        \"Programming Language :: Python :: 3\",\n        \"Programming Language :: Python :: 3 :: Only\",\n        \"Programming Language :: Python :: 3.8\",\n        \"Programming Language :: Python :: 3.9\",\n        \"Programming Language :: Python :: 3.10\",\n        \"Programming Language :: Python :: 3.11\",\n        \"Programming Language :: Python :: 3.12\",\n        \"Programming Language :: Python :: Implementation :: CPython\",\n        \"Programming Language :: Python :: Implementation :: PyPy\",\n        \"Topic :: Education :: Testing\",\n        \"Topic :: Software Development :: Testing\",\n        \"Typing :: Typed\",\n    ],\n    py_modules=[\"_hypothesis_pytestplugin\", \"_hypothesis_ftz_detector\"],\n    entry_points={\n        \"pytest11\": [\"hypothesispytest = _hypothesis_pytestplugin\"],\n        \"console_scripts\": [\"hypothesis = hypothesis.extra.cli:main\"],\n    },\n    long_description=local_file(\"README.rst\").read_text(encoding=\"utf-8\"),\n    long_description_content_type=\"text/x-rst\",\n    keywords=\"python testing fuzzing property-based-testing\",\n)\n", "path": "hypothesis-python/setup.py"}, {"content": "# This file is part of Hypothesis, which may be found at\n# https://github.com/HypothesisWorks/hypothesis/\n#\n# Copyright the Hypothesis Authors.\n# Individual contributors are listed in AUTHORS.rst and the git log.\n#\n# This Source Code Form is subject to the terms of the Mozilla Public License,\n# v. 2.0. If a copy of the MPL was not distributed with this file, You can\n# obtain one at https://mozilla.org/MPL/2.0/.\n\nfrom functools import reduce\nfrom itertools import chain\n\nimport attr\n\nfrom hypothesis import strategies as st\nfrom hypothesis.errors import ResolutionFailed\nfrom hypothesis.internal.compat import get_type_hints\nfrom hypothesis.strategies._internal.core import BuildsStrategy\nfrom hypothesis.strategies._internal.types import is_a_type, type_sorting_key\nfrom hypothesis.utils.conventions import infer\n\n\ndef get_attribute_by_alias(fields, alias, *, target=None):\n    \"\"\"\n    Get an attrs attribute by its alias, rather than its name (compare\n    getattr(fields, name)).\n\n    ``target`` is used only to provide a nicer error message, and can be safely\n    omitted.\n    \"\"\"\n    # attrs supports defining an alias for a field, which is the name used when\n    # defining __init__. The init args are what we pull from when determining\n    # what parameters we need to supply to the class, so it's what we need to\n    # match against as well, rather than the class-level attribute name.\n    matched_fields = [f for f in fields if f.alias == alias]\n    if not matched_fields:\n        raise TypeError(\n            f\"Unexpected keyword argument {alias} for attrs class\"\n            f\"{f' {target}' if target else ''}. Expected one of \"\n            f\"{[f.name for f in fields]}\"\n        )\n    # alias is used as an arg in __init__, so it is guaranteed to be unique, if\n    # it exists.\n    assert len(matched_fields) == 1\n    return matched_fields[0]\n\n\ndef from_attrs(target, args, kwargs, to_infer):\n    \"\"\"An internal version of builds(), specialised for Attrs classes.\"\"\"\n    fields = attr.fields(target)\n    kwargs = {k: v for k, v in kwargs.items() if v is not infer}\n    for name in to_infer:\n        attrib = get_attribute_by_alias(fields, name, target=target)\n        kwargs[name] = from_attrs_attribute(attrib, target)\n    # We might make this strategy more efficient if we added a layer here that\n    # retries drawing if validation fails, for improved composition.\n    # The treatment of timezones in datetimes() provides a precedent.\n    return BuildsStrategy(target, args, kwargs)\n\n\ndef from_attrs_attribute(attrib, target):\n    \"\"\"Infer a strategy from the metadata on an attr.Attribute object.\"\"\"\n    # Try inferring from the default argument.  Note that this will only help if\n    # the user passed `...` to builds() for this attribute, but in that case\n    # we use it as the minimal example.\n    default = st.nothing()\n    if isinstance(attrib.default, attr.Factory):\n        if not attrib.default.takes_self:\n            default = st.builds(attrib.default.factory)\n    elif attrib.default is not attr.NOTHING:\n        default = st.just(attrib.default)\n\n    # Try inferring None, exact values, or type from attrs provided validators.\n    null = st.nothing()  # updated to none() on seeing an OptionalValidator\n    in_collections = []  # list of in_ validator collections to sample from\n    validator_types = set()  # type constraints to pass to types_to_strategy()\n    if attrib.validator is not None:\n        validator = attrib.validator\n        if isinstance(validator, attr.validators._OptionalValidator):\n            null = st.none()\n            validator = validator.validator\n        if isinstance(validator, attr.validators._AndValidator):\n            vs = validator._validators\n        else:\n            vs = [validator]\n        for v in vs:\n            if isinstance(v, attr.validators._InValidator):\n                if isinstance(v.options, str):\n                    in_collections.append(list(all_substrings(v.options)))\n                else:\n                    in_collections.append(v.options)\n            elif isinstance(v, attr.validators._InstanceOfValidator):\n                validator_types.add(v.type)\n\n    # This is the important line.  We compose the final strategy from various\n    # parts.  The default value, if any, is the minimal shrink, followed by\n    # None (again, if allowed).  We then prefer to sample from values passed\n    # to an in_ validator if available, but infer from a type otherwise.\n    # Pick one because (sampled_from((1, 2)) | from_type(int)) would usually\n    # fail validation by generating e.g. zero!\n    if in_collections:\n        sample = st.sampled_from(list(ordered_intersection(in_collections)))\n        strat = default | null | sample\n    else:\n        strat = default | null | types_to_strategy(attrib, validator_types)\n\n    # Better to give a meaningful error here than an opaque \"could not draw\"\n    # when we try to get a value but have lost track of where this was created.\n    if strat.is_empty:\n        raise ResolutionFailed(\n            \"Cannot infer a strategy from the default, validator, type, or \"\n            f\"converter for attribute={attrib!r} of class={target!r}\"\n        )\n    return strat\n\n\ndef types_to_strategy(attrib, types):\n    \"\"\"Find all the type metadata for this attribute, reconcile it, and infer a\n    strategy from the mess.\"\"\"\n    # If we know types from the validator(s), that's sufficient.\n    if len(types) == 1:\n        (typ,) = types\n        if isinstance(typ, tuple):\n            return st.one_of(*map(st.from_type, typ))\n        return st.from_type(typ)\n    elif types:\n        # We have a list of tuples of types, and want to find a type\n        # (or tuple of types) that is a subclass of all of of them.\n        type_tuples = [k if isinstance(k, tuple) else (k,) for k in types]\n        # Flatten the list, filter types that would fail validation, and\n        # sort so that ordering is stable between runs and shrinks well.\n        allowed = [\n            t\n            for t in set(sum(type_tuples, ()))\n            if all(issubclass(t, tup) for tup in type_tuples)\n        ]\n        allowed.sort(key=type_sorting_key)\n        return st.one_of([st.from_type(t) for t in allowed])\n\n    # Otherwise, try the `type` attribute as a fallback, and finally try\n    # the type hints on a converter (desperate!) before giving up.\n    if is_a_type(getattr(attrib, \"type\", None)):\n        # The convoluted test is because variable annotations may be stored\n        # in string form; attrs doesn't evaluate them and we don't handle them.\n        # See PEP 526, PEP 563, and Hypothesis issue #1004 for details.\n        return st.from_type(attrib.type)\n\n    converter = getattr(attrib, \"converter\", None)\n    if isinstance(converter, type):\n        return st.from_type(converter)\n    elif callable(converter):\n        hints = get_type_hints(converter)\n        if \"return\" in hints:\n            return st.from_type(hints[\"return\"])\n\n    return st.nothing()\n\n\ndef ordered_intersection(in_):\n    \"\"\"Set union of n sequences, ordered for reproducibility across runs.\"\"\"\n    intersection = reduce(set.intersection, in_, set(in_[0]))\n    for x in chain.from_iterable(in_):\n        if x in intersection:\n            yield x\n            intersection.remove(x)\n\n\ndef all_substrings(s):\n    \"\"\"Generate all substrings of `s`, in order of length then occurrence.\n    Includes the empty string (first), and any duplicates that are present.\n\n    >>> list(all_substrings('010'))\n    ['', '0', '1', '0', '01', '10', '010']\n    \"\"\"\n    yield s[:0]\n    for n, _ in enumerate(s):\n        for i in range(len(s) - n):\n            yield s[i : i + n + 1]\n", "path": "hypothesis-python/src/hypothesis/strategies/_internal/attrs.py"}]}