Repository: xonsh/xonsh

Issue:
Using `source` on master prints `DeprecationWarning` for `execx`
<!--- Provide a general summary of the issue in the Title above -->
<!--- If you have a question along the lines of "How do I do this Bash command in xonsh"
please first look over the Bash to Xonsh translation guide: http://xon.sh/bash_to_xsh.html
If you don't find an answer there, please do open an issue! -->

## xonfig
<!--- Please post the output of the `xonfig` command (run from inside xonsh) so we know more about your current setup -->
```
+------------------+---------------------+
| xonsh            | 0.7.10.dev63        |
| Git SHA          | 2286a598            |
| Commit Date      | Oct 2 08:54:29 2018 |
| Python           | 3.6.5               |
| PLY              | 3.11                |
| have readline    | True                |
| prompt toolkit   | 2.0.5               |
| shell type       | prompt_toolkit2     |
| pygments         | 2.2.0               |
| on posix         | True                |
| on linux         | False               |
| on darwin        | True                |
| on windows       | False               |
| on cygwin        | False               |
| on msys2         | False               |
| is superuser     | False               |
| default encoding | utf-8               |
| xonsh encoding   | utf-8               |
| encoding errors  | surrogateescape     |
+------------------+---------------------+
```

## Expected Behavior
You source a file and it is sourced

## Current Behavior
A deprecation error is printed

## Steps to Reproduce
```
~/tmp/cleandir 88e2064 $ cat test.xsh
print('hi')
~/tmp/cleandir 88e2064 $ source test.xsh
/home/gil/miniconda3/lib/python3.6/site-packages/xonsh/built_ins.py:1410: DeprecationWarning: execx has been deprecated, please use __xonsh__.builtins.execx instead.
  DeprecationWarning,
hi
```


Discussion:
I believe this is the culprit: https://github.com/xonsh/xonsh/blob/master/xonsh/aliases.py#L403

Resolving patch:
diff --git a/xonsh/built_ins.py b/xonsh/built_ins.py
--- a/xonsh/built_ins.py
+++ b/xonsh/built_ins.py
@@ -1387,15 +1387,59 @@ def __init__(self, execer=None):
         self.events = events
 
 
-class ProxyWarning:
-    def __init__(self, badname, goodname):
-        super().__setattr__("badname", badname)
-        super().__setattr__("goodname", goodname)
+class DynamicAccessProxy:
+    """Proxies access dynamically."""
+
+    def __init__(self, refname, objname):
+        """
+        Parameters
+        ----------
+        refname : str
+            '.'-separated string that represents the new, reference name that
+            the user will access.
+        objname : str
+            '.'-separated string that represents the name where the target
+            object actually lives that refname points to.
+        """
+        super().__setattr__("refname", refname)
+        super().__setattr__("objname", objname)
 
     @property
     def obj(self):
         """Dynamically grabs object"""
-        names = self.goodname.split(".")
+        names = self.objname.split(".")
+        obj = builtins
+        for name in names:
+            obj = getattr(obj, name)
+        return obj
+
+    def __getattr__(self, name):
+        return getattr(self.obj, name)
+
+    def __setattr__(self, name, value):
+        return super().__setattr__(self.obj, name, value)
+
+    def __getitem__(self, item):
+        return self.obj.__getitem__(item)
+
+    def __setitem__(self, item, value):
+        return self.obj.__setitem__(item, value)
+
+    def __call__(self, *args, **kwargs):
+        return self.obj.__call__(*args, **kwargs)
+
+
+class DeprecationWarningProxy:
+    """Proxies access, but warns in the process."""
+
+    def __init__(self, oldname, newname):
+        super().__setattr__("oldname", oldname)
+        super().__setattr__("newname", newname)
+
+    @property
+    def obj(self):
+        """Dynamically grabs object"""
+        names = self.newname.split(".")
         obj = builtins
         for name in names:
             obj = getattr(obj, name)
@@ -1405,7 +1449,7 @@ def warn(self):
         """Issues deprecation warning."""
         warnings.warn(
             "{} has been deprecated, please use {} instead.".format(
-                self.badname, self.goodname
+                self.oldname, self.newname
             ),
             DeprecationWarning,
         )
@@ -1432,15 +1476,27 @@ def __call__(self, *args, **kwargs):
 
 
 def load_proxies():
-    """Put temporary shims in place for `__xonsh_*__` builtins.
-
+    """Loads builtin dynamic access proxies.
+    Also puts temporary shims in place for `__xonsh_*__` builtins.
     """
-    mapping = {
+    proxy_mapping = {
+        "XonshError": "__xonsh__.builtins.XonshError",
+        "XonshCalledProcessError": "__xonsh__.builtins.XonshCalledProcessError",
+        "evalx": "__xonsh__.builtins.evalx",
+        "execx": "__xonsh__.builtins.execx",
+        "compilex": "__xonsh__.builtins.compilex",
+        "events": "__xonsh__.builtins.events",
+    }
+    for refname, objname in proxy_mapping.items():
+        proxy = DynamicAccessProxy(refname, objname)
+        setattr(builtins, refname, proxy)
+
+    deprecated_mapping = {
         "__xonsh_env__": "__xonsh__.env",
         "__xonsh_history__": "__xonsh__.history",
         "__xonsh_ctx__": "__xonsh__.ctx",
         "__xonsh_help__": "__xonsh__.help",
-        "builtins": "builtins.superhelp",
+        "__xonsh_superhelp__": "__xonsh__.superhelp",
         "__xonsh_pathsearch__": "__xonsh__.pathsearch",
         "__xonsh_globsearch__": "__xonsh__.globsearch",
         "__xonsh_regexsearch__": "__xonsh__.regexsearch",
@@ -1464,24 +1520,17 @@ def load_proxies():
         "__xonsh_call_macro__": "__xonsh__.call_macro",
         "__xonsh_enter_macro__": "__xonsh__.enter_macro",
         "__xonsh_path_literal__": "__xonsh__.path_literal",
-        "XonshError": "__xonsh__.builtins.XonshError",
-        "XonshCalledProcessError": "__xonsh__.builtins.XonshCalledProcessError",
-        "evalx": "__xonsh__.builtins.evalx",
-        "execx": "__xonsh__.builtins.execx",
-        "compilex": "__xonsh__.builtins.compilex",
-        "events": "__xonsh__.builtins.events",
     }
-
-    for badname, goodname in mapping.items():
-        proxy = ProxyWarning(badname, goodname)
+    for badname, goodname in deprecated_mapping.items():
+        proxy = DeprecationWarningProxy(badname, goodname)
         setattr(builtins, badname, proxy)
 
     if hasattr(builtins.__xonsh__, "pyexit"):
-        builtins.__xonsh_pyexit__ = ProxyWarning(
+        builtins.__xonsh_pyexit__ = DeprecationWarningProxy(
             "builtins.__xonsh_pyexit__", "builtins.__xonsh__.pyexit"
         )
     if hasattr(builtins.__xonsh__, "quit"):
-        builtins.__xonsh_pyquit__ = ProxyWarning(
+        builtins.__xonsh_pyquit__ = DeprecationWarningProxy(
             "builtins.__xonsh_pyquit__", "builtins.__xonsh__.pyquit"
         )
 


Test patch: