prompt: You will be provided with a partial code base and an issue statement explaining a problem to resolve.
  <issue>
  Cannot use variables with integer-only values
  ### Expected behaviour:
  Variables should be able to handle integer-only values.
  
  ### Actual behaviour:
  Configuration parsing error (when using ``'{? deluge.port ?}'``): ``Got `50586`, expected: integer``
  Configuration parsing error (when using ``{? deluge.port ?}``):
  ```
  while parsing a flow mapping in "<unicode string>", line 16, column 13: port: {? deluge.port ?} ^ expected ',' or '}', but got '?' in "<unicode string>", line 16, column 28: port: {? deluge.port ?} ^
  ```
  
  ### Steps to reproduce:
  - Step 1: Try to use below config.
  
  #### Config:
  ```
      from_deluge:
        host: '{? deluge.host ?}'
        port: '{? deluge.port ?}'
  
  ```
    
  #### Log:
  See above.
  
  ### Additional information:
  
  - Flexget Version: 2.10.24
  - Python Version: 2.7.9
  - Installation method: pip
  - OS and version: macOS El Capitan 10.11.6
  - Link to crash log: n/a
  
  </issue>
  <code>
  [start of flexget/plugins/modify/variables.py]
  1 from __future__ import unicode_literals, division, absolute_import
  2 from builtins import *  # noqa pylint: disable=unused-import, redefined-builtin
  3 
  4 import codecs
  5 import logging
  6 import os
  7 from datetime import datetime
  8 
  9 import yaml
  10 
  11 from jinja2 import Environment, TemplateError
  12 
  13 from sqlalchemy import Column
  14 from sqlalchemy.sql.sqltypes import Unicode, DateTime, Integer
  15 
  16 from flexget import db_schema
  17 from flexget.config_schema import register_config_key
  18 from flexget.event import event
  19 from flexget.manager import Session
  20 from flexget.plugin import PluginError
  21 from flexget.utils.database import json_synonym
  22 
  23 log = logging.getLogger('variables')
  24 
  25 DB_VERSION = 0
  26 Base = db_schema.versioned_base('variables', DB_VERSION)
  27 
  28 
  29 class Variables(Base):
  30     __tablename__ = 'variables'
  31 
  32     id = Column(Integer, primary_key=True)
  33     _variables = Column('variables', Unicode)
  34     variables = json_synonym('_variables')
  35     added = Column(DateTime, default=datetime.now)
  36 
  37 
  38 def variables_from_file(config_base, filename):
  39     variables_file = os.path.join(config_base, filename)
  40     if not os.path.exists(variables_file):
  41         raise PluginError('File %s does not exist!' % variables_file)
  42     try:
  43         with codecs.open(variables_file, 'rb', 'utf-8') as f:
  44             variables_dict = yaml.safe_load(f.read())
  45     except yaml.YAMLError as e:
  46         raise PluginError('Invalid variables file: %s' % e)
  47     return variables_dict or {}
  48 
  49 
  50 def variables_from_db():
  51     with Session() as session:
  52         variables = session.query(Variables).first()
  53         if variables:
  54             return variables.variables
  55         else:
  56             return {}
  57 
  58 
  59 def variables_to_db(variables_dict):
  60     with Session() as session:
  61         variables = session.query(Variables).first()
  62         if not variables:
  63             variables = Variables()
  64         variables.variables = variables_dict
  65         session.merge(variables)
  66 
  67 
  68 @event('manager.before_config_validate')
  69 def process_variables(config, manager):
  70     """Render all string elements of the config against defined variables."""
  71     env_params = {
  72         'block_start_string': '^^disabled^^',
  73         'block_end_string': '^^disabled^^',
  74         'variable_start_string': '{?',
  75         'variable_end_string': '?}'
  76     }
  77     if 'variables' not in config or config.get('variables') is False:
  78         return
  79     env = Environment(**env_params)
  80     if isinstance(config['variables'], bool):
  81         log.debug('trying to load variables from DB')
  82         variables = variables_from_db()
  83     else:
  84         log.debug('trying to load variables from file')
  85         variables = variables_from_file(manager.config_base, config['variables'])
  86         log.debug('updating DB with variable file contents')
  87         variables_to_db(variables)
  88     env.globals = variables
  89     _process(config, env)
  90     return config
  91 
  92 
  93 def _process(element, environment):
  94     if isinstance(element, dict):
  95         for k, v in element.items():
  96             new_key = _process(k, environment)
  97             if new_key:
  98                 element[new_key] = element.pop(k)
  99                 k = new_key
  100             val = _process(element[k], environment)
  101             if val:
  102                 element[k] = val
  103     elif isinstance(element, list):
  104         for i, v in enumerate(element):
  105             val = _process(v, environment)
  106             if val:
  107                 element[i] = val
  108     elif isinstance(element, str) and '{?' in element:
  109         try:
  110             template = environment.from_string(element)
  111             return template.render()
  112         except (TemplateError, TypeError):
  113             return None
  114 
  115 
  116 variables_config_schema = {'type': ['string', 'boolean']}
  117 
  118 
  119 @event('config.register')
  120 def register_config():
  121     register_config_key('variables', variables_config_schema)
  122
  [end of flexget/plugins/modify/variables.py]
  [start of flexget/_version.py]
  1 """
  2 Current FlexGet version.
  3 This is contained in a separate file so that it can be easily read by setup.py, and easily edited and committed by
  4 release scripts in continuous integration. Should (almost) never be set manually.
  5 
  6 The version should always be set to the <next release version>.dev
  7 The jenkins release job will automatically strip the .dev for release,
  8 and update the version again for continued development.
  9 """
  10 __version__ = '2.15.2.dev'
  11
  [end of flexget/_version.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/flexget/_version.py b/flexget/_version.py
  --- a/flexget/_version.py
  +++ b/flexget/_version.py
  @@ -7,4 +7,4 @@
   The jenkins release job will automatically strip the .dev for release,
   and update the version again for continued development.
   """
  -__version__ = '2.15.2.dev'
  +__version__ = '2.16.0.dev'
  diff --git a/flexget/plugins/modify/variables.py b/flexget/plugins/modify/variables.py
  --- a/flexget/plugins/modify/variables.py
  +++ b/flexget/plugins/modify/variables.py
  @@ -8,7 +8,8 @@
   
   import yaml
   
  -from jinja2 import Environment, TemplateError
  +from jinja2 import TemplateError
  +from jinja2.nativetypes import NativeEnvironment
   
   from sqlalchemy import Column
   from sqlalchemy.sql.sqltypes import Unicode, DateTime, Integer
  @@ -76,10 +77,13 @@
       }
       if 'variables' not in config or config.get('variables') is False:
           return
  -    env = Environment(**env_params)
  +    env = NativeEnvironment(**env_params)
       if isinstance(config['variables'], bool):
           log.debug('trying to load variables from DB')
           variables = variables_from_db()
  +    elif isinstance(config['variables'], dict):
  +        log.debug('loading variables from config')
  +        variables = config['variables']
       else:
           log.debug('trying to load variables from file')
           variables = variables_from_file(manager.config_base, config['variables'])
  @@ -113,7 +117,7 @@
               return None
   
   
  -variables_config_schema = {'type': ['string', 'boolean']}
  +variables_config_schema = {'type': ['string', 'boolean', 'object']}
   
   
   @event('config.register')
  
verification_info: {"golden_diff": "diff --git a/flexget/_version.py b/flexget/_version.py\n--- a/flexget/_version.py\n+++ b/flexget/_version.py\n@@ -7,4 +7,4 @@\n The jenkins release job will automatically strip the .dev for release,\n and update the version again for continued development.\n \"\"\"\n-__version__ = '2.15.2.dev'\n+__version__ = '2.16.0.dev'\ndiff --git a/flexget/plugins/modify/variables.py b/flexget/plugins/modify/variables.py\n--- a/flexget/plugins/modify/variables.py\n+++ b/flexget/plugins/modify/variables.py\n@@ -8,7 +8,8 @@\n \n import yaml\n \n-from jinja2 import Environment, TemplateError\n+from jinja2 import TemplateError\n+from jinja2.nativetypes import NativeEnvironment\n \n from sqlalchemy import Column\n from sqlalchemy.sql.sqltypes import Unicode, DateTime, Integer\n@@ -76,10 +77,13 @@\n     }\n     if 'variables' not in config or config.get('variables') is False:\n         return\n-    env = Environment(**env_params)\n+    env = NativeEnvironment(**env_params)\n     if isinstance(config['variables'], bool):\n         log.debug('trying to load variables from DB')\n         variables = variables_from_db()\n+    elif isinstance(config['variables'], dict):\n+        log.debug('loading variables from config')\n+        variables = config['variables']\n     else:\n         log.debug('trying to load variables from file')\n         variables = variables_from_file(manager.config_base, config['variables'])\n@@ -113,7 +117,7 @@\n             return None\n \n \n-variables_config_schema = {'type': ['string', 'boolean']}\n+variables_config_schema = {'type': ['string', 'boolean', 'object']}\n \n \n @event('config.register')\n", "issue": "Cannot use variables with integer-only values\n### Expected behaviour:\r\nVariables should be able to handle integer-only values.\r\n\r\n### Actual behaviour:\r\nConfiguration parsing error (when using ``'{? deluge.port ?}'``): ``Got `50586`, expected: integer``\r\nConfiguration parsing error (when using ``{? deluge.port ?}``):\r\n```\r\nwhile parsing a flow mapping in \"<unicode string>\", line 16, column 13: port: {? deluge.port ?} ^ expected ',' or '}', but got '?' in \"<unicode string>\", line 16, column 28: port: {? deluge.port ?} ^\r\n```\r\n\r\n### Steps to reproduce:\r\n- Step 1: Try to use below config.\r\n\r\n#### Config:\r\n```\r\n    from_deluge:\r\n      host: '{? deluge.host ?}'\r\n      port: '{? deluge.port ?}'\r\n\r\n```\r\n  \r\n#### Log:\r\nSee above.\r\n\r\n### Additional information:\r\n\r\n- Flexget Version: 2.10.24\r\n- Python Version: 2.7.9\r\n- Installation method: pip\r\n- OS and version: macOS El Capitan 10.11.6\r\n- Link to crash log: n/a\n", "before_files": [{"content": "from __future__ import unicode_literals, division, absolute_import\nfrom builtins import *  # noqa pylint: disable=unused-import, redefined-builtin\n\nimport codecs\nimport logging\nimport os\nfrom datetime import datetime\n\nimport yaml\n\nfrom jinja2 import Environment, TemplateError\n\nfrom sqlalchemy import Column\nfrom sqlalchemy.sql.sqltypes import Unicode, DateTime, Integer\n\nfrom flexget import db_schema\nfrom flexget.config_schema import register_config_key\nfrom flexget.event import event\nfrom flexget.manager import Session\nfrom flexget.plugin import PluginError\nfrom flexget.utils.database import json_synonym\n\nlog = logging.getLogger('variables')\n\nDB_VERSION = 0\nBase = db_schema.versioned_base('variables', DB_VERSION)\n\n\nclass Variables(Base):\n    __tablename__ = 'variables'\n\n    id = Column(Integer, primary_key=True)\n    _variables = Column('variables', Unicode)\n    variables = json_synonym('_variables')\n    added = Column(DateTime, default=datetime.now)\n\n\ndef variables_from_file(config_base, filename):\n    variables_file = os.path.join(config_base, filename)\n    if not os.path.exists(variables_file):\n        raise PluginError('File %s does not exist!' % variables_file)\n    try:\n        with codecs.open(variables_file, 'rb', 'utf-8') as f:\n            variables_dict = yaml.safe_load(f.read())\n    except yaml.YAMLError as e:\n        raise PluginError('Invalid variables file: %s' % e)\n    return variables_dict or {}\n\n\ndef variables_from_db():\n    with Session() as session:\n        variables = session.query(Variables).first()\n        if variables:\n            return variables.variables\n        else:\n            return {}\n\n\ndef variables_to_db(variables_dict):\n    with Session() as session:\n        variables = session.query(Variables).first()\n        if not variables:\n            variables = Variables()\n        variables.variables = variables_dict\n        session.merge(variables)\n\n\n@event('manager.before_config_validate')\ndef process_variables(config, manager):\n    \"\"\"Render all string elements of the config against defined variables.\"\"\"\n    env_params = {\n        'block_start_string': '^^disabled^^',\n        'block_end_string': '^^disabled^^',\n        'variable_start_string': '{?',\n        'variable_end_string': '?}'\n    }\n    if 'variables' not in config or config.get('variables') is False:\n        return\n    env = Environment(**env_params)\n    if isinstance(config['variables'], bool):\n        log.debug('trying to load variables from DB')\n        variables = variables_from_db()\n    else:\n        log.debug('trying to load variables from file')\n        variables = variables_from_file(manager.config_base, config['variables'])\n        log.debug('updating DB with variable file contents')\n        variables_to_db(variables)\n    env.globals = variables\n    _process(config, env)\n    return config\n\n\ndef _process(element, environment):\n    if isinstance(element, dict):\n        for k, v in element.items():\n            new_key = _process(k, environment)\n            if new_key:\n                element[new_key] = element.pop(k)\n                k = new_key\n            val = _process(element[k], environment)\n            if val:\n                element[k] = val\n    elif isinstance(element, list):\n        for i, v in enumerate(element):\n            val = _process(v, environment)\n            if val:\n                element[i] = val\n    elif isinstance(element, str) and '{?' in element:\n        try:\n            template = environment.from_string(element)\n            return template.render()\n        except (TemplateError, TypeError):\n            return None\n\n\nvariables_config_schema = {'type': ['string', 'boolean']}\n\n\n@event('config.register')\ndef register_config():\n    register_config_key('variables', variables_config_schema)\n", "path": "flexget/plugins/modify/variables.py"}, {"content": "\"\"\"\nCurrent FlexGet version.\nThis is contained in a separate file so that it can be easily read by setup.py, and easily edited and committed by\nrelease scripts in continuous integration. Should (almost) never be set manually.\n\nThe version should always be set to the <next release version>.dev\nThe jenkins release job will automatically strip the .dev for release,\nand update the version again for continued development.\n\"\"\"\n__version__ = '2.15.2.dev'\n", "path": "flexget/_version.py"}]}