Skip to content

Commit

Permalink
Try to detect encoding
Browse files Browse the repository at this point in the history
  • Loading branch information
avirshup committed Jun 19, 2017
2 parents 41d65b0 + 5852f52 commit f632d1d
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 67 deletions.
2 changes: 1 addition & 1 deletion pyccc/files/bytecontainer.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ def open(self, mode='r', encoding=None):

if access_type == 't' and encoding is not None and encoding != self.encoded_with:
warnings.warn('Attempting to decode %s as "%s", but encoding is declared as "%s"'
%(self, encoding, self.encoded_with))
% (self, encoding, self.encoded_with))

if encoding is None:
encoding = self.encoded_with
Expand Down
2 changes: 2 additions & 0 deletions pyccc/picklers.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ def persistent_id(self, obj):
"""
if getattr(obj, '_persistent_ref', None) is not None:
return obj._persistent_ref
else:
return None


class ReturningUnpickler(pickle.Unpickler):
Expand Down
90 changes: 24 additions & 66 deletions pyccc/source_inspections.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,21 @@
"""
Source code inspections for sending python code to workers
"""
from __future__ import print_function, unicode_literals, absolute_import, division
from __future__ import print_function, absolute_import, division

from future import standard_library, builtins
standard_library.install_aliases()
from future.builtins import *

from future.utils import PY2

import inspect
import linecache
import re
import string

__author__ = 'aaronvirshup'
from .backports import getclosurevars
if PY2:
from .backports import detect_encoding


def get_global_vars(func):
Expand All @@ -36,7 +39,6 @@ def get_global_vars(func):
Returns:
dict: mapping of variable names to globally bound VARIABLES
dict: mapping of variable names to globally bound MODULES
"""
closure = getclosurevars(func)
if closure['nonlocal']:
Expand Down Expand Up @@ -79,7 +81,13 @@ def getsource(classorfunc):

declaration = []

sourcelines = iter(source.splitlines())
lines = source.splitlines()
#if PY2 and not isinstance(source, unicode):
# encoding = detect_encoding(iter(lines).next)
#else:
# encoding = None

sourcelines = iter(lines)

# First, get the declaration
found_keyword = False
Expand Down Expand Up @@ -153,6 +161,11 @@ def getsourcefallback(cls):
name = cls.__name__
pat = re.compile(r'^(\s*)class\s*'+name+r'\b')

# AMVMOD: find the encoding (necessary for python 2 only)
#if PY2:
# with open(file, 'rb') as infile:
# encoding = detect_encoding(infile.readline)[0]

# make some effort to find the best matching class definition:
# use the one with the least indentation, which is the one
# that's most probably not inside a function definition.
Expand All @@ -177,70 +190,14 @@ def getsourcefallback(cls):
raise IOError('could not find class definition')
### end modified inspect.findsource ###

#### this is what inspect.getsourcelines does ###
# this is what inspect.getsourcelines does
glines = inspect.getblock(flines[flnum:])

### And this is what inspect.getsource does ###
return string.join(glines, "")


def getclosurevars(func):
"""
NOTE: this is "backported" (copied verbatim) from the python3 inspect module
Get the mapping of free variables to their current values.
Returns a named tuple of dicts mapping the current nonlocal, global
and builtin references as seen by the body of the function. A final
set of unbound names that could not be resolved is also provided.
"""

if inspect.ismethod(func):
func = func.__func__

elif not inspect.isroutine(func):
raise TypeError("'{!r}' is not a Python function".format(func))

# AMVMOD: deal with python 2 builtins that don't define these
code = getattr(func, '__code__', None)
closure = getattr(func, '__closure__', None)
co_names = getattr(code, 'co_names', ())
glb = getattr(func, '__globals__', {})

# Nonlocal references are named in co_freevars and resolved
# by looking them up in __closure__ by positional index
if closure is None:
nonlocal_vars = {}
# And this is what inspect.getsource does
if False: #if PY2:
return ("".join(glines)).decode(encoding)
else:
nonlocal_vars = {var: cell.cell_contents
for var, cell in zip(code.co_freevars, func.__closure__)}

# Global and builtin references are named in co_names and resolved
# by looking them up in __globals__ or __builtins__
global_ns = glb
builtin_ns = global_ns.get("__builtins__", builtins.__dict__)
if inspect.ismodule(builtin_ns):
builtin_ns = builtin_ns.__dict__
global_vars = {}
builtin_vars = {}
unbound_names = set()
for name in co_names:
if name in ("None", "True", "False"):
# Because these used to be builtins instead of keywords, they
# may still show up as name references. We ignore them.
continue
try:
global_vars[name] = global_ns[name]
except KeyError:
try:
builtin_vars[name] = builtin_ns[name]
except KeyError:
unbound_names.add(name)

return {'nonlocal': nonlocal_vars,
'global': global_vars,
'builtin': builtin_vars,
'unbound': unbound_names}
return "".join(glines)


def _isbuiltin(obj):
Expand All @@ -250,3 +207,4 @@ def _isbuiltin(obj):
return True
else:
return False

0 comments on commit f632d1d

Please sign in to comment.