We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
c7n mailer dependency has a high vulnerability
### Describe the bug

c7n mailer depends on starkbank-ecdsa==1.1.1

This library at this version has been found to have a high vulnerability.

https://github.com/advisories/GHSA-9wx7-jrvc-28mm

The version has been fixed in version 2.0.1


### What did you expect to happen?

No vulnerabilities found in dependency libraries

### Cloud Provider

Amazon Web Services (AWS)

### Cloud Custodian version and dependency information

```shell
Custodian:   0.9.13
Python:      3.9.7 (default, Sep  1 2021, 14:45:30)
             [GCC 10.3.1 20210424]
Platform:    posix.uname_result(sysname='Linux', nodename='b82f5787903f', release='5.11.0-1016-aws', version='#17~20.04.1-Ubuntu SMP Thu Aug 12 05:39:36 UTC 2021', machine='x86_64')
Using venv:  False
Docker: True
Installed:

argcomplete==1.12.3
attrs==21.2.0
boto3==1.17.102
botocore==1.20.102
importlib-metadata==4.6.0
jmespath==0.10.0
jsonschema==3.2.0
pyrsistent==0.18.0
python-dateutil==2.8.1
pyyaml==5.4.1
s3transfer==0.4.2
setuptools==57.4.0
six==1.16.0
tabulate==0.8.9
typing-extensions==3.10.0.0
urllib3==1.26.6
zipp==3.4.1
```


### Policy

_No response_

### Relevant log/traceback output

```shell
Trivy output:


Python (python-pkg)
===================
Total: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)
+-----------------+---------------------+----------+-------------------+---------------+----------------------------------------------+
|     LIBRARY     |  VULNERABILITY ID   | SEVERITY | INSTALLED VERSION | FIXED VERSION |                    TITLE                     |
+-----------------+---------------------+----------+-------------------+---------------+----------------------------------------------+
| starkbank-ecdsa | GHSA-9wx7-jrvc-28mm | HIGH     | 1.1.1             | 2.0.1         | Signature verification vulnerability         |
|                 |                     |          |                   |               | in Stark Bank ecdsa libraries                |
|                 |                     |          |                   |               | -->github.com/advisories/GHSA-9wx7-jrvc-28mm |
+-----------------+---------------------+----------+-------------------+---------------+----------------------------------------------+
```
```


### Extra information or context

_No response_

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tools/dev/poetrypkg.py`
Content:
```
1 # Copyright The Cloud Custodian Authors.
2 # SPDX-License-Identifier: Apache-2.0
3 """
4 Supplemental tooling for managing custodian packaging.
5 
6 Has various workarounds for poetry
7 """
8 from collections import defaultdict
9 import click
10 import os
11 import sys
12 import toml
13 from pathlib import Path
14 
15 
16 @click.group()
17 def cli():
18     """Custodian Python Packaging Utility
19 
20     some simple tooling to sync poetry files to setup/pip
21     """
22     # If there is a global installation of poetry, prefer that.
23     poetry_python_lib = Path(os.path.expanduser('~/.poetry/lib'))
24     if poetry_python_lib.exists():
25         sys.path.insert(0, os.path.realpath(poetry_python_lib))
26         # poetry env vendored deps
27         sys.path.insert(
28             0,
29             os.path.join(poetry_python_lib, 'poetry', '_vendor', 'py{}.{}'.format(
30                 sys.version_info.major, sys.version_info.minor)))
31 
32     # If there is a global installation of poetry, prefer that.
33     cur_poetry_python_lib = Path(os.path.expanduser('~/.local/share/pypoetry/venv/lib'))
34     if cur_poetry_python_lib.exists():
35         sys.path.insert(
36             0,
37             str(list(cur_poetry_python_lib.glob('*'))[0] / "site-packages"))
38 
39 
40 # Override the poetry base template as all our readmes files
41 # are in markdown format.
42 #
43 # Pull request submitted upstream to correctly autodetect
44 # https://github.com/python-poetry/poetry/pull/1994
45 #
46 SETUP_TEMPLATE = """\
47 # -*- coding: utf-8 -*-
48 from setuptools import setup
49 
50 {before}
51 setup_kwargs = {{
52     'name': {name!r},
53     'version': {version!r},
54     'description': {description!r},
55     'license': 'Apache-2.0',
56     'classifiers': [
57         'License :: OSI Approved :: Apache Software License',
58         'Topic :: System :: Systems Administration',
59         'Topic :: System :: Distributed Computing'
60     ],
61     'long_description': {long_description!r},
62     'long_description_content_type': 'text/markdown',
63     'author': {author!r},
64     'author_email': {author_email!r},
65     'maintainer': {maintainer!r},
66     'maintainer_email': {maintainer_email!r},
67     'url': {url!r},
68     {extra}
69 }}
70 {after}
71 
72 setup(**setup_kwargs)
73 """
74 
75 
76 @cli.command()
77 @click.option('-p', '--package-dir', type=click.Path())
78 @click.option('-f', '--version-file', type=click.Path())
79 def gen_version_file(package_dir, version_file):
80     data = toml.load(Path(str(package_dir)) / 'pyproject.toml')
81     version = data['tool']['poetry']['version']
82     with open(version_file, 'w') as fh:
83         fh.write('# Generated via tools/dev/poetrypkg.py\n')
84         fh.write('version = "{}"\n'.format(version))
85 
86 
87 @cli.command()
88 @click.option('-p', '--package-dir', type=click.Path())
89 def gen_setup(package_dir):
90     """Generate a setup suitable for dev compatibility with pip.
91     """
92     from poetry.core.masonry.builders import sdist
93     from poetry.factory import Factory
94 
95     factory = Factory()
96     poetry = factory.create_poetry(package_dir)
97 
98     # the alternative to monkey patching is carrying forward a
99     # 100 line method. See SETUP_TEMPLATE comments above.
100     sdist.SETUP = SETUP_TEMPLATE
101 
102     class SourceDevBuilder(sdist.SdistBuilder):
103         # to enable poetry with a monorepo, we have internal deps
104         # as source path dev dependencies, when we go to generate
105         # setup.py we need to ensure that the source deps are
106         # recorded faithfully.
107 
108         @classmethod
109         def convert_dependencies(cls, package, dependencies):
110             reqs, default = super().convert_dependencies(package, dependencies)
111             resolve_source_deps(poetry, package, reqs)
112             return reqs, default
113 
114     builder = SourceDevBuilder(poetry, None, None)
115     setup_content = builder.build_setup()
116 
117     with open(os.path.join(package_dir, 'setup.py'), 'wb') as fh:
118         fh.write(b'# Automatically generated from poetry/pyproject.toml\n')
119         fh.write(b'# flake8: noqa\n')
120         fh.write(setup_content)
121 
122 
123 @cli.command()
124 @click.option('-p', '--package-dir', type=click.Path())
125 @click.option('-o', '--output', default='setup.py')
126 def gen_frozensetup(package_dir, output):
127     """Generate a frozen setup suitable for distribution.
128     """
129     from poetry.core.masonry.builders import sdist
130     from poetry.factory import Factory
131 
132     factory = Factory()
133     poetry = factory.create_poetry(package_dir)
134 
135     sdist.SETUP = SETUP_TEMPLATE
136 
137     class FrozenBuilder(sdist.SdistBuilder):
138 
139         @classmethod
140         def convert_dependencies(cls, package, dependencies):
141             reqs, default = locked_deps(package, poetry)
142             resolve_source_deps(poetry, package, reqs, frozen=True)
143             return reqs, default
144 
145     builder = FrozenBuilder(poetry, None, None)
146     setup_content = builder.build_setup()
147 
148     with open(os.path.join(package_dir, output), 'wb') as fh:
149         fh.write(b'# Automatically generated from pyproject.toml\n')
150         fh.write(b'# flake8: noqa\n')
151         fh.write(setup_content)
152 
153 
154 def resolve_source_deps(poetry, package, reqs, frozen=False):
155     # find any source path dev deps and them and their recursive
156     # deps to reqs
157     if poetry.local_config['name'] not in (package.name, package.pretty_name):
158         return
159 
160     source_deps = []
161     for dep_name, info in poetry.local_config.get('dev-dependencies', {}).items():
162         if isinstance(info, dict) and 'path' in info:
163             source_deps.append(dep_name)
164     if not source_deps:
165         return
166 
167     from poetry.core.packages.dependency import Dependency
168 
169     dep_map = {d['name']: d for d in poetry.locker.lock_data['package']}
170     seen = set(source_deps)
171     seen.add('setuptools')
172 
173     prefix = '' if frozen else '^'
174     while source_deps:
175         dep = source_deps.pop()
176         if dep not in dep_map:
177             dep = dep.replace('_', '-')
178         version = dep_map[dep]['version']
179         reqs.append(Dependency(dep, '{}{}'.format(prefix, version)).to_pep_508())
180         for cdep, cversion in dep_map[dep].get('dependencies', {}).items():
181             if cdep in seen:
182                 continue
183             source_deps.append(cdep)
184             seen.add(cdep)
185 
186 
187 def locked_deps(package, poetry):
188     reqs = []
189     packages = poetry.locker.locked_repository(False).packages
190     for p in packages:
191         dep = p.to_dependency()
192         line = "{}=={}".format(p.name, p.version)
193         requirement = dep.to_pep_508()
194         if ';' in requirement:
195             line += "; {}".format(requirement.split(";")[1].strip())
196         reqs.append(line)
197     return reqs, defaultdict(list)
198 
199 
200 if __name__ == '__main__':
201     cli()
202
```
--- 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/tools/dev/poetrypkg.py b/tools/dev/poetrypkg.py
--- a/tools/dev/poetrypkg.py
+++ b/tools/dev/poetrypkg.py
@@ -123,7 +123,9 @@
 @cli.command()
 @click.option('-p', '--package-dir', type=click.Path())
 @click.option('-o', '--output', default='setup.py')
-def gen_frozensetup(package_dir, output):
+@click.option('-x', '--exclude', multiple=True)
+@click.option('-r', '--remove', multiple=True)
+def gen_frozensetup(package_dir, output, exclude, remove):
     """Generate a frozen setup suitable for distribution.
     """
     from poetry.core.masonry.builders import sdist
@@ -138,7 +140,7 @@
 
         @classmethod
         def convert_dependencies(cls, package, dependencies):
-            reqs, default = locked_deps(package, poetry)
+            reqs, default = locked_deps(package, poetry, exclude, remove)
             resolve_source_deps(poetry, package, reqs, frozen=True)
             return reqs, default
 
@@ -184,10 +186,18 @@
             seen.add(cdep)
 
 
-def locked_deps(package, poetry):
+def locked_deps(package, poetry, exclude=(), remove=()):
     reqs = []
     packages = poetry.locker.locked_repository(False).packages
+
+    project_deps = {
+        r.name: r for r in poetry.package.requires}
     for p in packages:
+        if p.name in exclude:
+            reqs.append(project_deps[p.name].to_pep_508())
+            continue
+        if p.name in remove:
+            continue
         dep = p.to_dependency()
         line = "{}=={}".format(p.name, p.version)
         requirement = dep.to_pep_508()

{"golden_diff": "diff --git a/tools/dev/poetrypkg.py b/tools/dev/poetrypkg.py\n--- a/tools/dev/poetrypkg.py\n+++ b/tools/dev/poetrypkg.py\n@@ -123,7 +123,9 @@\n @cli.command()\n @click.option('-p', '--package-dir', type=click.Path())\n @click.option('-o', '--output', default='setup.py')\n-def gen_frozensetup(package_dir, output):\n+@click.option('-x', '--exclude', multiple=True)\n+@click.option('-r', '--remove', multiple=True)\n+def gen_frozensetup(package_dir, output, exclude, remove):\n     \"\"\"Generate a frozen setup suitable for distribution.\n     \"\"\"\n     from poetry.core.masonry.builders import sdist\n@@ -138,7 +140,7 @@\n \n         @classmethod\n         def convert_dependencies(cls, package, dependencies):\n-            reqs, default = locked_deps(package, poetry)\n+            reqs, default = locked_deps(package, poetry, exclude, remove)\n             resolve_source_deps(poetry, package, reqs, frozen=True)\n             return reqs, default\n \n@@ -184,10 +186,18 @@\n             seen.add(cdep)\n \n \n-def locked_deps(package, poetry):\n+def locked_deps(package, poetry, exclude=(), remove=()):\n     reqs = []\n     packages = poetry.locker.locked_repository(False).packages\n+\n+    project_deps = {\n+        r.name: r for r in poetry.package.requires}\n     for p in packages:\n+        if p.name in exclude:\n+            reqs.append(project_deps[p.name].to_pep_508())\n+            continue\n+        if p.name in remove:\n+            continue\n         dep = p.to_dependency()\n         line = \"{}=={}\".format(p.name, p.version)\n         requirement = dep.to_pep_508()\n", "issue": "c7n mailer dependency has a high vulnerability\n### Describe the bug\n\nc7n mailer depends on starkbank-ecdsa==1.1.1\r\n\r\nThis library at this version has been found to have a high vulnerability.\r\n\r\nhttps://github.com/advisories/GHSA-9wx7-jrvc-28mm\r\n\r\nThe version has been fixed in version 2.0.1\r\n\n\n### What did you expect to happen?\n\nNo vulnerabilities found in dependency libraries\n\n### Cloud Provider\n\nAmazon Web Services (AWS)\n\n### Cloud Custodian version and dependency information\n\n```shell\nCustodian:   0.9.13\r\nPython:      3.9.7 (default, Sep  1 2021, 14:45:30)\r\n             [GCC 10.3.1 20210424]\r\nPlatform:    posix.uname_result(sysname='Linux', nodename='b82f5787903f', release='5.11.0-1016-aws', version='#17~20.04.1-Ubuntu SMP Thu Aug 12 05:39:36 UTC 2021', machine='x86_64')\r\nUsing venv:  False\r\nDocker: True\r\nInstalled:\r\n\r\nargcomplete==1.12.3\r\nattrs==21.2.0\r\nboto3==1.17.102\r\nbotocore==1.20.102\r\nimportlib-metadata==4.6.0\r\njmespath==0.10.0\r\njsonschema==3.2.0\r\npyrsistent==0.18.0\r\npython-dateutil==2.8.1\r\npyyaml==5.4.1\r\ns3transfer==0.4.2\r\nsetuptools==57.4.0\r\nsix==1.16.0\r\ntabulate==0.8.9\r\ntyping-extensions==3.10.0.0\r\nurllib3==1.26.6\r\nzipp==3.4.1\n```\n\n\n### Policy\n\n_No response_\n\n### Relevant log/traceback output\n\n```shell\nTrivy output:\r\n\r\n\r\nPython (python-pkg)\r\n===================\r\nTotal: 1 (UNKNOWN: 0, LOW: 0, MEDIUM: 0, HIGH: 1, CRITICAL: 0)\r\n+-----------------+---------------------+----------+-------------------+---------------+----------------------------------------------+\r\n|     LIBRARY     |  VULNERABILITY ID   | SEVERITY | INSTALLED VERSION | FIXED VERSION |                    TITLE                     |\r\n+-----------------+---------------------+----------+-------------------+---------------+----------------------------------------------+\r\n| starkbank-ecdsa | GHSA-9wx7-jrvc-28mm | HIGH     | 1.1.1             | 2.0.1         | Signature verification vulnerability         |\r\n|                 |                     |          |                   |               | in Stark Bank ecdsa libraries                |\r\n|                 |                     |          |                   |               | -->github.com/advisories/GHSA-9wx7-jrvc-28mm |\r\n+-----------------+---------------------+----------+-------------------+---------------+----------------------------------------------+\r\n```\n```\n\n\n### Extra information or context\n\n_No response_\n", "before_files": [{"content": "# Copyright The Cloud Custodian Authors.\n# SPDX-License-Identifier: Apache-2.0\n\"\"\"\nSupplemental tooling for managing custodian packaging.\n\nHas various workarounds for poetry\n\"\"\"\nfrom collections import defaultdict\nimport click\nimport os\nimport sys\nimport toml\nfrom pathlib import Path\n\n\n@click.group()\ndef cli():\n    \"\"\"Custodian Python Packaging Utility\n\n    some simple tooling to sync poetry files to setup/pip\n    \"\"\"\n    # If there is a global installation of poetry, prefer that.\n    poetry_python_lib = Path(os.path.expanduser('~/.poetry/lib'))\n    if poetry_python_lib.exists():\n        sys.path.insert(0, os.path.realpath(poetry_python_lib))\n        # poetry env vendored deps\n        sys.path.insert(\n            0,\n            os.path.join(poetry_python_lib, 'poetry', '_vendor', 'py{}.{}'.format(\n                sys.version_info.major, sys.version_info.minor)))\n\n    # If there is a global installation of poetry, prefer that.\n    cur_poetry_python_lib = Path(os.path.expanduser('~/.local/share/pypoetry/venv/lib'))\n    if cur_poetry_python_lib.exists():\n        sys.path.insert(\n            0,\n            str(list(cur_poetry_python_lib.glob('*'))[0] / \"site-packages\"))\n\n\n# Override the poetry base template as all our readmes files\n# are in markdown format.\n#\n# Pull request submitted upstream to correctly autodetect\n# https://github.com/python-poetry/poetry/pull/1994\n#\nSETUP_TEMPLATE = \"\"\"\\\n# -*- coding: utf-8 -*-\nfrom setuptools import setup\n\n{before}\nsetup_kwargs = {{\n    'name': {name!r},\n    'version': {version!r},\n    'description': {description!r},\n    'license': 'Apache-2.0',\n    'classifiers': [\n        'License :: OSI Approved :: Apache Software License',\n        'Topic :: System :: Systems Administration',\n        'Topic :: System :: Distributed Computing'\n    ],\n    'long_description': {long_description!r},\n    'long_description_content_type': 'text/markdown',\n    'author': {author!r},\n    'author_email': {author_email!r},\n    'maintainer': {maintainer!r},\n    'maintainer_email': {maintainer_email!r},\n    'url': {url!r},\n    {extra}\n}}\n{after}\n\nsetup(**setup_kwargs)\n\"\"\"\n\n\n@cli.command()\n@click.option('-p', '--package-dir', type=click.Path())\n@click.option('-f', '--version-file', type=click.Path())\ndef gen_version_file(package_dir, version_file):\n    data = toml.load(Path(str(package_dir)) / 'pyproject.toml')\n    version = data['tool']['poetry']['version']\n    with open(version_file, 'w') as fh:\n        fh.write('# Generated via tools/dev/poetrypkg.py\\n')\n        fh.write('version = \"{}\"\\n'.format(version))\n\n\n@cli.command()\n@click.option('-p', '--package-dir', type=click.Path())\ndef gen_setup(package_dir):\n    \"\"\"Generate a setup suitable for dev compatibility with pip.\n    \"\"\"\n    from poetry.core.masonry.builders import sdist\n    from poetry.factory import Factory\n\n    factory = Factory()\n    poetry = factory.create_poetry(package_dir)\n\n    # the alternative to monkey patching is carrying forward a\n    # 100 line method. See SETUP_TEMPLATE comments above.\n    sdist.SETUP = SETUP_TEMPLATE\n\n    class SourceDevBuilder(sdist.SdistBuilder):\n        # to enable poetry with a monorepo, we have internal deps\n        # as source path dev dependencies, when we go to generate\n        # setup.py we need to ensure that the source deps are\n        # recorded faithfully.\n\n        @classmethod\n        def convert_dependencies(cls, package, dependencies):\n            reqs, default = super().convert_dependencies(package, dependencies)\n            resolve_source_deps(poetry, package, reqs)\n            return reqs, default\n\n    builder = SourceDevBuilder(poetry, None, None)\n    setup_content = builder.build_setup()\n\n    with open(os.path.join(package_dir, 'setup.py'), 'wb') as fh:\n        fh.write(b'# Automatically generated from poetry/pyproject.toml\\n')\n        fh.write(b'# flake8: noqa\\n')\n        fh.write(setup_content)\n\n\n@cli.command()\n@click.option('-p', '--package-dir', type=click.Path())\n@click.option('-o', '--output', default='setup.py')\ndef gen_frozensetup(package_dir, output):\n    \"\"\"Generate a frozen setup suitable for distribution.\n    \"\"\"\n    from poetry.core.masonry.builders import sdist\n    from poetry.factory import Factory\n\n    factory = Factory()\n    poetry = factory.create_poetry(package_dir)\n\n    sdist.SETUP = SETUP_TEMPLATE\n\n    class FrozenBuilder(sdist.SdistBuilder):\n\n        @classmethod\n        def convert_dependencies(cls, package, dependencies):\n            reqs, default = locked_deps(package, poetry)\n            resolve_source_deps(poetry, package, reqs, frozen=True)\n            return reqs, default\n\n    builder = FrozenBuilder(poetry, None, None)\n    setup_content = builder.build_setup()\n\n    with open(os.path.join(package_dir, output), 'wb') as fh:\n        fh.write(b'# Automatically generated from pyproject.toml\\n')\n        fh.write(b'# flake8: noqa\\n')\n        fh.write(setup_content)\n\n\ndef resolve_source_deps(poetry, package, reqs, frozen=False):\n    # find any source path dev deps and them and their recursive\n    # deps to reqs\n    if poetry.local_config['name'] not in (package.name, package.pretty_name):\n        return\n\n    source_deps = []\n    for dep_name, info in poetry.local_config.get('dev-dependencies', {}).items():\n        if isinstance(info, dict) and 'path' in info:\n            source_deps.append(dep_name)\n    if not source_deps:\n        return\n\n    from poetry.core.packages.dependency import Dependency\n\n    dep_map = {d['name']: d for d in poetry.locker.lock_data['package']}\n    seen = set(source_deps)\n    seen.add('setuptools')\n\n    prefix = '' if frozen else '^'\n    while source_deps:\n        dep = source_deps.pop()\n        if dep not in dep_map:\n            dep = dep.replace('_', '-')\n        version = dep_map[dep]['version']\n        reqs.append(Dependency(dep, '{}{}'.format(prefix, version)).to_pep_508())\n        for cdep, cversion in dep_map[dep].get('dependencies', {}).items():\n            if cdep in seen:\n                continue\n            source_deps.append(cdep)\n            seen.add(cdep)\n\n\ndef locked_deps(package, poetry):\n    reqs = []\n    packages = poetry.locker.locked_repository(False).packages\n    for p in packages:\n        dep = p.to_dependency()\n        line = \"{}=={}\".format(p.name, p.version)\n        requirement = dep.to_pep_508()\n        if ';' in requirement:\n            line += \"; {}\".format(requirement.split(\";\")[1].strip())\n        reqs.append(line)\n    return reqs, defaultdict(list)\n\n\nif __name__ == '__main__':\n    cli()\n", "path": "tools/dev/poetrypkg.py"}], "after_files": [{"content": "# Copyright The Cloud Custodian Authors.\n# SPDX-License-Identifier: Apache-2.0\n\"\"\"\nSupplemental tooling for managing custodian packaging.\n\nHas various workarounds for poetry\n\"\"\"\nfrom collections import defaultdict\nimport click\nimport os\nimport sys\nimport toml\nfrom pathlib import Path\n\n\n@click.group()\ndef cli():\n    \"\"\"Custodian Python Packaging Utility\n\n    some simple tooling to sync poetry files to setup/pip\n    \"\"\"\n    # If there is a global installation of poetry, prefer that.\n    poetry_python_lib = Path(os.path.expanduser('~/.poetry/lib'))\n    if poetry_python_lib.exists():\n        sys.path.insert(0, os.path.realpath(poetry_python_lib))\n        # poetry env vendored deps\n        sys.path.insert(\n            0,\n            os.path.join(poetry_python_lib, 'poetry', '_vendor', 'py{}.{}'.format(\n                sys.version_info.major, sys.version_info.minor)))\n\n    # If there is a global installation of poetry, prefer that.\n    cur_poetry_python_lib = Path(os.path.expanduser('~/.local/share/pypoetry/venv/lib'))\n    if cur_poetry_python_lib.exists():\n        sys.path.insert(\n            0,\n            str(list(cur_poetry_python_lib.glob('*'))[0] / \"site-packages\"))\n\n\n# Override the poetry base template as all our readmes files\n# are in markdown format.\n#\n# Pull request submitted upstream to correctly autodetect\n# https://github.com/python-poetry/poetry/pull/1994\n#\nSETUP_TEMPLATE = \"\"\"\\\n# -*- coding: utf-8 -*-\nfrom setuptools import setup\n\n{before}\nsetup_kwargs = {{\n    'name': {name!r},\n    'version': {version!r},\n    'description': {description!r},\n    'license': 'Apache-2.0',\n    'classifiers': [\n        'License :: OSI Approved :: Apache Software License',\n        'Topic :: System :: Systems Administration',\n        'Topic :: System :: Distributed Computing'\n    ],\n    'long_description': {long_description!r},\n    'long_description_content_type': 'text/markdown',\n    'author': {author!r},\n    'author_email': {author_email!r},\n    'maintainer': {maintainer!r},\n    'maintainer_email': {maintainer_email!r},\n    'url': {url!r},\n    {extra}\n}}\n{after}\n\nsetup(**setup_kwargs)\n\"\"\"\n\n\n@cli.command()\n@click.option('-p', '--package-dir', type=click.Path())\n@click.option('-f', '--version-file', type=click.Path())\ndef gen_version_file(package_dir, version_file):\n    data = toml.load(Path(str(package_dir)) / 'pyproject.toml')\n    version = data['tool']['poetry']['version']\n    with open(version_file, 'w') as fh:\n        fh.write('# Generated via tools/dev/poetrypkg.py\\n')\n        fh.write('version = \"{}\"\\n'.format(version))\n\n\n@cli.command()\n@click.option('-p', '--package-dir', type=click.Path())\ndef gen_setup(package_dir):\n    \"\"\"Generate a setup suitable for dev compatibility with pip.\n    \"\"\"\n    from poetry.core.masonry.builders import sdist\n    from poetry.factory import Factory\n\n    factory = Factory()\n    poetry = factory.create_poetry(package_dir)\n\n    # the alternative to monkey patching is carrying forward a\n    # 100 line method. See SETUP_TEMPLATE comments above.\n    sdist.SETUP = SETUP_TEMPLATE\n\n    class SourceDevBuilder(sdist.SdistBuilder):\n        # to enable poetry with a monorepo, we have internal deps\n        # as source path dev dependencies, when we go to generate\n        # setup.py we need to ensure that the source deps are\n        # recorded faithfully.\n\n        @classmethod\n        def convert_dependencies(cls, package, dependencies):\n            reqs, default = super().convert_dependencies(package, dependencies)\n            resolve_source_deps(poetry, package, reqs)\n            return reqs, default\n\n    builder = SourceDevBuilder(poetry, None, None)\n    setup_content = builder.build_setup()\n\n    with open(os.path.join(package_dir, 'setup.py'), 'wb') as fh:\n        fh.write(b'# Automatically generated from poetry/pyproject.toml\\n')\n        fh.write(b'# flake8: noqa\\n')\n        fh.write(setup_content)\n\n\n@cli.command()\n@click.option('-p', '--package-dir', type=click.Path())\n@click.option('-o', '--output', default='setup.py')\n@click.option('-x', '--exclude', multiple=True)\n@click.option('-r', '--remove', multiple=True)\ndef gen_frozensetup(package_dir, output, exclude, remove):\n    \"\"\"Generate a frozen setup suitable for distribution.\n    \"\"\"\n    from poetry.core.masonry.builders import sdist\n    from poetry.factory import Factory\n\n    factory = Factory()\n    poetry = factory.create_poetry(package_dir)\n\n    sdist.SETUP = SETUP_TEMPLATE\n\n    class FrozenBuilder(sdist.SdistBuilder):\n\n        @classmethod\n        def convert_dependencies(cls, package, dependencies):\n            reqs, default = locked_deps(package, poetry, exclude, remove)\n            resolve_source_deps(poetry, package, reqs, frozen=True)\n            return reqs, default\n\n    builder = FrozenBuilder(poetry, None, None)\n    setup_content = builder.build_setup()\n\n    with open(os.path.join(package_dir, output), 'wb') as fh:\n        fh.write(b'# Automatically generated from pyproject.toml\\n')\n        fh.write(b'# flake8: noqa\\n')\n        fh.write(setup_content)\n\n\ndef resolve_source_deps(poetry, package, reqs, frozen=False):\n    # find any source path dev deps and them and their recursive\n    # deps to reqs\n    if poetry.local_config['name'] not in (package.name, package.pretty_name):\n        return\n\n    source_deps = []\n    for dep_name, info in poetry.local_config.get('dev-dependencies', {}).items():\n        if isinstance(info, dict) and 'path' in info:\n            source_deps.append(dep_name)\n    if not source_deps:\n        return\n\n    from poetry.core.packages.dependency import Dependency\n\n    dep_map = {d['name']: d for d in poetry.locker.lock_data['package']}\n    seen = set(source_deps)\n    seen.add('setuptools')\n\n    prefix = '' if frozen else '^'\n    while source_deps:\n        dep = source_deps.pop()\n        if dep not in dep_map:\n            dep = dep.replace('_', '-')\n        version = dep_map[dep]['version']\n        reqs.append(Dependency(dep, '{}{}'.format(prefix, version)).to_pep_508())\n        for cdep, cversion in dep_map[dep].get('dependencies', {}).items():\n            if cdep in seen:\n                continue\n            source_deps.append(cdep)\n            seen.add(cdep)\n\n\ndef locked_deps(package, poetry, exclude=(), remove=()):\n    reqs = []\n    packages = poetry.locker.locked_repository(False).packages\n\n    project_deps = {\n        r.name: r for r in poetry.package.requires}\n    for p in packages:\n        if p.name in exclude:\n            reqs.append(project_deps[p.name].to_pep_508())\n            continue\n        if p.name in remove:\n            continue\n        dep = p.to_dependency()\n        line = \"{}=={}\".format(p.name, p.version)\n        requirement = dep.to_pep_508()\n        if ';' in requirement:\n            line += \"; {}\".format(requirement.split(\";\")[1].strip())\n        reqs.append(line)\n    return reqs, defaultdict(list)\n\n\nif __name__ == '__main__':\n    cli()\n", "path": "tools/dev/poetrypkg.py"}]}