We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Namecheap support not optional
Unlike route53 or softlayer and unlike what setup.py suggests, the namecheap provider is not optional in 2.1.17.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `lexicon/providers/namecheap.py`
Content:
```
1 from __future__ import absolute_import
2 from __future__ import print_function
3 
4 import logging
5 
6 import namecheap
7 
8 from .base import Provider as BaseProvider
9 
10 logger = logging.getLogger(__name__)
11 
12 
13 def ProviderParser(subparser):
14     subparser.add_argument(
15         '--auth-token',
16         help='specify api token used to authenticate'
17     )
18     subparser.add_argument(
19         '--auth-username',
20         help='specify email address used to authenticate'
21     )
22     # FIXME What is the client IP used for?
23     subparser.add_argument(
24         '--auth-client-ip',
25         help='Client IP address to send to Namecheap API calls',
26         default='127.0.0.1'
27     )
28     subparser.add_argument(
29         '--auth-sandbox',
30         help='Whether to use the sandbox server',
31         action='store_true'
32     )
33 
34 class Provider(BaseProvider):
35 
36     def __init__(self, options, engine_overrides=None):
37         super(Provider, self).__init__(options, engine_overrides)
38         self.options = options
39         self.client = namecheap.Api(
40             ApiUser=options.get('auth_username',''),
41             ApiKey=options.get('auth_token',''),
42             UserName=options.get('auth_username',''),
43             ClientIP=options.get('auth_client_ip',''),
44             sandbox=options.get('auth_sandbox', False),
45             debug=False
46         )
47         self.domain = self.options['domain']
48         self.domain_id = None
49 
50     def authenticate(self):
51         try:
52             domain_names = [x['Name'] for x in self.client.domains_getList()]
53         except namecheap.ApiError:
54             raise Exception('Authentication failed')
55         if self.domain not in domain_names:
56             raise Exception('The domain {} is not controlled by this Namecheap '
57                             'account'.format(self.domain))
58         # FIXME What is this for?
59         self.domain_id = self.domain
60 
61     # Create record. If record already exists with the same content, do nothing
62     def create_record(self, type, name, content):
63         record = {
64             # required
65             'Type': type,
66             'Name': self._relative_name(name),
67             'Address': content
68         }
69         # logger.debug('create_record: %s', 'id' in payload)
70         # return 'id' in payload
71         self.client.domains_dns_addHost(self.domain, record)
72         return True
73 
74     # List all records. Return an empty list if no records found.
75     # type, name and content are used to filter records.
76     # If possible filter during the query, otherwise filter after response is
77     # received.
78     def list_records(self, type=None, name=None, content=None, id=None):
79 
80 
81         records = []
82         raw_records = self.client.domains_dns_getHosts(self.domain)
83         for record in raw_records:
84             records.append(self._convert_to_lexicon(record))
85 
86         if id:
87             records = [record for record in records if record['id'] == id]
88         if type:
89             records = [record for record in records if record['type'] == type]
90         if name:
91             if name.endswith('.'):
92                 name = name[:-1]
93             records = [record for record in records if name in record['name'] ]
94         if content:
95             records = [record for record in records if record['content'].lower() == content.lower()]
96 
97         logger.debug('list_records: %s', records)
98         return records
99 
100     # Create or update a record.
101     def update_record(self, identifier, type=None, name=None, content=None):
102         # Delete record if it exists
103         self.delete_record(identifier, type, name, content)
104         return self.create_record(type, name, content)
105 
106     # Delete an existing record.
107     # If record does not exist, do nothing.
108     def delete_record(self, identifier=None, type=None, name=None, content=None):
109 
110         record = self.list_records(type=type, name=name, content=content, id=identifier)
111         if record:
112             self.client.domains_dns_delHost(self.domain, self._convert_to_namecheap(record[0]))
113             return True
114         else:
115             return False
116 
117     def _convert_to_namecheap(self, record):
118         """ converts from lexicon format record to namecheap format record,
119         suitable to sending through the api to namecheap"""
120 
121         name = record['name']
122         if name.endswith('.'):
123             name = name[:-1]
124 
125         short_name = name[:name.find(self.domain)-1]
126         processed_record = {
127             'Type': record['type'],
128             'Name': short_name,
129             'TTL': record['ttl'],
130             'Address': record['content'],
131             'HostId': record['id']
132         }
133 
134         return processed_record
135 
136     def _convert_to_lexicon(self, record):
137         """ converts from namecheap raw record format to lexicon format record
138         """
139 
140         name = record['Name']
141         if self.domain not in name:
142             name = "{}.{}".format(name,self.domain)
143 
144         processed_record = {
145             'type': record['Type'],
146             'name': '{0}.{1}'.format(record['Name'], self.domain),
147             'ttl': record['TTL'],
148             'content': record['Address'],
149             'id': record['HostId']
150         }
151 
152         return processed_record
153
```
--- 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/lexicon/providers/namecheap.py b/lexicon/providers/namecheap.py
--- a/lexicon/providers/namecheap.py
+++ b/lexicon/providers/namecheap.py
@@ -3,10 +3,14 @@
 
 import logging
 
-import namecheap
 
 from .base import Provider as BaseProvider
 
+try:
+    import namecheap #optional dep
+except ImportError:
+    pass
+
 logger = logging.getLogger(__name__)

{"golden_diff": "diff --git a/lexicon/providers/namecheap.py b/lexicon/providers/namecheap.py\n--- a/lexicon/providers/namecheap.py\n+++ b/lexicon/providers/namecheap.py\n@@ -3,10 +3,14 @@\n \n import logging\n \n-import namecheap\n \n from .base import Provider as BaseProvider\n \n+try:\n+    import namecheap #optional dep\n+except ImportError:\n+    pass\n+\n logger = logging.getLogger(__name__)\n", "issue": "Namecheap support not optional\nUnlike route53 or softlayer and unlike what setup.py suggests, the namecheap provider is not optional in 2.1.17.\n", "before_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport logging\n\nimport namecheap\n\nfrom .base import Provider as BaseProvider\n\nlogger = logging.getLogger(__name__)\n\n\ndef ProviderParser(subparser):\n    subparser.add_argument(\n        '--auth-token',\n        help='specify api token used to authenticate'\n    )\n    subparser.add_argument(\n        '--auth-username',\n        help='specify email address used to authenticate'\n    )\n    # FIXME What is the client IP used for?\n    subparser.add_argument(\n        '--auth-client-ip',\n        help='Client IP address to send to Namecheap API calls',\n        default='127.0.0.1'\n    )\n    subparser.add_argument(\n        '--auth-sandbox',\n        help='Whether to use the sandbox server',\n        action='store_true'\n    )\n\nclass Provider(BaseProvider):\n\n    def __init__(self, options, engine_overrides=None):\n        super(Provider, self).__init__(options, engine_overrides)\n        self.options = options\n        self.client = namecheap.Api(\n            ApiUser=options.get('auth_username',''),\n            ApiKey=options.get('auth_token',''),\n            UserName=options.get('auth_username',''),\n            ClientIP=options.get('auth_client_ip',''),\n            sandbox=options.get('auth_sandbox', False),\n            debug=False\n        )\n        self.domain = self.options['domain']\n        self.domain_id = None\n\n    def authenticate(self):\n        try:\n            domain_names = [x['Name'] for x in self.client.domains_getList()]\n        except namecheap.ApiError:\n            raise Exception('Authentication failed')\n        if self.domain not in domain_names:\n            raise Exception('The domain {} is not controlled by this Namecheap '\n                            'account'.format(self.domain))\n        # FIXME What is this for?\n        self.domain_id = self.domain\n\n    # Create record. If record already exists with the same content, do nothing\n    def create_record(self, type, name, content):\n        record = {\n            # required\n            'Type': type,\n            'Name': self._relative_name(name),\n            'Address': content\n        }\n        # logger.debug('create_record: %s', 'id' in payload)\n        # return 'id' in payload\n        self.client.domains_dns_addHost(self.domain, record)\n        return True\n\n    # List all records. Return an empty list if no records found.\n    # type, name and content are used to filter records.\n    # If possible filter during the query, otherwise filter after response is\n    # received.\n    def list_records(self, type=None, name=None, content=None, id=None):\n\n\n        records = []\n        raw_records = self.client.domains_dns_getHosts(self.domain)\n        for record in raw_records:\n            records.append(self._convert_to_lexicon(record))\n\n        if id:\n            records = [record for record in records if record['id'] == id]\n        if type:\n            records = [record for record in records if record['type'] == type]\n        if name:\n            if name.endswith('.'):\n                name = name[:-1]\n            records = [record for record in records if name in record['name'] ]\n        if content:\n            records = [record for record in records if record['content'].lower() == content.lower()]\n\n        logger.debug('list_records: %s', records)\n        return records\n\n    # Create or update a record.\n    def update_record(self, identifier, type=None, name=None, content=None):\n        # Delete record if it exists\n        self.delete_record(identifier, type, name, content)\n        return self.create_record(type, name, content)\n\n    # Delete an existing record.\n    # If record does not exist, do nothing.\n    def delete_record(self, identifier=None, type=None, name=None, content=None):\n\n        record = self.list_records(type=type, name=name, content=content, id=identifier)\n        if record:\n            self.client.domains_dns_delHost(self.domain, self._convert_to_namecheap(record[0]))\n            return True\n        else:\n            return False\n\n    def _convert_to_namecheap(self, record):\n        \"\"\" converts from lexicon format record to namecheap format record,\n        suitable to sending through the api to namecheap\"\"\"\n\n        name = record['name']\n        if name.endswith('.'):\n            name = name[:-1]\n\n        short_name = name[:name.find(self.domain)-1]\n        processed_record = {\n            'Type': record['type'],\n            'Name': short_name,\n            'TTL': record['ttl'],\n            'Address': record['content'],\n            'HostId': record['id']\n        }\n\n        return processed_record\n\n    def _convert_to_lexicon(self, record):\n        \"\"\" converts from namecheap raw record format to lexicon format record\n        \"\"\"\n\n        name = record['Name']\n        if self.domain not in name:\n            name = \"{}.{}\".format(name,self.domain)\n\n        processed_record = {\n            'type': record['Type'],\n            'name': '{0}.{1}'.format(record['Name'], self.domain),\n            'ttl': record['TTL'],\n            'content': record['Address'],\n            'id': record['HostId']\n        }\n\n        return processed_record\n", "path": "lexicon/providers/namecheap.py"}], "after_files": [{"content": "from __future__ import absolute_import\nfrom __future__ import print_function\n\nimport logging\n\n\nfrom .base import Provider as BaseProvider\n\ntry:\n    import namecheap #optional dep\nexcept ImportError:\n    pass\n\nlogger = logging.getLogger(__name__)\n\n\ndef ProviderParser(subparser):\n    subparser.add_argument(\n        '--auth-token',\n        help='specify api token used to authenticate'\n    )\n    subparser.add_argument(\n        '--auth-username',\n        help='specify email address used to authenticate'\n    )\n    # FIXME What is the client IP used for?\n    subparser.add_argument(\n        '--auth-client-ip',\n        help='Client IP address to send to Namecheap API calls',\n        default='127.0.0.1'\n    )\n    subparser.add_argument(\n        '--auth-sandbox',\n        help='Whether to use the sandbox server',\n        action='store_true'\n    )\n\nclass Provider(BaseProvider):\n\n    def __init__(self, options, engine_overrides=None):\n        super(Provider, self).__init__(options, engine_overrides)\n        self.options = options\n        self.client = namecheap.Api(\n            ApiUser=options.get('auth_username',''),\n            ApiKey=options.get('auth_token',''),\n            UserName=options.get('auth_username',''),\n            ClientIP=options.get('auth_client_ip',''),\n            sandbox=options.get('auth_sandbox', False),\n            debug=False\n        )\n        self.domain = self.options['domain']\n        self.domain_id = None\n\n    def authenticate(self):\n        try:\n            domain_names = [x['Name'] for x in self.client.domains_getList()]\n        except namecheap.ApiError:\n            raise Exception('Authentication failed')\n        if self.domain not in domain_names:\n            raise Exception('The domain {} is not controlled by this Namecheap '\n                            'account'.format(self.domain))\n        # FIXME What is this for?\n        self.domain_id = self.domain\n\n    # Create record. If record already exists with the same content, do nothing\n    def create_record(self, type, name, content):\n        record = {\n            # required\n            'Type': type,\n            'Name': self._relative_name(name),\n            'Address': content\n        }\n        # logger.debug('create_record: %s', 'id' in payload)\n        # return 'id' in payload\n        self.client.domains_dns_addHost(self.domain, record)\n        return True\n\n    # List all records. Return an empty list if no records found.\n    # type, name and content are used to filter records.\n    # If possible filter during the query, otherwise filter after response is\n    # received.\n    def list_records(self, type=None, name=None, content=None, id=None):\n\n\n        records = []\n        raw_records = self.client.domains_dns_getHosts(self.domain)\n        for record in raw_records:\n            records.append(self._convert_to_lexicon(record))\n\n        if id:\n            records = [record for record in records if record['id'] == id]\n        if type:\n            records = [record for record in records if record['type'] == type]\n        if name:\n            if name.endswith('.'):\n                name = name[:-1]\n            records = [record for record in records if name in record['name'] ]\n        if content:\n            records = [record for record in records if record['content'].lower() == content.lower()]\n\n        logger.debug('list_records: %s', records)\n        return records\n\n    # Create or update a record.\n    def update_record(self, identifier, type=None, name=None, content=None):\n        # Delete record if it exists\n        self.delete_record(identifier, type, name, content)\n        return self.create_record(type, name, content)\n\n    # Delete an existing record.\n    # If record does not exist, do nothing.\n    def delete_record(self, identifier=None, type=None, name=None, content=None):\n\n        record = self.list_records(type=type, name=name, content=content, id=identifier)\n        if record:\n            self.client.domains_dns_delHost(self.domain, self._convert_to_namecheap(record[0]))\n            return True\n        else:\n            return False\n\n    def _convert_to_namecheap(self, record):\n        \"\"\" converts from lexicon format record to namecheap format record,\n        suitable to sending through the api to namecheap\"\"\"\n\n        name = record['name']\n        if name.endswith('.'):\n            name = name[:-1]\n\n        short_name = name[:name.find(self.domain)-1]\n        processed_record = {\n            'Type': record['type'],\n            'Name': short_name,\n            'TTL': record['ttl'],\n            'Address': record['content'],\n            'HostId': record['id']\n        }\n\n        return processed_record\n\n    def _convert_to_lexicon(self, record):\n        \"\"\" converts from namecheap raw record format to lexicon format record\n        \"\"\"\n\n        name = record['Name']\n        if self.domain not in name:\n            name = \"{}.{}\".format(name,self.domain)\n\n        processed_record = {\n            'type': record['Type'],\n            'name': '{0}.{1}'.format(record['Name'], self.domain),\n            'ttl': record['TTL'],\n            'content': record['Address'],\n            'id': record['HostId']\n        }\n\n        return processed_record\n", "path": "lexicon/providers/namecheap.py"}]}