Repository: ansible/ansible

Issue:
referencing variable out of scope
https://github.com/ansible/ansible/blob/f2ade09dce0e65187e6d213fd02e5341353c246e/lib/ansible/module_utils/basic.py#L2542

In the following code:
```
            try:
                out_dest = open(dest, 'wb')
                in_src = open(src, 'rb')
                shutil.copyfileobj(in_src, out_dest)
            finally:  # assuring closed files in 2.4 compatible way
                if out_dest:
                    out_dest.close()
```
If the first `open` raises an exception, then the `if out_dest` fails with either a "trying to reference undefined variable" or a "dereferencing variable before assignment" error, depending on the python version I guess. I ran into this corner case in a situation that's a bit hard to recreate while using lineinfile and unsafe writes. However, you can test a simplified version of this code in interactive python to see that the issue does exist (works for me with python 2.7).

##### SUMMARY
referencing undefined variable

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
module_utils/basic.py

##### ANSIBLE VERSION
master

##### OS / ENVIRONMENT
OSX

##### STEPS TO REPRODUCE





Discussion:
@lavie Greetings! Thanks for taking the time to open this issue. In order for the community to handle your issue effectively, we need a bit more information. 

Here are the items we could not find in your description:
- issue type
- ansible version
- component name

Please set the description of this issue with this template:
https://raw.githubusercontent.com/ansible/ansible/devel/.github/ISSUE_TEMPLATE.md

[click here for bot help](https://github.com/ansible/ansibullbot/blob/master/ISSUE_HELP.md)
<!--- boilerplate: issue_missing_data --->
<!---
Verify first that your issue/request is not already reported on GitHub.
Also test if the latest release, and master branch are affected too.
-->

##### ISSUE TYPE
 - Bug Report

##### COMPONENT NAME
module_utils/basic.py

##### ANSIBLE VERSION
master

##### CONFIGURATION


##### OS / ENVIRONMENT
OSX

##### SUMMARY
referencing undefined variable

##### STEPS TO REPRODUCE
https://github.com/ansible/ansible/blob/f2ade09dce0e65187e6d213fd02e5341353c246e/lib/ansible/module_utils/basic.py#L2542

In the following code:
```
            try:
                out_dest = open(dest, 'wb')
                in_src = open(src, 'rb')
                shutil.copyfileobj(in_src, out_dest)
            finally:  # assuring closed files in 2.4 compatible way
                if out_dest:
                    out_dest.close()
```
If the first `open` raises an exception, then the `if out_dest` fails with either a "trying to reference undefined variable" or a "dereferencing variable before assignment" error, depending on the python version I guess. I ran into this corner case in a situation that's a bit hard to recreate while using lineinfile and unsafe writes. However, you can test a simplified version of this code in interactive python to see that the issue does exist (works for me with python 2.7).


(I updated the initial bug comment with info from https://github.com/ansible/ansible/issues/31786#issuecomment-336899145)
pinging @bcoca, @abadger (basic.py atomic_move/_unsafe_writes)

Resolving patch:
diff --git a/lib/ansible/module_utils/basic.py b/lib/ansible/module_utils/basic.py
--- a/lib/ansible/module_utils/basic.py
+++ b/lib/ansible/module_utils/basic.py
@@ -2538,6 +2538,7 @@ def _unsafe_writes(self, src, dest):
         # sadly there are some situations where we cannot ensure atomicity, but only if
         # the user insists and we get the appropriate error we update the file unsafely
         try:
+            out_dest = in_src = None
             try:
                 out_dest = open(dest, 'wb')
                 in_src = open(src, 'rb')


Test patch: