We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
S3 Bucket constructor
**Expected result:** troposphere.s3.Bucket constructor accepts `template` as a second parameter.
**Actual result:** troposphere.s3.Bucket constructor does not accept `template` as a second parameter.

Example of code that should work:
```python
template = Template()
Bucket(
    'PlaylistsFailoverS3Bucket',
    template,
    AccessControl=Private,
    BucketName="test-bucket",
)
```

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `troposphere/s3.py`
Content:
```
1 # Copyright (c) 2013, Bob Van Zant <bob@veznat.com>
2 # All rights reserved.
3 #
4 # See LICENSE file for full license.
5 import warnings
6 
7 from . import AWSObject, AWSProperty, Tags
8 from .validators import positive_integer, s3_bucket_name
9 from .validators import s3_transfer_acceleration_status
10 
11 try:
12     from awacs.aws import Policy
13 
14     policytypes = (dict, Policy)
15 except ImportError:
16     policytypes = dict,
17 
18 Private = "Private"
19 PublicRead = "PublicRead"
20 PublicReadWrite = "PublicReadWrite"
21 AuthenticatedRead = "AuthenticatedRead"
22 BucketOwnerRead = "BucketOwnerRead"
23 BucketOwnerFullControl = "BucketOwnerFullControl"
24 LogDeliveryWrite = "LogDeliveryWrite"
25 
26 
27 class CorsRules(AWSProperty):
28     props = {
29         'AllowedHeaders': ([basestring], False),
30         'AllowedMethods': ([basestring], True),
31         'AllowedOrigins': ([basestring], True),
32         'ExposedHeaders': ([basestring], False),
33         'Id': (basestring, False),
34         'MaxAge': (positive_integer, False),
35     }
36 
37 
38 class CorsConfiguration(AWSProperty):
39     props = {
40         'CorsRules': ([CorsRules], True),
41     }
42 
43 
44 class VersioningConfiguration(AWSProperty):
45     props = {
46         'Status': (basestring, False),
47     }
48 
49 
50 class AccelerateConfiguration(AWSProperty):
51     props = {
52         'AccelerationStatus': (s3_transfer_acceleration_status, True),
53     }
54 
55 
56 class RedirectAllRequestsTo(AWSProperty):
57     props = {
58         'HostName': (basestring, True),
59         'Protocol': (basestring, False),
60     }
61 
62 
63 class RedirectRule(AWSProperty):
64     props = {
65         'HostName': (basestring, False),
66         'HttpRedirectCode': (basestring, False),
67         'Protocol': (basestring, False),
68         'ReplaceKeyPrefixWith': (basestring, False),
69         'ReplaceKeyWith': (basestring, False),
70     }
71 
72 
73 class RoutingRuleCondition(AWSProperty):
74     props = {
75         'HttpErrorCodeReturnedEquals': (basestring, False),
76         'KeyPrefixEquals': (basestring, False),
77     }
78 
79 
80 class RoutingRule(AWSProperty):
81     props = {
82         'RedirectRule': (RedirectRule, True),
83         'RoutingRuleCondition': (RoutingRuleCondition, False),
84     }
85 
86 
87 class WebsiteConfiguration(AWSProperty):
88     props = {
89         'IndexDocument': (basestring, False),
90         'ErrorDocument': (basestring, False),
91         'RedirectAllRequestsTo': (RedirectAllRequestsTo, False),
92         'RoutingRules': ([RoutingRule], False),
93     }
94 
95 
96 class LifecycleRuleTransition(AWSProperty):
97     props = {
98         'StorageClass': (basestring, True),
99         'TransitionDate': (basestring, False),
100         'TransitionInDays': (positive_integer, False),
101     }
102 
103 
104 class AbortIncompleteMultipartUpload(AWSProperty):
105     props = {
106         'DaysAfterInitiation': (positive_integer, True),
107     }
108 
109 
110 class NoncurrentVersionTransition(AWSProperty):
111     props = {
112         'StorageClass': (basestring, True),
113         'TransitionInDays': (positive_integer, True),
114     }
115 
116 
117 class TagFilter(AWSProperty):
118     props = {
119         'Key': (basestring, True),
120         'Value': (basestring, True),
121     }
122 
123 
124 class LifecycleRule(AWSProperty):
125     props = {
126         'AbortIncompleteMultipartUpload':
127             (AbortIncompleteMultipartUpload, False),
128         'ExpirationDate': (basestring, False),
129         'ExpirationInDays': (positive_integer, False),
130         'Id': (basestring, False),
131         'NoncurrentVersionExpirationInDays': (positive_integer, False),
132         'NoncurrentVersionTransition': (NoncurrentVersionTransition, False),
133         'NoncurrentVersionTransitions': ([NoncurrentVersionTransition], False),
134         'Prefix': (basestring, False),
135         'Status': (basestring, True),
136         'TagFilters': ([TagFilter], False),
137         'Transition': (LifecycleRuleTransition, False),
138         'Transitions': ([LifecycleRuleTransition], False)
139     }
140 
141     def validate(self):
142         if 'Transition' in self.properties:
143             if 'Transitions' not in self.properties:
144                 # aws moved from a single transition to a list of them
145                 # and deprecated 'Transition', so let's just move it to
146                 # the new property and not annoy the user.
147                 self.properties['Transitions'] = [
148                     self.properties.pop('Transition')]
149             else:
150                 raise ValueError(
151                     'Cannot specify both "Transition" and "Transitions" '
152                     'properties on S3 Bucket Lifecycle Rule. Please use '
153                     '"Transitions" since the former has been deprecated.')
154 
155         if 'NoncurrentVersionTransition' in self.properties:
156             if 'NoncurrentVersionTransitions' not in self.properties:
157                 warnings.warn(
158                     'NoncurrentVersionTransition has been deprecated in '
159                     'favour of NoncurrentVersionTransitions.'
160                 )
161                 # Translate the old transition format to the new format
162                 self.properties['NoncurrentVersionTransitions'] = [
163                     self.properties.pop('NoncurrentVersionTransition')]
164             else:
165                 raise ValueError(
166                     'Cannot specify both "NoncurrentVersionTransition" and '
167                     '"NoncurrentVersionTransitions" properties on S3 Bucket '
168                     'Lifecycle Rule. Please use '
169                     '"NoncurrentVersionTransitions" since the former has been '
170                     'deprecated.')
171 
172         if 'ExpirationInDays' in self.properties and 'ExpirationDate' in \
173                 self.properties:
174             raise ValueError(
175                 'Cannot specify both "ExpirationDate" and "ExpirationInDays"'
176             )
177 
178 
179 class LifecycleConfiguration(AWSProperty):
180     props = {
181         'Rules': ([LifecycleRule], True),
182     }
183 
184 
185 class LoggingConfiguration(AWSProperty):
186     props = {
187         'DestinationBucketName': (s3_bucket_name, False),
188         'LogFilePrefix': (basestring, False),
189     }
190 
191 
192 class Rules(AWSProperty):
193     props = {
194         'Name': (basestring, True),
195         'Value': (basestring, True)
196     }
197 
198 
199 class S3Key(AWSProperty):
200     props = {
201         'Rules': ([Rules], True)
202     }
203 
204 
205 class Filter(AWSProperty):
206     props = {
207         'S3Key': (S3Key, True)
208     }
209 
210 
211 class LambdaConfigurations(AWSProperty):
212     props = {
213         'Event': (basestring, True),
214         'Filter': (Filter, False),
215         'Function': (basestring, True),
216     }
217 
218 
219 class QueueConfigurations(AWSProperty):
220     props = {
221         'Event': (basestring, True),
222         'Filter': (Filter, False),
223         'Queue': (basestring, True),
224     }
225 
226 
227 class TopicConfigurations(AWSProperty):
228     props = {
229         'Event': (basestring, True),
230         'Filter': (Filter, False),
231         'Topic': (basestring, True),
232     }
233 
234 
235 class MetricsConfiguration(AWSProperty):
236     props = {
237         'Id': (basestring, True),
238         'Prefix': (basestring, False),
239         'TagFilters': ([TagFilter], False),
240     }
241 
242 
243 class NotificationConfiguration(AWSProperty):
244     props = {
245         'LambdaConfigurations': ([LambdaConfigurations], False),
246         'QueueConfigurations': ([QueueConfigurations], False),
247         'TopicConfigurations': ([TopicConfigurations], False),
248     }
249 
250 
251 class ReplicationConfigurationRulesDestination(AWSProperty):
252     props = {
253         'Bucket': (basestring, True),
254         'StorageClass': (basestring, False)
255     }
256 
257 
258 class ReplicationConfigurationRules(AWSProperty):
259     props = {
260         'Destination': (ReplicationConfigurationRulesDestination, True),
261         'Id': (basestring, False),
262         'Prefix': (basestring, True),
263         'Status': (basestring, True)
264     }
265 
266 
267 class ReplicationConfiguration(AWSProperty):
268     props = {
269         'Role': (basestring, True),
270         'Rules': ([ReplicationConfigurationRules], True)
271     }
272 
273 
274 class Bucket(AWSObject):
275     resource_type = "AWS::S3::Bucket"
276 
277     props = {
278         'AccessControl': (basestring, False),
279         'AccelerateConfiguration': (AccelerateConfiguration, False),
280         'BucketName': (s3_bucket_name, False),
281         'CorsConfiguration': (CorsConfiguration, False),
282         'LifecycleConfiguration': (LifecycleConfiguration, False),
283         'LoggingConfiguration': (LoggingConfiguration, False),
284         'MetricsConfigurations': ([MetricsConfiguration], False),
285         'NotificationConfiguration': (NotificationConfiguration, False),
286         'ReplicationConfiguration': (ReplicationConfiguration, False),
287         'Tags': (Tags, False),
288         'WebsiteConfiguration': (WebsiteConfiguration, False),
289         'VersioningConfiguration': (VersioningConfiguration, False)
290     }
291 
292     access_control_types = [
293         Private,
294         PublicRead,
295         PublicReadWrite,
296         AuthenticatedRead,
297         BucketOwnerRead,
298         BucketOwnerFullControl,
299         LogDeliveryWrite,
300     ]
301 
302     def __init__(self, name=None, **kwargs):
303 
304         # note: 'name' is the resource title, not the bucket name
305 
306         if not name and 'title' in kwargs:
307             name = kwargs.pop('title')
308         if not name:
309             raise TypeError("You must provide a title for the bucket resource")
310         super(Bucket, self).__init__(name, **kwargs)
311 
312         if 'AccessControl' in kwargs and \
313                 isinstance(kwargs['AccessControl'], basestring):
314             if kwargs['AccessControl'] not in self.access_control_types:
315                 raise ValueError('AccessControl must be one of "%s"' % (
316                     ', '.join(self.access_control_types)))
317 
318 
319 class BucketPolicy(AWSObject):
320     resource_type = "AWS::S3::BucketPolicy"
321 
322     props = {
323         'Bucket': (basestring, True),
324         'PolicyDocument': (policytypes, True),
325     }
326
```
--- 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/troposphere/s3.py b/troposphere/s3.py
--- a/troposphere/s3.py
+++ b/troposphere/s3.py
@@ -299,19 +299,10 @@
         LogDeliveryWrite,
     ]
 
-    def __init__(self, name=None, **kwargs):
-
-        # note: 'name' is the resource title, not the bucket name
-
-        if not name and 'title' in kwargs:
-            name = kwargs.pop('title')
-        if not name:
-            raise TypeError("You must provide a title for the bucket resource")
-        super(Bucket, self).__init__(name, **kwargs)
-
-        if 'AccessControl' in kwargs and \
-                isinstance(kwargs['AccessControl'], basestring):
-            if kwargs['AccessControl'] not in self.access_control_types:
+    def validate(self):
+        access_control = self.properties.get('AccessControl')
+        if access_control is not None:
+            if access_control not in self.access_control_types:
                 raise ValueError('AccessControl must be one of "%s"' % (
                     ', '.join(self.access_control_types)))

{"golden_diff": "diff --git a/troposphere/s3.py b/troposphere/s3.py\n--- a/troposphere/s3.py\n+++ b/troposphere/s3.py\n@@ -299,19 +299,10 @@\n         LogDeliveryWrite,\n     ]\n \n-    def __init__(self, name=None, **kwargs):\n-\n-        # note: 'name' is the resource title, not the bucket name\n-\n-        if not name and 'title' in kwargs:\n-            name = kwargs.pop('title')\n-        if not name:\n-            raise TypeError(\"You must provide a title for the bucket resource\")\n-        super(Bucket, self).__init__(name, **kwargs)\n-\n-        if 'AccessControl' in kwargs and \\\n-                isinstance(kwargs['AccessControl'], basestring):\n-            if kwargs['AccessControl'] not in self.access_control_types:\n+    def validate(self):\n+        access_control = self.properties.get('AccessControl')\n+        if access_control is not None:\n+            if access_control not in self.access_control_types:\n                 raise ValueError('AccessControl must be one of \"%s\"' % (\n                     ', '.join(self.access_control_types)))\n", "issue": "S3 Bucket constructor\n**Expected result:** troposphere.s3.Bucket constructor accepts `template` as a second parameter.\r\n**Actual result:** troposphere.s3.Bucket constructor does not accept `template` as a second parameter.\r\n\r\nExample of code that should work:\r\n```python\r\ntemplate = Template()\r\nBucket(\r\n    'PlaylistsFailoverS3Bucket',\r\n    template,\r\n    AccessControl=Private,\r\n    BucketName=\"test-bucket\",\r\n)\r\n```\n", "before_files": [{"content": "# Copyright (c) 2013, Bob Van Zant <bob@veznat.com>\n# All rights reserved.\n#\n# See LICENSE file for full license.\nimport warnings\n\nfrom . import AWSObject, AWSProperty, Tags\nfrom .validators import positive_integer, s3_bucket_name\nfrom .validators import s3_transfer_acceleration_status\n\ntry:\n    from awacs.aws import Policy\n\n    policytypes = (dict, Policy)\nexcept ImportError:\n    policytypes = dict,\n\nPrivate = \"Private\"\nPublicRead = \"PublicRead\"\nPublicReadWrite = \"PublicReadWrite\"\nAuthenticatedRead = \"AuthenticatedRead\"\nBucketOwnerRead = \"BucketOwnerRead\"\nBucketOwnerFullControl = \"BucketOwnerFullControl\"\nLogDeliveryWrite = \"LogDeliveryWrite\"\n\n\nclass CorsRules(AWSProperty):\n    props = {\n        'AllowedHeaders': ([basestring], False),\n        'AllowedMethods': ([basestring], True),\n        'AllowedOrigins': ([basestring], True),\n        'ExposedHeaders': ([basestring], False),\n        'Id': (basestring, False),\n        'MaxAge': (positive_integer, False),\n    }\n\n\nclass CorsConfiguration(AWSProperty):\n    props = {\n        'CorsRules': ([CorsRules], True),\n    }\n\n\nclass VersioningConfiguration(AWSProperty):\n    props = {\n        'Status': (basestring, False),\n    }\n\n\nclass AccelerateConfiguration(AWSProperty):\n    props = {\n        'AccelerationStatus': (s3_transfer_acceleration_status, True),\n    }\n\n\nclass RedirectAllRequestsTo(AWSProperty):\n    props = {\n        'HostName': (basestring, True),\n        'Protocol': (basestring, False),\n    }\n\n\nclass RedirectRule(AWSProperty):\n    props = {\n        'HostName': (basestring, False),\n        'HttpRedirectCode': (basestring, False),\n        'Protocol': (basestring, False),\n        'ReplaceKeyPrefixWith': (basestring, False),\n        'ReplaceKeyWith': (basestring, False),\n    }\n\n\nclass RoutingRuleCondition(AWSProperty):\n    props = {\n        'HttpErrorCodeReturnedEquals': (basestring, False),\n        'KeyPrefixEquals': (basestring, False),\n    }\n\n\nclass RoutingRule(AWSProperty):\n    props = {\n        'RedirectRule': (RedirectRule, True),\n        'RoutingRuleCondition': (RoutingRuleCondition, False),\n    }\n\n\nclass WebsiteConfiguration(AWSProperty):\n    props = {\n        'IndexDocument': (basestring, False),\n        'ErrorDocument': (basestring, False),\n        'RedirectAllRequestsTo': (RedirectAllRequestsTo, False),\n        'RoutingRules': ([RoutingRule], False),\n    }\n\n\nclass LifecycleRuleTransition(AWSProperty):\n    props = {\n        'StorageClass': (basestring, True),\n        'TransitionDate': (basestring, False),\n        'TransitionInDays': (positive_integer, False),\n    }\n\n\nclass AbortIncompleteMultipartUpload(AWSProperty):\n    props = {\n        'DaysAfterInitiation': (positive_integer, True),\n    }\n\n\nclass NoncurrentVersionTransition(AWSProperty):\n    props = {\n        'StorageClass': (basestring, True),\n        'TransitionInDays': (positive_integer, True),\n    }\n\n\nclass TagFilter(AWSProperty):\n    props = {\n        'Key': (basestring, True),\n        'Value': (basestring, True),\n    }\n\n\nclass LifecycleRule(AWSProperty):\n    props = {\n        'AbortIncompleteMultipartUpload':\n            (AbortIncompleteMultipartUpload, False),\n        'ExpirationDate': (basestring, False),\n        'ExpirationInDays': (positive_integer, False),\n        'Id': (basestring, False),\n        'NoncurrentVersionExpirationInDays': (positive_integer, False),\n        'NoncurrentVersionTransition': (NoncurrentVersionTransition, False),\n        'NoncurrentVersionTransitions': ([NoncurrentVersionTransition], False),\n        'Prefix': (basestring, False),\n        'Status': (basestring, True),\n        'TagFilters': ([TagFilter], False),\n        'Transition': (LifecycleRuleTransition, False),\n        'Transitions': ([LifecycleRuleTransition], False)\n    }\n\n    def validate(self):\n        if 'Transition' in self.properties:\n            if 'Transitions' not in self.properties:\n                # aws moved from a single transition to a list of them\n                # and deprecated 'Transition', so let's just move it to\n                # the new property and not annoy the user.\n                self.properties['Transitions'] = [\n                    self.properties.pop('Transition')]\n            else:\n                raise ValueError(\n                    'Cannot specify both \"Transition\" and \"Transitions\" '\n                    'properties on S3 Bucket Lifecycle Rule. Please use '\n                    '\"Transitions\" since the former has been deprecated.')\n\n        if 'NoncurrentVersionTransition' in self.properties:\n            if 'NoncurrentVersionTransitions' not in self.properties:\n                warnings.warn(\n                    'NoncurrentVersionTransition has been deprecated in '\n                    'favour of NoncurrentVersionTransitions.'\n                )\n                # Translate the old transition format to the new format\n                self.properties['NoncurrentVersionTransitions'] = [\n                    self.properties.pop('NoncurrentVersionTransition')]\n            else:\n                raise ValueError(\n                    'Cannot specify both \"NoncurrentVersionTransition\" and '\n                    '\"NoncurrentVersionTransitions\" properties on S3 Bucket '\n                    'Lifecycle Rule. Please use '\n                    '\"NoncurrentVersionTransitions\" since the former has been '\n                    'deprecated.')\n\n        if 'ExpirationInDays' in self.properties and 'ExpirationDate' in \\\n                self.properties:\n            raise ValueError(\n                'Cannot specify both \"ExpirationDate\" and \"ExpirationInDays\"'\n            )\n\n\nclass LifecycleConfiguration(AWSProperty):\n    props = {\n        'Rules': ([LifecycleRule], True),\n    }\n\n\nclass LoggingConfiguration(AWSProperty):\n    props = {\n        'DestinationBucketName': (s3_bucket_name, False),\n        'LogFilePrefix': (basestring, False),\n    }\n\n\nclass Rules(AWSProperty):\n    props = {\n        'Name': (basestring, True),\n        'Value': (basestring, True)\n    }\n\n\nclass S3Key(AWSProperty):\n    props = {\n        'Rules': ([Rules], True)\n    }\n\n\nclass Filter(AWSProperty):\n    props = {\n        'S3Key': (S3Key, True)\n    }\n\n\nclass LambdaConfigurations(AWSProperty):\n    props = {\n        'Event': (basestring, True),\n        'Filter': (Filter, False),\n        'Function': (basestring, True),\n    }\n\n\nclass QueueConfigurations(AWSProperty):\n    props = {\n        'Event': (basestring, True),\n        'Filter': (Filter, False),\n        'Queue': (basestring, True),\n    }\n\n\nclass TopicConfigurations(AWSProperty):\n    props = {\n        'Event': (basestring, True),\n        'Filter': (Filter, False),\n        'Topic': (basestring, True),\n    }\n\n\nclass MetricsConfiguration(AWSProperty):\n    props = {\n        'Id': (basestring, True),\n        'Prefix': (basestring, False),\n        'TagFilters': ([TagFilter], False),\n    }\n\n\nclass NotificationConfiguration(AWSProperty):\n    props = {\n        'LambdaConfigurations': ([LambdaConfigurations], False),\n        'QueueConfigurations': ([QueueConfigurations], False),\n        'TopicConfigurations': ([TopicConfigurations], False),\n    }\n\n\nclass ReplicationConfigurationRulesDestination(AWSProperty):\n    props = {\n        'Bucket': (basestring, True),\n        'StorageClass': (basestring, False)\n    }\n\n\nclass ReplicationConfigurationRules(AWSProperty):\n    props = {\n        'Destination': (ReplicationConfigurationRulesDestination, True),\n        'Id': (basestring, False),\n        'Prefix': (basestring, True),\n        'Status': (basestring, True)\n    }\n\n\nclass ReplicationConfiguration(AWSProperty):\n    props = {\n        'Role': (basestring, True),\n        'Rules': ([ReplicationConfigurationRules], True)\n    }\n\n\nclass Bucket(AWSObject):\n    resource_type = \"AWS::S3::Bucket\"\n\n    props = {\n        'AccessControl': (basestring, False),\n        'AccelerateConfiguration': (AccelerateConfiguration, False),\n        'BucketName': (s3_bucket_name, False),\n        'CorsConfiguration': (CorsConfiguration, False),\n        'LifecycleConfiguration': (LifecycleConfiguration, False),\n        'LoggingConfiguration': (LoggingConfiguration, False),\n        'MetricsConfigurations': ([MetricsConfiguration], False),\n        'NotificationConfiguration': (NotificationConfiguration, False),\n        'ReplicationConfiguration': (ReplicationConfiguration, False),\n        'Tags': (Tags, False),\n        'WebsiteConfiguration': (WebsiteConfiguration, False),\n        'VersioningConfiguration': (VersioningConfiguration, False)\n    }\n\n    access_control_types = [\n        Private,\n        PublicRead,\n        PublicReadWrite,\n        AuthenticatedRead,\n        BucketOwnerRead,\n        BucketOwnerFullControl,\n        LogDeliveryWrite,\n    ]\n\n    def __init__(self, name=None, **kwargs):\n\n        # note: 'name' is the resource title, not the bucket name\n\n        if not name and 'title' in kwargs:\n            name = kwargs.pop('title')\n        if not name:\n            raise TypeError(\"You must provide a title for the bucket resource\")\n        super(Bucket, self).__init__(name, **kwargs)\n\n        if 'AccessControl' in kwargs and \\\n                isinstance(kwargs['AccessControl'], basestring):\n            if kwargs['AccessControl'] not in self.access_control_types:\n                raise ValueError('AccessControl must be one of \"%s\"' % (\n                    ', '.join(self.access_control_types)))\n\n\nclass BucketPolicy(AWSObject):\n    resource_type = \"AWS::S3::BucketPolicy\"\n\n    props = {\n        'Bucket': (basestring, True),\n        'PolicyDocument': (policytypes, True),\n    }\n", "path": "troposphere/s3.py"}], "after_files": [{"content": "# Copyright (c) 2013, Bob Van Zant <bob@veznat.com>\n# All rights reserved.\n#\n# See LICENSE file for full license.\nimport warnings\n\nfrom . import AWSObject, AWSProperty, Tags\nfrom .validators import positive_integer, s3_bucket_name\nfrom .validators import s3_transfer_acceleration_status\n\ntry:\n    from awacs.aws import Policy\n\n    policytypes = (dict, Policy)\nexcept ImportError:\n    policytypes = dict,\n\nPrivate = \"Private\"\nPublicRead = \"PublicRead\"\nPublicReadWrite = \"PublicReadWrite\"\nAuthenticatedRead = \"AuthenticatedRead\"\nBucketOwnerRead = \"BucketOwnerRead\"\nBucketOwnerFullControl = \"BucketOwnerFullControl\"\nLogDeliveryWrite = \"LogDeliveryWrite\"\n\n\nclass CorsRules(AWSProperty):\n    props = {\n        'AllowedHeaders': ([basestring], False),\n        'AllowedMethods': ([basestring], True),\n        'AllowedOrigins': ([basestring], True),\n        'ExposedHeaders': ([basestring], False),\n        'Id': (basestring, False),\n        'MaxAge': (positive_integer, False),\n    }\n\n\nclass CorsConfiguration(AWSProperty):\n    props = {\n        'CorsRules': ([CorsRules], True),\n    }\n\n\nclass VersioningConfiguration(AWSProperty):\n    props = {\n        'Status': (basestring, False),\n    }\n\n\nclass AccelerateConfiguration(AWSProperty):\n    props = {\n        'AccelerationStatus': (s3_transfer_acceleration_status, True),\n    }\n\n\nclass RedirectAllRequestsTo(AWSProperty):\n    props = {\n        'HostName': (basestring, True),\n        'Protocol': (basestring, False),\n    }\n\n\nclass RedirectRule(AWSProperty):\n    props = {\n        'HostName': (basestring, False),\n        'HttpRedirectCode': (basestring, False),\n        'Protocol': (basestring, False),\n        'ReplaceKeyPrefixWith': (basestring, False),\n        'ReplaceKeyWith': (basestring, False),\n    }\n\n\nclass RoutingRuleCondition(AWSProperty):\n    props = {\n        'HttpErrorCodeReturnedEquals': (basestring, False),\n        'KeyPrefixEquals': (basestring, False),\n    }\n\n\nclass RoutingRule(AWSProperty):\n    props = {\n        'RedirectRule': (RedirectRule, True),\n        'RoutingRuleCondition': (RoutingRuleCondition, False),\n    }\n\n\nclass WebsiteConfiguration(AWSProperty):\n    props = {\n        'IndexDocument': (basestring, False),\n        'ErrorDocument': (basestring, False),\n        'RedirectAllRequestsTo': (RedirectAllRequestsTo, False),\n        'RoutingRules': ([RoutingRule], False),\n    }\n\n\nclass LifecycleRuleTransition(AWSProperty):\n    props = {\n        'StorageClass': (basestring, True),\n        'TransitionDate': (basestring, False),\n        'TransitionInDays': (positive_integer, False),\n    }\n\n\nclass AbortIncompleteMultipartUpload(AWSProperty):\n    props = {\n        'DaysAfterInitiation': (positive_integer, True),\n    }\n\n\nclass NoncurrentVersionTransition(AWSProperty):\n    props = {\n        'StorageClass': (basestring, True),\n        'TransitionInDays': (positive_integer, True),\n    }\n\n\nclass TagFilter(AWSProperty):\n    props = {\n        'Key': (basestring, True),\n        'Value': (basestring, True),\n    }\n\n\nclass LifecycleRule(AWSProperty):\n    props = {\n        'AbortIncompleteMultipartUpload':\n            (AbortIncompleteMultipartUpload, False),\n        'ExpirationDate': (basestring, False),\n        'ExpirationInDays': (positive_integer, False),\n        'Id': (basestring, False),\n        'NoncurrentVersionExpirationInDays': (positive_integer, False),\n        'NoncurrentVersionTransition': (NoncurrentVersionTransition, False),\n        'NoncurrentVersionTransitions': ([NoncurrentVersionTransition], False),\n        'Prefix': (basestring, False),\n        'Status': (basestring, True),\n        'TagFilters': ([TagFilter], False),\n        'Transition': (LifecycleRuleTransition, False),\n        'Transitions': ([LifecycleRuleTransition], False)\n    }\n\n    def validate(self):\n        if 'Transition' in self.properties:\n            if 'Transitions' not in self.properties:\n                # aws moved from a single transition to a list of them\n                # and deprecated 'Transition', so let's just move it to\n                # the new property and not annoy the user.\n                self.properties['Transitions'] = [\n                    self.properties.pop('Transition')]\n            else:\n                raise ValueError(\n                    'Cannot specify both \"Transition\" and \"Transitions\" '\n                    'properties on S3 Bucket Lifecycle Rule. Please use '\n                    '\"Transitions\" since the former has been deprecated.')\n\n        if 'NoncurrentVersionTransition' in self.properties:\n            if 'NoncurrentVersionTransitions' not in self.properties:\n                warnings.warn(\n                    'NoncurrentVersionTransition has been deprecated in '\n                    'favour of NoncurrentVersionTransitions.'\n                )\n                # Translate the old transition format to the new format\n                self.properties['NoncurrentVersionTransitions'] = [\n                    self.properties.pop('NoncurrentVersionTransition')]\n            else:\n                raise ValueError(\n                    'Cannot specify both \"NoncurrentVersionTransition\" and '\n                    '\"NoncurrentVersionTransitions\" properties on S3 Bucket '\n                    'Lifecycle Rule. Please use '\n                    '\"NoncurrentVersionTransitions\" since the former has been '\n                    'deprecated.')\n\n        if 'ExpirationInDays' in self.properties and 'ExpirationDate' in \\\n                self.properties:\n            raise ValueError(\n                'Cannot specify both \"ExpirationDate\" and \"ExpirationInDays\"'\n            )\n\n\nclass LifecycleConfiguration(AWSProperty):\n    props = {\n        'Rules': ([LifecycleRule], True),\n    }\n\n\nclass LoggingConfiguration(AWSProperty):\n    props = {\n        'DestinationBucketName': (s3_bucket_name, False),\n        'LogFilePrefix': (basestring, False),\n    }\n\n\nclass Rules(AWSProperty):\n    props = {\n        'Name': (basestring, True),\n        'Value': (basestring, True)\n    }\n\n\nclass S3Key(AWSProperty):\n    props = {\n        'Rules': ([Rules], True)\n    }\n\n\nclass Filter(AWSProperty):\n    props = {\n        'S3Key': (S3Key, True)\n    }\n\n\nclass LambdaConfigurations(AWSProperty):\n    props = {\n        'Event': (basestring, True),\n        'Filter': (Filter, False),\n        'Function': (basestring, True),\n    }\n\n\nclass QueueConfigurations(AWSProperty):\n    props = {\n        'Event': (basestring, True),\n        'Filter': (Filter, False),\n        'Queue': (basestring, True),\n    }\n\n\nclass TopicConfigurations(AWSProperty):\n    props = {\n        'Event': (basestring, True),\n        'Filter': (Filter, False),\n        'Topic': (basestring, True),\n    }\n\n\nclass MetricsConfiguration(AWSProperty):\n    props = {\n        'Id': (basestring, True),\n        'Prefix': (basestring, False),\n        'TagFilters': ([TagFilter], False),\n    }\n\n\nclass NotificationConfiguration(AWSProperty):\n    props = {\n        'LambdaConfigurations': ([LambdaConfigurations], False),\n        'QueueConfigurations': ([QueueConfigurations], False),\n        'TopicConfigurations': ([TopicConfigurations], False),\n    }\n\n\nclass ReplicationConfigurationRulesDestination(AWSProperty):\n    props = {\n        'Bucket': (basestring, True),\n        'StorageClass': (basestring, False)\n    }\n\n\nclass ReplicationConfigurationRules(AWSProperty):\n    props = {\n        'Destination': (ReplicationConfigurationRulesDestination, True),\n        'Id': (basestring, False),\n        'Prefix': (basestring, True),\n        'Status': (basestring, True)\n    }\n\n\nclass ReplicationConfiguration(AWSProperty):\n    props = {\n        'Role': (basestring, True),\n        'Rules': ([ReplicationConfigurationRules], True)\n    }\n\n\nclass Bucket(AWSObject):\n    resource_type = \"AWS::S3::Bucket\"\n\n    props = {\n        'AccessControl': (basestring, False),\n        'AccelerateConfiguration': (AccelerateConfiguration, False),\n        'BucketName': (s3_bucket_name, False),\n        'CorsConfiguration': (CorsConfiguration, False),\n        'LifecycleConfiguration': (LifecycleConfiguration, False),\n        'LoggingConfiguration': (LoggingConfiguration, False),\n        'MetricsConfigurations': ([MetricsConfiguration], False),\n        'NotificationConfiguration': (NotificationConfiguration, False),\n        'ReplicationConfiguration': (ReplicationConfiguration, False),\n        'Tags': (Tags, False),\n        'WebsiteConfiguration': (WebsiteConfiguration, False),\n        'VersioningConfiguration': (VersioningConfiguration, False)\n    }\n\n    access_control_types = [\n        Private,\n        PublicRead,\n        PublicReadWrite,\n        AuthenticatedRead,\n        BucketOwnerRead,\n        BucketOwnerFullControl,\n        LogDeliveryWrite,\n    ]\n\n    def validate(self):\n        access_control = self.properties.get('AccessControl')\n        if access_control is not None:\n            if access_control not in self.access_control_types:\n                raise ValueError('AccessControl must be one of \"%s\"' % (\n                    ', '.join(self.access_control_types)))\n\n\nclass BucketPolicy(AWSObject):\n    resource_type = \"AWS::S3::BucketPolicy\"\n\n    props = {\n        'Bucket': (basestring, True),\n        'PolicyDocument': (policytypes, True),\n    }\n", "path": "troposphere/s3.py"}]}