prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Incompatibility with emcee3 pre-release
  Trying to use the `from_emcee()` function raises the following error for `emcee3`:
  
  > AttributeError: 'EnsembleSampler' object has no attribute 'args'
  
  This is due to line 29 in `io_emcee.py`:
  
      num_args = len(sampler.args)
  
  In version 2, the EnsembleSampler class stored this information, but only to pass this to `_function_wrapper` class, which also stored the same information. This wrapper was for the posterior probability, so, `sampler.args` is equivalent to `sampler.lnprobfn.args`.
  
  In version 3, this has been slightly modified, and now only the `_FunctionWrapper` class stores this information, however, its name has also been modified, so in this case it should be retrieved with `sampler.log_prob_fn.args`. 
  
  </issue>
  <code>
  [start of arviz/data/io_emcee.py]
  1 """emcee-specific conversion code."""
  2 from .inference_data import InferenceData
  3 from .base import dict_to_dataset
  4 
  5 
  6 def _verify_names(sampler, var_names, arg_names):
  7     """Make sure var_names and arg_names are assigned reasonably.
  8 
  9     This is meant to run before loading emcee objects into InferenceData.
  10     In case var_names or arg_names is None, will provide defaults. If they are
  11     not None, it verifies there are the right number of them.
  12 
  13     Throws a ValueError in case validation fails.
  14 
  15     Parameters
  16     ----------
  17     sampler : emcee.EnsembleSampler
  18         Fitted emcee sampler
  19     var_names : list[str] or None
  20         Names for the emcee parameters
  21     arg_names : list[str] or None
  22         Names for the args/observations provided to emcee
  23 
  24     Returns
  25     -------
  26     list[str], list[str]
  27         Defaults for var_names and arg_names
  28     """
  29     num_vars = sampler.chain.shape[-1]
  30     num_args = len(sampler.args)
  31 
  32     if var_names is None:
  33         var_names = ["var_{}".format(idx) for idx in range(num_vars)]
  34     if arg_names is None:
  35         arg_names = ["arg_{}".format(idx) for idx in range(num_args)]
  36 
  37     if len(var_names) != num_vars:
  38         raise ValueError(
  39             "The sampler has {} variables, but only {} var_names were provided!".format(
  40                 num_vars, len(var_names)
  41             )
  42         )
  43 
  44     if len(arg_names) != num_args:
  45         raise ValueError(
  46             "The sampler has {} args, but only {} arg_names were provided!".format(
  47                 num_args, len(arg_names)
  48             )
  49         )
  50     return var_names, arg_names
  51 
  52 
  53 class EmceeConverter:
  54     """Encapsulate emcee specific logic."""
  55 
  56     def __init__(self, sampler, *_, var_names=None, arg_names=None, coords=None, dims=None):
  57         var_names, arg_names = _verify_names(sampler, var_names, arg_names)
  58         self.sampler = sampler
  59         self.var_names = var_names
  60         self.arg_names = arg_names
  61         self.coords = coords
  62         self.dims = dims
  63         import emcee
  64 
  65         self.emcee = emcee
  66 
  67     def posterior_to_xarray(self):
  68         """Convert the posterior to an xarray dataset."""
  69         data = {}
  70         for idx, var_name in enumerate(self.var_names):
  71             data[var_name] = self.sampler.chain[(..., idx)]
  72         return dict_to_dataset(data, library=self.emcee, coords=self.coords, dims=self.dims)
  73 
  74     def observed_data_to_xarray(self):
  75         """Convert observed data to xarray."""
  76         data = {}
  77         for idx, var_name in enumerate(self.arg_names):
  78             data[var_name] = self.sampler.args[idx]
  79         return dict_to_dataset(data, library=self.emcee, coords=self.coords, dims=self.dims)
  80 
  81     def to_inference_data(self):
  82         """Convert all available data to an InferenceData object."""
  83         return InferenceData(
  84             **{
  85                 "posterior": self.posterior_to_xarray(),
  86                 "observed_data": self.observed_data_to_xarray(),
  87             }
  88         )
  89 
  90 
  91 def from_emcee(sampler, *, var_names=None, arg_names=None, coords=None, dims=None):
  92     """Convert emcee data into an InferenceData object.
  93 
  94     Parameters
  95     ----------
  96     sampler : emcee.EnsembleSampler
  97         Fitted sampler from emcee.
  98     var_names : list[str] (Optional)
  99         A list of names for variables in the sampler
  100     arg_names : list[str] (Optional)
  101         A list of names for args in the sampler
  102     coords : dict[str] -> list[str]
  103         Map of dimensions to coordinates
  104     dims : dict[str] -> list[str]
  105         Map variable names to their coordinates
  106     """
  107     return EmceeConverter(
  108         sampler, var_names=var_names, arg_names=arg_names, coords=coords, dims=dims
  109     ).to_inference_data()
  110
  [end of arviz/data/io_emcee.py]
  </code>
  
  I need you to solve this issue by generating a single patch file that I can apply directly to this repository using git apply. Please respond with a single patch file in the following format.
  <patch>
  diff --git a/file.py b/file.py
  --- a/file.py
  +++ b/file.py
  @@ -1,27 +1,35 @@
   def euclidean(a, b):
  -    while b:
  -        a, b = b, a % b
  -    return a
  +    if b == 0:
  +        return a
  +    return euclidean(b, a % b)
   
   
   def bresenham(x0, y0, x1, y1):
       points = []
       dx = abs(x1 - x0)
       dy = abs(y1 - y0)
  -    sx = 1 if x0 < x1 else -1
  -    sy = 1 if y0 < y1 else -1
  -    err = dx - dy
  +    x, y = x0, y0
  +    sx = -1 if x0 > x1 else 1
  +    sy = -1 if y0 > y1 else 1
   
  -    while True:
  -        points.append((x0, y0))
  -        if x0 == x1 and y0 == y1:
  -            break
  -        e2 = 2 * err
  -        if e2 > -dy:
  -            err -= dy
  -            x0 += sx
  -        if e2 < dx:
  -            err += dx
  -            y0 += sy
  +    if dx > dy:
  +        err = dx / 2.0
  +        while x != x1:
  +            points.append((x, y))
  +            err -= dy
  +            if err < 0:
  +                y += sy
  +                err += dx
  +            x += sx
  +    else:
  +        err = dy / 2.0
  +        while y != y1:
  +            points.append((x, y))
  +            err -= dx
  +            if err < 0:
  +                x += sx
  +                err += dy
  +            y += sy
  +
  +    points.append((x, y))
       return points
  
  </patch>
golden_diff: diff --git a/arviz/data/io_emcee.py b/arviz/data/io_emcee.py
  --- a/arviz/data/io_emcee.py
  +++ b/arviz/data/io_emcee.py
  @@ -27,7 +27,8 @@
           Defaults for var_names and arg_names
       """
       num_vars = sampler.chain.shape[-1]
  -    num_args = len(sampler.args)
  +    # Get emcee version 2 sampler args, else get emcee version 3
  +    num_args = len(sampler.args) if hasattr(sampler, "args") else len(sampler.log_prob_fn.args)
   
       if var_names is None:
           var_names = ["var_{}".format(idx) for idx in range(num_vars)]
  @@ -75,7 +76,12 @@
           """Convert observed data to xarray."""
           data = {}
           for idx, var_name in enumerate(self.arg_names):
  -            data[var_name] = self.sampler.args[idx]
  +            # Get emcee version 2 sampler args, else get emcee version 3
  +            data[var_name] = (
  +                self.sampler.args[idx]
  +                if hasattr(self.sampler, "args")
  +                else self.sampler.log_prob_fn.args[idx]
  +            )
           return dict_to_dataset(data, library=self.emcee, coords=self.coords, dims=self.dims)
   
       def to_inference_data(self):
  
verification_info: {"golden_diff": "diff --git a/arviz/data/io_emcee.py b/arviz/data/io_emcee.py\n--- a/arviz/data/io_emcee.py\n+++ b/arviz/data/io_emcee.py\n@@ -27,7 +27,8 @@\n         Defaults for var_names and arg_names\n     \"\"\"\n     num_vars = sampler.chain.shape[-1]\n-    num_args = len(sampler.args)\n+    # Get emcee version 2 sampler args, else get emcee version 3\n+    num_args = len(sampler.args) if hasattr(sampler, \"args\") else len(sampler.log_prob_fn.args)\n \n     if var_names is None:\n         var_names = [\"var_{}\".format(idx) for idx in range(num_vars)]\n@@ -75,7 +76,12 @@\n         \"\"\"Convert observed data to xarray.\"\"\"\n         data = {}\n         for idx, var_name in enumerate(self.arg_names):\n-            data[var_name] = self.sampler.args[idx]\n+            # Get emcee version 2 sampler args, else get emcee version 3\n+            data[var_name] = (\n+                self.sampler.args[idx]\n+                if hasattr(self.sampler, \"args\")\n+                else self.sampler.log_prob_fn.args[idx]\n+            )\n         return dict_to_dataset(data, library=self.emcee, coords=self.coords, dims=self.dims)\n \n     def to_inference_data(self):\n", "issue": "Incompatibility with emcee3 pre-release\nTrying to use the `from_emcee()` function raises the following error for `emcee3`:\r\n\r\n> AttributeError: 'EnsembleSampler' object has no attribute 'args'\r\n\r\nThis is due to line 29 in `io_emcee.py`:\r\n\r\n    num_args = len(sampler.args)\r\n\r\nIn version 2, the EnsembleSampler class stored this information, but only to pass this to `_function_wrapper` class, which also stored the same information. This wrapper was for the posterior probability, so, `sampler.args` is equivalent to `sampler.lnprobfn.args`.\r\n\r\nIn version 3, this has been slightly modified, and now only the `_FunctionWrapper` class stores this information, however, its name has also been modified, so in this case it should be retrieved with `sampler.log_prob_fn.args`. \n", "before_files": [{"content": "\"\"\"emcee-specific conversion code.\"\"\"\nfrom .inference_data import InferenceData\nfrom .base import dict_to_dataset\n\n\ndef _verify_names(sampler, var_names, arg_names):\n    \"\"\"Make sure var_names and arg_names are assigned reasonably.\n\n    This is meant to run before loading emcee objects into InferenceData.\n    In case var_names or arg_names is None, will provide defaults. If they are\n    not None, it verifies there are the right number of them.\n\n    Throws a ValueError in case validation fails.\n\n    Parameters\n    ----------\n    sampler : emcee.EnsembleSampler\n        Fitted emcee sampler\n    var_names : list[str] or None\n        Names for the emcee parameters\n    arg_names : list[str] or None\n        Names for the args/observations provided to emcee\n\n    Returns\n    -------\n    list[str], list[str]\n        Defaults for var_names and arg_names\n    \"\"\"\n    num_vars = sampler.chain.shape[-1]\n    num_args = len(sampler.args)\n\n    if var_names is None:\n        var_names = [\"var_{}\".format(idx) for idx in range(num_vars)]\n    if arg_names is None:\n        arg_names = [\"arg_{}\".format(idx) for idx in range(num_args)]\n\n    if len(var_names) != num_vars:\n        raise ValueError(\n            \"The sampler has {} variables, but only {} var_names were provided!\".format(\n                num_vars, len(var_names)\n            )\n        )\n\n    if len(arg_names) != num_args:\n        raise ValueError(\n            \"The sampler has {} args, but only {} arg_names were provided!\".format(\n                num_args, len(arg_names)\n            )\n        )\n    return var_names, arg_names\n\n\nclass EmceeConverter:\n    \"\"\"Encapsulate emcee specific logic.\"\"\"\n\n    def __init__(self, sampler, *_, var_names=None, arg_names=None, coords=None, dims=None):\n        var_names, arg_names = _verify_names(sampler, var_names, arg_names)\n        self.sampler = sampler\n        self.var_names = var_names\n        self.arg_names = arg_names\n        self.coords = coords\n        self.dims = dims\n        import emcee\n\n        self.emcee = emcee\n\n    def posterior_to_xarray(self):\n        \"\"\"Convert the posterior to an xarray dataset.\"\"\"\n        data = {}\n        for idx, var_name in enumerate(self.var_names):\n            data[var_name] = self.sampler.chain[(..., idx)]\n        return dict_to_dataset(data, library=self.emcee, coords=self.coords, dims=self.dims)\n\n    def observed_data_to_xarray(self):\n        \"\"\"Convert observed data to xarray.\"\"\"\n        data = {}\n        for idx, var_name in enumerate(self.arg_names):\n            data[var_name] = self.sampler.args[idx]\n        return dict_to_dataset(data, library=self.emcee, coords=self.coords, dims=self.dims)\n\n    def to_inference_data(self):\n        \"\"\"Convert all available data to an InferenceData object.\"\"\"\n        return InferenceData(\n            **{\n                \"posterior\": self.posterior_to_xarray(),\n                \"observed_data\": self.observed_data_to_xarray(),\n            }\n        )\n\n\ndef from_emcee(sampler, *, var_names=None, arg_names=None, coords=None, dims=None):\n    \"\"\"Convert emcee data into an InferenceData object.\n\n    Parameters\n    ----------\n    sampler : emcee.EnsembleSampler\n        Fitted sampler from emcee.\n    var_names : list[str] (Optional)\n        A list of names for variables in the sampler\n    arg_names : list[str] (Optional)\n        A list of names for args in the sampler\n    coords : dict[str] -> list[str]\n        Map of dimensions to coordinates\n    dims : dict[str] -> list[str]\n        Map variable names to their coordinates\n    \"\"\"\n    return EmceeConverter(\n        sampler, var_names=var_names, arg_names=arg_names, coords=coords, dims=dims\n    ).to_inference_data()\n", "path": "arviz/data/io_emcee.py"}]}