Repository: aws/aws-cli

Issue:
aws 1.6.3
We upgraded our awscli and are now seeing the following error:

'datetime.datetime' object has no attribute 'read'

aws --profile <my-profile> s3 ls s3://<my-bucket>/

aws --version
aws-cli/1.6.3 Python/2.7.3 Linux/3.2.0-64-virtual



Discussion:
FYI, downgraded to 1.6.2 and the error went away....

Can you post the full `--debug` log?  I'm not seeing that issue.

Ah nevermind, I'm able to see the issue.

Ok thanks for reporting, working on a fix for this.

Excellent, thank you!


Resolving patch:
diff --git a/awscli/clidriver.py b/awscli/clidriver.py
--- a/awscli/clidriver.py
+++ b/awscli/clidriver.py
@@ -193,6 +193,7 @@ def main(self, args=None):
             # general exception handling logic as calling into the
             # command table.  This is why it's in the try/except clause.
             self._handle_top_level_args(parsed_args)
+            self._emit_session_event()
             return command_table[parsed_args.command](remaining, parsed_args)
         except UnknownArgumentError as e:
             sys.stderr.write("\n")
@@ -215,6 +216,14 @@ def main(self, args=None):
             sys.stderr.write("%s\n" % e)
             return 255
 
+    def _emit_session_event(self):
+        # This event is guaranteed to run after the session has been
+        # initialized and a profile has been set.  This was previously
+        # problematic because if something in CLIDriver caused the
+        # session components to be reset (such as session.profile = foo)
+        # then all the prior registered components would be removed.
+        self.session.emit('session-initialized', session=self.session)
+
     def _show_error(self, msg):
         LOG.debug(msg, exc_info=True)
         sys.stderr.write(msg)
diff --git a/awscli/customizations/scalarparse.py b/awscli/customizations/scalarparse.py
--- a/awscli/customizations/scalarparse.py
+++ b/awscli/customizations/scalarparse.py
@@ -28,7 +28,7 @@
 
 """
 def register_scalar_parser(event_handlers):
-    event_handlers.register('building-command-table.main',
+    event_handlers.register('session-initialized',
                             add_scalar_parsers)
 
 


Test patch:
diff --git a/tests/integration/customizations/s3/test_plugin.py b/tests/integration/customizations/s3/test_plugin.py
--- a/tests/integration/customizations/s3/test_plugin.py
+++ b/tests/integration/customizations/s3/test_plugin.py
@@ -1541,5 +1541,26 @@ def test_multipart_download(self):
         self.assertEqual(p.stdout, data_encoded.decode(get_stdout_encoding()))
 
 
+class TestLSWithProfile(BaseS3CLICommand):
+    def extra_setup(self):
+        self.config_file = os.path.join(self.files.rootdir, 'tmpconfig')
+        with open(self.config_file, 'w') as f:
+            creds = self.session.get_credentials()
+            f.write(
+                "[profile testprofile]\n"
+                "aws_access_key_id=%s\n"
+                "aws_secret_access_key=%s\n" % (
+                    creds.access_key,
+                    creds.secret_key)
+            )
+            if creds.token is not None:
+                f.write("aws_session_token=%s\n" % creds.token)
+
+    def test_can_ls_with_profile(self):
+        p = aws('s3 ls s3:// --profile testprofile',
+                env_vars={'AWS_CONFIG_FILE': self.config_file})
+        self.assert_no_errors(p)
+
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/tests/unit/customizations/test_scalarparse.py b/tests/unit/customizations/test_scalarparse.py
--- a/tests/unit/customizations/test_scalarparse.py
+++ b/tests/unit/customizations/test_scalarparse.py
@@ -23,7 +23,7 @@ def test_register_scalar_parser(self):
         event_handers = mock.Mock()
         scalarparse.register_scalar_parser(event_handers)
         event_handers.register.assert_called_with(
-            'building-command-table.main', scalarparse.add_scalar_parsers)
+            'session-initialized', scalarparse.add_scalar_parsers)
 
     def test_identity(self):
         self.assertEqual(scalarparse.identity('foo'), 'foo')
diff --git a/tests/unit/test_clidriver.py b/tests/unit/test_clidriver.py
--- a/tests/unit/test_clidriver.py
+++ b/tests/unit/test_clidriver.py
@@ -243,6 +243,7 @@ def test_expected_events_are_emitted_in_order(self):
             'building-command-table.main',
             'building-top-level-params',
             'top-level-args-parsed',
+            'session-initialized',
             'building-command-table.s3',
             'building-argument-table.s3.list-objects',
             'before-building-argument-table-parser.s3.list-objects',