prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  pyhf commandline tools requires uproot extra
  # Description
  
  just issuing `pyhf --help` requires the uproot extra since `commandline.py` imports `writexml`.
  
  # Expected Behavior
  
  I don't need uproot if I don't want to use json2xml or xml2json
  
  # Actual Behavior
  
  I can't use `pyhf` without installing uproot.
  
  # Steps to Reproduce
  
  install master and run pyhf
  
  # Checklist
  
  - [x] Run `git fetch` to get the most up to date version of `master`
  - [x] Searched through existing Issues to confirm this is not a duplicate issue
  - [x] Filled out the Description, Expected Behavior, Actual Behavior, and Steps to Reproduce sections above or have edited/removed them in a way that fully describes the issue
  
  
  </issue>
  <code>
  [start of pyhf/commandline.py]
  1 import logging
  2 
  3 import click
  4 import json
  5 import os
  6 
  7 from . import writexml
  8 from .utils import hypotest
  9 from .pdf import Workspace
  10 from .version import __version__
  11 
  12 logging.basicConfig()
  13 log = logging.getLogger(__name__)
  14 
  15 # This is only needed for Python 2/3 compatibility
  16 def ensure_dirs(path):
  17     try:
  18         os.makedirs(path, exist_ok=True)
  19     except TypeError:
  20         if not os.path.exists(path):
  21             os.makedirs(path)
  22 
  23 
  24 @click.group(context_settings=dict(help_option_names=['-h', '--help']))
  25 @click.version_option(version=__version__)
  26 def pyhf():
  27     pass
  28 
  29 
  30 @pyhf.command()
  31 @click.argument('entrypoint-xml', type=click.Path(exists=True))
  32 @click.option(
  33     '--basedir',
  34     help='The base directory for the XML files to point relative to.',
  35     type=click.Path(exists=True),
  36     default=os.getcwd(),
  37 )
  38 @click.option(
  39     '--output-file',
  40     help='The location of the output json file. If not specified, prints to screen.',
  41     default=None,
  42 )
  43 @click.option('--track-progress/--hide-progress', default=True)
  44 def xml2json(entrypoint_xml, basedir, output_file, track_progress):
  45     """ Entrypoint XML: The top-level XML file for the PDF definition. """
  46     try:
  47         import uproot
  48 
  49         assert uproot
  50     except ImportError:
  51         log.error(
  52             "xml2json requires uproot, please install pyhf using the "
  53             "xmlio extra: pip install pyhf[xmlio] or install uproot "
  54             "manually: pip install uproot"
  55         )
  56     from . import readxml
  57 
  58     spec = readxml.parse(entrypoint_xml, basedir, track_progress=track_progress)
  59     if output_file is None:
  60         print(json.dumps(spec, indent=4, sort_keys=True))
  61     else:
  62         with open(output_file, 'w+') as out_file:
  63             json.dump(spec, out_file, indent=4, sort_keys=True)
  64         log.debug("Written to {0:s}".format(output_file))
  65 
  66 
  67 @pyhf.command()
  68 @click.argument('workspace', default='-')
  69 @click.option('--output-dir', type=click.Path(exists=True), default='.')
  70 @click.option('--specroot', default='config')
  71 @click.option('--dataroot', default='data')
  72 @click.option('--resultprefix', default='FitConfig')
  73 def json2xml(workspace, output_dir, specroot, dataroot, resultprefix):
  74     try:
  75         import uproot
  76 
  77         assert uproot
  78     except ImportError:
  79         log.error(
  80             "json2xml requires uproot, please install pyhf using the "
  81             "xmlio extra: pip install pyhf[xmlio] or install uproot "
  82             "manually: pip install uproot"
  83         )
  84 
  85     ensure_dirs(output_dir)
  86     with click.open_file(workspace, 'r') as specstream:
  87         d = json.load(specstream)
  88         ensure_dirs(os.path.join(output_dir, specroot))
  89         ensure_dirs(os.path.join(output_dir, dataroot))
  90         with click.open_file(
  91             os.path.join(output_dir, '{0:s}.xml'.format(resultprefix)), 'w'
  92         ) as outstream:
  93             outstream.write(
  94                 writexml.writexml(
  95                     d,
  96                     os.path.join(output_dir, specroot),
  97                     os.path.join(output_dir, dataroot),
  98                     resultprefix,
  99                 ).decode('utf-8')
  100             )
  101 
  102 
  103 @pyhf.command()
  104 @click.argument('workspace', default='-')
  105 @click.option(
  106     '--output-file',
  107     help='The location of the output json file. If not specified, prints to screen.',
  108     default=None,
  109 )
  110 @click.option('--measurement', default=None)
  111 @click.option('-p', '--patch', multiple=True)
  112 @click.option('--testpoi', default=1.0)
  113 def cls(workspace, output_file, measurement, patch, testpoi):
  114     with click.open_file(workspace, 'r') as specstream:
  115         wspec = json.load(specstream)
  116 
  117     w = Workspace(wspec)
  118 
  119     patches = [json.loads(click.open_file(pfile, 'r').read()) for pfile in patch]
  120     p = w.model(measurement_name=measurement, patches=patches)
  121     result = hypotest(testpoi, w.data(p), p, return_expected_set=True)
  122     result = {'CLs_obs': result[0].tolist()[0], 'CLs_exp': result[-1].ravel().tolist()}
  123     if output_file is None:
  124         print(json.dumps(result, indent=4, sort_keys=True))
  125     else:
  126         with open(output_file, 'w+') as out_file:
  127             json.dump(result, out_file, indent=4, sort_keys=True)
  128         log.debug("Written to {0:s}".format(output_file))
  129
  [end of pyhf/commandline.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/pyhf/commandline.py b/pyhf/commandline.py
  --- a/pyhf/commandline.py
  +++ b/pyhf/commandline.py
  @@ -4,7 +4,6 @@
   import json
   import os
   
  -from . import writexml
   from .utils import hypotest
   from .pdf import Workspace
   from .version import __version__
  @@ -81,6 +80,7 @@
               "xmlio extra: pip install pyhf[xmlio] or install uproot "
               "manually: pip install uproot"
           )
  +    from . import writexml
   
       ensure_dirs(output_dir)
       with click.open_file(workspace, 'r') as specstream:
  
verification_info: {"golden_diff": "diff --git a/pyhf/commandline.py b/pyhf/commandline.py\n--- a/pyhf/commandline.py\n+++ b/pyhf/commandline.py\n@@ -4,7 +4,6 @@\n import json\n import os\n \n-from . import writexml\n from .utils import hypotest\n from .pdf import Workspace\n from .version import __version__\n@@ -81,6 +80,7 @@\n             \"xmlio extra: pip install pyhf[xmlio] or install uproot \"\n             \"manually: pip install uproot\"\n         )\n+    from . import writexml\n \n     ensure_dirs(output_dir)\n     with click.open_file(workspace, 'r') as specstream:\n", "issue": "pyhf commandline tools requires uproot extra\n# Description\r\n\r\njust issuing `pyhf --help` requires the uproot extra since `commandline.py` imports `writexml`.\r\n\r\n# Expected Behavior\r\n\r\nI don't need uproot if I don't want to use json2xml or xml2json\r\n\r\n# Actual Behavior\r\n\r\nI can't use `pyhf` without installing uproot.\r\n\r\n# Steps to Reproduce\r\n\r\ninstall master and run pyhf\r\n\r\n# Checklist\r\n\r\n- [x] Run `git fetch` to get the most up to date version of `master`\r\n- [x] Searched through existing Issues to confirm this is not a duplicate issue\r\n- [x] Filled out the Description, Expected Behavior, Actual Behavior, and Steps to Reproduce sections above or have edited/removed them in a way that fully describes the issue\r\n\n", "before_files": [{"content": "import logging\n\nimport click\nimport json\nimport os\n\nfrom . import writexml\nfrom .utils import hypotest\nfrom .pdf import Workspace\nfrom .version import __version__\n\nlogging.basicConfig()\nlog = logging.getLogger(__name__)\n\n# This is only needed for Python 2/3 compatibility\ndef ensure_dirs(path):\n    try:\n        os.makedirs(path, exist_ok=True)\n    except TypeError:\n        if not os.path.exists(path):\n            os.makedirs(path)\n\n\n@click.group(context_settings=dict(help_option_names=['-h', '--help']))\n@click.version_option(version=__version__)\ndef pyhf():\n    pass\n\n\n@pyhf.command()\n@click.argument('entrypoint-xml', type=click.Path(exists=True))\n@click.option(\n    '--basedir',\n    help='The base directory for the XML files to point relative to.',\n    type=click.Path(exists=True),\n    default=os.getcwd(),\n)\n@click.option(\n    '--output-file',\n    help='The location of the output json file. If not specified, prints to screen.',\n    default=None,\n)\n@click.option('--track-progress/--hide-progress', default=True)\ndef xml2json(entrypoint_xml, basedir, output_file, track_progress):\n    \"\"\" Entrypoint XML: The top-level XML file for the PDF definition. \"\"\"\n    try:\n        import uproot\n\n        assert uproot\n    except ImportError:\n        log.error(\n            \"xml2json requires uproot, please install pyhf using the \"\n            \"xmlio extra: pip install pyhf[xmlio] or install uproot \"\n            \"manually: pip install uproot\"\n        )\n    from . import readxml\n\n    spec = readxml.parse(entrypoint_xml, basedir, track_progress=track_progress)\n    if output_file is None:\n        print(json.dumps(spec, indent=4, sort_keys=True))\n    else:\n        with open(output_file, 'w+') as out_file:\n            json.dump(spec, out_file, indent=4, sort_keys=True)\n        log.debug(\"Written to {0:s}\".format(output_file))\n\n\n@pyhf.command()\n@click.argument('workspace', default='-')\n@click.option('--output-dir', type=click.Path(exists=True), default='.')\n@click.option('--specroot', default='config')\n@click.option('--dataroot', default='data')\n@click.option('--resultprefix', default='FitConfig')\ndef json2xml(workspace, output_dir, specroot, dataroot, resultprefix):\n    try:\n        import uproot\n\n        assert uproot\n    except ImportError:\n        log.error(\n            \"json2xml requires uproot, please install pyhf using the \"\n            \"xmlio extra: pip install pyhf[xmlio] or install uproot \"\n            \"manually: pip install uproot\"\n        )\n\n    ensure_dirs(output_dir)\n    with click.open_file(workspace, 'r') as specstream:\n        d = json.load(specstream)\n        ensure_dirs(os.path.join(output_dir, specroot))\n        ensure_dirs(os.path.join(output_dir, dataroot))\n        with click.open_file(\n            os.path.join(output_dir, '{0:s}.xml'.format(resultprefix)), 'w'\n        ) as outstream:\n            outstream.write(\n                writexml.writexml(\n                    d,\n                    os.path.join(output_dir, specroot),\n                    os.path.join(output_dir, dataroot),\n                    resultprefix,\n                ).decode('utf-8')\n            )\n\n\n@pyhf.command()\n@click.argument('workspace', default='-')\n@click.option(\n    '--output-file',\n    help='The location of the output json file. If not specified, prints to screen.',\n    default=None,\n)\n@click.option('--measurement', default=None)\n@click.option('-p', '--patch', multiple=True)\n@click.option('--testpoi', default=1.0)\ndef cls(workspace, output_file, measurement, patch, testpoi):\n    with click.open_file(workspace, 'r') as specstream:\n        wspec = json.load(specstream)\n\n    w = Workspace(wspec)\n\n    patches = [json.loads(click.open_file(pfile, 'r').read()) for pfile in patch]\n    p = w.model(measurement_name=measurement, patches=patches)\n    result = hypotest(testpoi, w.data(p), p, return_expected_set=True)\n    result = {'CLs_obs': result[0].tolist()[0], 'CLs_exp': result[-1].ravel().tolist()}\n    if output_file is None:\n        print(json.dumps(result, indent=4, sort_keys=True))\n    else:\n        with open(output_file, 'w+') as out_file:\n            json.dump(result, out_file, indent=4, sort_keys=True)\n        log.debug(\"Written to {0:s}\".format(output_file))\n", "path": "pyhf/commandline.py"}]}