prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Extract meta failure on missing props docstring.
  If a props is missing a docstring, it will fail to generate the component with js error, `Cannot read property 'length' of undefined`.
  
  https://community.plot.ly/t/dash-component-creation-javascript-ok-nothing-rendered-in-python/19369
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `dash/development/component_generator.py`
  Content:
  ```
  1 from __future__ import print_function
  2 from collections import OrderedDict
  3 
  4 import json
  5 import sys
  6 import subprocess
  7 import shlex
  8 import os
  9 import argparse
  10 import shutil
  11 import functools
  12 
  13 import pkg_resources
  14 
  15 from ._r_components_generation import write_class_file
  16 from ._r_components_generation import generate_exports
  17 from ._py_components_generation import generate_class_file
  18 from ._py_components_generation import generate_imports
  19 from ._py_components_generation import generate_classes_files
  20 
  21 
  22 class _CombinedFormatter(argparse.ArgumentDefaultsHelpFormatter,
  23                          argparse.RawDescriptionHelpFormatter):
  24     pass
  25 
  26 
  27 # pylint: disable=too-many-locals
  28 def generate_components(components_source, project_shortname,
  29                         package_info_filename='package.json',
  30                         ignore='^_',
  31                         rprefix=None):
  32 
  33     project_shortname = project_shortname.replace('-', '_').rstrip('/\\')
  34 
  35     if rprefix:
  36         prefix = rprefix
  37 
  38     is_windows = sys.platform == 'win32'
  39 
  40     extract_path = pkg_resources.resource_filename('dash', 'extract-meta.js')
  41 
  42     os.environ['NODE_PATH'] = 'node_modules'
  43     cmd = shlex.split(
  44         'node {} {} {}'.format(extract_path, ignore, components_source),
  45         posix=not is_windows
  46     )
  47 
  48     shutil.copyfile('package.json',
  49                     os.path.join(project_shortname, package_info_filename))
  50 
  51     proc = subprocess.Popen(cmd,
  52                             stdout=subprocess.PIPE,
  53                             stderr=subprocess.PIPE,
  54                             shell=is_windows)
  55     out, err = proc.communicate()
  56     status = proc.poll()
  57 
  58     if err:
  59         print(err.decode(), file=sys.stderr)
  60 
  61     if not out:
  62         print(
  63             'Error generating metadata in {} (status={})'.format(
  64                 project_shortname, status),
  65             file=sys.stderr)
  66         sys.exit(1)
  67 
  68     jsondata_unicode = json.loads(out.decode(), object_pairs_hook=OrderedDict)
  69 
  70     if sys.version_info[0] >= 3:
  71         metadata = jsondata_unicode
  72     else:
  73         metadata = byteify(jsondata_unicode)
  74 
  75     generator_methods = [generate_class_file]
  76 
  77     if rprefix:
  78         if not os.path.exists('man'):
  79             os.makedirs('man')
  80         if not os.path.exists('R'):
  81             os.makedirs('R')
  82         generator_methods.append(
  83             functools.partial(write_class_file, prefix=prefix))
  84 
  85     components = generate_classes_files(
  86         project_shortname,
  87         metadata,
  88         *generator_methods
  89     )
  90 
  91     with open(os.path.join(project_shortname, 'metadata.json'), 'w') as f:
  92         json.dump(metadata, f)
  93 
  94     generate_imports(project_shortname, components)
  95 
  96     if rprefix:
  97         with open('package.json', 'r') as f:
  98             jsondata_unicode = json.load(f, object_pairs_hook=OrderedDict)
  99             if sys.version_info[0] >= 3:
  100                 pkg_data = jsondata_unicode
  101             else:
  102                 pkg_data = byteify(jsondata_unicode)
  103 
  104         generate_exports(
  105             project_shortname, components, metadata, pkg_data, prefix
  106         )
  107 
  108 
  109 def cli():
  110     parser = argparse.ArgumentParser(
  111         prog='dash-generate-components',
  112         formatter_class=_CombinedFormatter,
  113         description='Generate dash components by extracting the metadata '
  114         'using react-docgen. Then map the metadata to python classes.'
  115     )
  116     parser.add_argument('components_source',
  117                         help='React components source directory.')
  118     parser.add_argument(
  119         'project_shortname',
  120         help='Name of the project to export the classes files.'
  121     )
  122     parser.add_argument(
  123         '-p', '--package-info-filename',
  124         default='package.json',
  125         help='The filename of the copied `package.json` to `project_shortname`'
  126     )
  127     parser.add_argument(
  128         '-i', '--ignore',
  129         default='^_',
  130         help='Files/directories matching the pattern will be ignored'
  131     )
  132     parser.add_argument(
  133         '--r-prefix',
  134         help='Experimental: specify a prefix for DashR component names, write'
  135              'DashR components to R dir, create R package.'
  136     )
  137 
  138     args = parser.parse_args()
  139     generate_components(
  140         args.components_source, args.project_shortname,
  141         package_info_filename=args.package_info_filename,
  142         ignore=args.ignore,
  143         rprefix=args.r_prefix)
  144 
  145 
  146 # pylint: disable=undefined-variable
  147 def byteify(input_object):
  148     if isinstance(input_object, dict):
  149         return OrderedDict([
  150             (byteify(key), byteify(value))
  151             for key, value in input_object.iteritems()
  152         ])
  153     elif isinstance(input_object, list):
  154         return [byteify(element) for element in input_object]
  155     elif isinstance(input_object, unicode):  # noqa:F821
  156         return input_object.encode('utf-8')
  157     return input_object
  158 
  159 
  160 if __name__ == '__main__':
  161     cli()
  162
  ```
  --- 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()
  
  ```
  
golden_diff: diff --git a/dash/development/component_generator.py b/dash/development/component_generator.py
  --- a/dash/development/component_generator.py
  +++ b/dash/development/component_generator.py
  @@ -89,7 +89,7 @@
       )
   
       with open(os.path.join(project_shortname, 'metadata.json'), 'w') as f:
  -        json.dump(metadata, f)
  +        json.dump(metadata, f, indent=2)
   
       generate_imports(project_shortname, components)
  
verification_info: {"golden_diff": "diff --git a/dash/development/component_generator.py b/dash/development/component_generator.py\n--- a/dash/development/component_generator.py\n+++ b/dash/development/component_generator.py\n@@ -89,7 +89,7 @@\n     )\n \n     with open(os.path.join(project_shortname, 'metadata.json'), 'w') as f:\n-        json.dump(metadata, f)\n+        json.dump(metadata, f, indent=2)\n \n     generate_imports(project_shortname, components)\n", "issue": "Extract meta failure on missing props docstring.\nIf a props is missing a docstring, it will fail to generate the component with js error, `Cannot read property 'length' of undefined`.\r\n\r\nhttps://community.plot.ly/t/dash-component-creation-javascript-ok-nothing-rendered-in-python/19369\n", "before_files": [{"content": "from __future__ import print_function\nfrom collections import OrderedDict\n\nimport json\nimport sys\nimport subprocess\nimport shlex\nimport os\nimport argparse\nimport shutil\nimport functools\n\nimport pkg_resources\n\nfrom ._r_components_generation import write_class_file\nfrom ._r_components_generation import generate_exports\nfrom ._py_components_generation import generate_class_file\nfrom ._py_components_generation import generate_imports\nfrom ._py_components_generation import generate_classes_files\n\n\nclass _CombinedFormatter(argparse.ArgumentDefaultsHelpFormatter,\n                         argparse.RawDescriptionHelpFormatter):\n    pass\n\n\n# pylint: disable=too-many-locals\ndef generate_components(components_source, project_shortname,\n                        package_info_filename='package.json',\n                        ignore='^_',\n                        rprefix=None):\n\n    project_shortname = project_shortname.replace('-', '_').rstrip('/\\\\')\n\n    if rprefix:\n        prefix = rprefix\n\n    is_windows = sys.platform == 'win32'\n\n    extract_path = pkg_resources.resource_filename('dash', 'extract-meta.js')\n\n    os.environ['NODE_PATH'] = 'node_modules'\n    cmd = shlex.split(\n        'node {} {} {}'.format(extract_path, ignore, components_source),\n        posix=not is_windows\n    )\n\n    shutil.copyfile('package.json',\n                    os.path.join(project_shortname, package_info_filename))\n\n    proc = subprocess.Popen(cmd,\n                            stdout=subprocess.PIPE,\n                            stderr=subprocess.PIPE,\n                            shell=is_windows)\n    out, err = proc.communicate()\n    status = proc.poll()\n\n    if err:\n        print(err.decode(), file=sys.stderr)\n\n    if not out:\n        print(\n            'Error generating metadata in {} (status={})'.format(\n                project_shortname, status),\n            file=sys.stderr)\n        sys.exit(1)\n\n    jsondata_unicode = json.loads(out.decode(), object_pairs_hook=OrderedDict)\n\n    if sys.version_info[0] >= 3:\n        metadata = jsondata_unicode\n    else:\n        metadata = byteify(jsondata_unicode)\n\n    generator_methods = [generate_class_file]\n\n    if rprefix:\n        if not os.path.exists('man'):\n            os.makedirs('man')\n        if not os.path.exists('R'):\n            os.makedirs('R')\n        generator_methods.append(\n            functools.partial(write_class_file, prefix=prefix))\n\n    components = generate_classes_files(\n        project_shortname,\n        metadata,\n        *generator_methods\n    )\n\n    with open(os.path.join(project_shortname, 'metadata.json'), 'w') as f:\n        json.dump(metadata, f)\n\n    generate_imports(project_shortname, components)\n\n    if rprefix:\n        with open('package.json', 'r') as f:\n            jsondata_unicode = json.load(f, object_pairs_hook=OrderedDict)\n            if sys.version_info[0] >= 3:\n                pkg_data = jsondata_unicode\n            else:\n                pkg_data = byteify(jsondata_unicode)\n\n        generate_exports(\n            project_shortname, components, metadata, pkg_data, prefix\n        )\n\n\ndef cli():\n    parser = argparse.ArgumentParser(\n        prog='dash-generate-components',\n        formatter_class=_CombinedFormatter,\n        description='Generate dash components by extracting the metadata '\n        'using react-docgen. Then map the metadata to python classes.'\n    )\n    parser.add_argument('components_source',\n                        help='React components source directory.')\n    parser.add_argument(\n        'project_shortname',\n        help='Name of the project to export the classes files.'\n    )\n    parser.add_argument(\n        '-p', '--package-info-filename',\n        default='package.json',\n        help='The filename of the copied `package.json` to `project_shortname`'\n    )\n    parser.add_argument(\n        '-i', '--ignore',\n        default='^_',\n        help='Files/directories matching the pattern will be ignored'\n    )\n    parser.add_argument(\n        '--r-prefix',\n        help='Experimental: specify a prefix for DashR component names, write'\n             'DashR components to R dir, create R package.'\n    )\n\n    args = parser.parse_args()\n    generate_components(\n        args.components_source, args.project_shortname,\n        package_info_filename=args.package_info_filename,\n        ignore=args.ignore,\n        rprefix=args.r_prefix)\n\n\n# pylint: disable=undefined-variable\ndef byteify(input_object):\n    if isinstance(input_object, dict):\n        return OrderedDict([\n            (byteify(key), byteify(value))\n            for key, value in input_object.iteritems()\n        ])\n    elif isinstance(input_object, list):\n        return [byteify(element) for element in input_object]\n    elif isinstance(input_object, unicode):  # noqa:F821\n        return input_object.encode('utf-8')\n    return input_object\n\n\nif __name__ == '__main__':\n    cli()\n", "path": "dash/development/component_generator.py"}], "after_files": [{"content": "from __future__ import print_function\nfrom collections import OrderedDict\n\nimport json\nimport sys\nimport subprocess\nimport shlex\nimport os\nimport argparse\nimport shutil\nimport functools\n\nimport pkg_resources\n\nfrom ._r_components_generation import write_class_file\nfrom ._r_components_generation import generate_exports\nfrom ._py_components_generation import generate_class_file\nfrom ._py_components_generation import generate_imports\nfrom ._py_components_generation import generate_classes_files\n\n\nclass _CombinedFormatter(argparse.ArgumentDefaultsHelpFormatter,\n                         argparse.RawDescriptionHelpFormatter):\n    pass\n\n\n# pylint: disable=too-many-locals\ndef generate_components(components_source, project_shortname,\n                        package_info_filename='package.json',\n                        ignore='^_',\n                        rprefix=None):\n\n    project_shortname = project_shortname.replace('-', '_').rstrip('/\\\\')\n\n    if rprefix:\n        prefix = rprefix\n\n    is_windows = sys.platform == 'win32'\n\n    extract_path = pkg_resources.resource_filename('dash', 'extract-meta.js')\n\n    os.environ['NODE_PATH'] = 'node_modules'\n    cmd = shlex.split(\n        'node {} {} {}'.format(extract_path, ignore, components_source),\n        posix=not is_windows\n    )\n\n    shutil.copyfile('package.json',\n                    os.path.join(project_shortname, package_info_filename))\n\n    proc = subprocess.Popen(cmd,\n                            stdout=subprocess.PIPE,\n                            stderr=subprocess.PIPE,\n                            shell=is_windows)\n    out, err = proc.communicate()\n    status = proc.poll()\n\n    if err:\n        print(err.decode(), file=sys.stderr)\n\n    if not out:\n        print(\n            'Error generating metadata in {} (status={})'.format(\n                project_shortname, status),\n            file=sys.stderr)\n        sys.exit(1)\n\n    jsondata_unicode = json.loads(out.decode(), object_pairs_hook=OrderedDict)\n\n    if sys.version_info[0] >= 3:\n        metadata = jsondata_unicode\n    else:\n        metadata = byteify(jsondata_unicode)\n\n    generator_methods = [generate_class_file]\n\n    if rprefix:\n        if not os.path.exists('man'):\n            os.makedirs('man')\n        if not os.path.exists('R'):\n            os.makedirs('R')\n        generator_methods.append(\n            functools.partial(write_class_file, prefix=prefix))\n\n    components = generate_classes_files(\n        project_shortname,\n        metadata,\n        *generator_methods\n    )\n\n    with open(os.path.join(project_shortname, 'metadata.json'), 'w') as f:\n        json.dump(metadata, f, indent=2)\n\n    generate_imports(project_shortname, components)\n\n    if rprefix:\n        with open('package.json', 'r') as f:\n            jsondata_unicode = json.load(f, object_pairs_hook=OrderedDict)\n            if sys.version_info[0] >= 3:\n                pkg_data = jsondata_unicode\n            else:\n                pkg_data = byteify(jsondata_unicode)\n\n        generate_exports(\n            project_shortname, components, metadata, pkg_data, prefix\n        )\n\n\ndef cli():\n    parser = argparse.ArgumentParser(\n        prog='dash-generate-components',\n        formatter_class=_CombinedFormatter,\n        description='Generate dash components by extracting the metadata '\n        'using react-docgen. Then map the metadata to python classes.'\n    )\n    parser.add_argument('components_source',\n                        help='React components source directory.')\n    parser.add_argument(\n        'project_shortname',\n        help='Name of the project to export the classes files.'\n    )\n    parser.add_argument(\n        '-p', '--package-info-filename',\n        default='package.json',\n        help='The filename of the copied `package.json` to `project_shortname`'\n    )\n    parser.add_argument(\n        '-i', '--ignore',\n        default='^_',\n        help='Files/directories matching the pattern will be ignored'\n    )\n    parser.add_argument(\n        '--r-prefix',\n        help='Experimental: specify a prefix for DashR component names, write'\n             'DashR components to R dir, create R package.'\n    )\n\n    args = parser.parse_args()\n    generate_components(\n        args.components_source, args.project_shortname,\n        package_info_filename=args.package_info_filename,\n        ignore=args.ignore,\n        rprefix=args.r_prefix)\n\n\n# pylint: disable=undefined-variable\ndef byteify(input_object):\n    if isinstance(input_object, dict):\n        return OrderedDict([\n            (byteify(key), byteify(value))\n            for key, value in input_object.iteritems()\n        ])\n    elif isinstance(input_object, list):\n        return [byteify(element) for element in input_object]\n    elif isinstance(input_object, unicode):  # noqa:F821\n        return input_object.encode('utf-8')\n    return input_object\n\n\nif __name__ == '__main__':\n    cli()\n", "path": "dash/development/component_generator.py"}]}