Skip to content

Commit

Permalink
Finished release 3.2.1.
Browse files Browse the repository at this point in the history
  • Loading branch information
htgoebel committed Jan 15, 2017
2 parents e98b70e + 5b6315b commit 5b84a8d
Show file tree
Hide file tree
Showing 140 changed files with 10,218 additions and 2,670 deletions.
2 changes: 1 addition & 1 deletion .pylintrc
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[MASTER]
# Add files or directories to the blacklist. They should be base names, not
# paths.
ignore=CVS,altgraph,macholib,pefile.py,six.py,unittest2,pefile_py2.py,pefile_py3.py,ordlookup,modulegraph
ignore=CVS,altgraph,macholib,pefile.py,six.py,unittest2,ordlookup,modulegraph
[BASIC]
# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_,hiddenimports,binaries,datas,excludedimports
Expand Down
17 changes: 6 additions & 11 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ os:
#- osx

env:
# shorten logging of pip-accel
- PIP_ACCEL_LOG_FORMAT="%(name)-18s %(levelname)s %(message)s"
# - PYCRYPTO_VERSION=2.4.1
# - PYCRYPTO_VERSION=2.6.1

Expand Down Expand Up @@ -65,22 +63,19 @@ before_install:


install:
# Update pip.
- python -m pip install -U pip
# Install PyInstaller.
- pip install -e .

# Install dependencies for tests. Use pip-accel to cache compiled
# packages and safe recompiling each time.
# Download-progress bars break Travis's log view. Disable them by
# piping output through another program (if output is not a tty, no
# progress bars)
- pip install pip-accel | cat
- pip-accel install -r tests/requirements-tools.txt | cat
- pip-accel install -r tests/requirements-linux.txt | cat
# Install dependencies for tests.
- pip install -U -r tests/requirements-tools.txt
- pip install -U -r tests/requirements-linux.txt

script:
# Run tests and speed them up by sending them to multiple CPUs.
# Run unitttest first.
- py.test -n 5 --maxfail 3 tests/unit/ tests/
- py.test -n 3 --maxfail 3 tests/unit/ tests/

notifications:
irc:
Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ prune doc/source
prune old
prune scripts
prune tests/scripts
prune .github

exclude .* *.yml
global-exclude *.py[co]
2 changes: 1 addition & 1 deletion PyInstaller/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@

# Note: Keep this variable as plain string so it could be updated automatically
# when doing a release.
__version__ = '3.2'
__version__ = '3.2.1'


# Absolute path of this package's directory. Save this early so all
Expand Down
5 changes: 4 additions & 1 deletion PyInstaller/archive/writers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@

from PyInstaller.building.utils import get_code_object, strip_paths_in_code
from .readers import PYZ_TYPE_MODULE, PYZ_TYPE_PKG, PYZ_TYPE_DATA
from ..compat import BYTECODE_MAGIC
from ..compat import BYTECODE_MAGIC, is_py2


class ArchiveWriter(object):
Expand Down Expand Up @@ -246,6 +246,9 @@ def tobinary(self):
# standard python modules only contain ascii-characters
# (and standard shared libraries should have the same) and
# thus the C-code still can handle this correctly.
if is_py2 and isinstance(nm, str):
nm = nm.decode(sys.getfilesystemencoding())

nm = nm.encode('utf-8')
nmlen = len(nm) + 1 # add 1 for a '\0'
# align to 16 byte boundary so xplatform C can read
Expand Down
Binary file modified PyInstaller/bootloader/Darwin-64bit/run
Binary file not shown.
Binary file modified PyInstaller/bootloader/Darwin-64bit/run_d
Binary file not shown.
Binary file modified PyInstaller/bootloader/Darwin-64bit/runw
Binary file not shown.
Binary file modified PyInstaller/bootloader/Darwin-64bit/runw_d
Binary file not shown.
Binary file modified PyInstaller/bootloader/Linux-32bit/run
Binary file not shown.
Binary file modified PyInstaller/bootloader/Linux-32bit/run_d
Binary file not shown.
Binary file modified PyInstaller/bootloader/Linux-64bit/run
Binary file not shown.
Binary file modified PyInstaller/bootloader/Linux-64bit/run_d
Binary file not shown.
Binary file modified PyInstaller/bootloader/Windows-32bit/run.exe
Binary file not shown.
Binary file modified PyInstaller/bootloader/Windows-32bit/run_d.exe
Binary file not shown.
Binary file modified PyInstaller/bootloader/Windows-32bit/runw.exe
Binary file not shown.
Binary file modified PyInstaller/bootloader/Windows-32bit/runw_d.exe
Binary file not shown.
Binary file modified PyInstaller/bootloader/Windows-64bit/run.exe
Binary file not shown.
Binary file modified PyInstaller/bootloader/Windows-64bit/run_d.exe
Binary file not shown.
Binary file modified PyInstaller/bootloader/Windows-64bit/runw.exe
Binary file not shown.
Binary file modified PyInstaller/bootloader/Windows-64bit/runw_d.exe
Binary file not shown.
16 changes: 13 additions & 3 deletions PyInstaller/building/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,8 @@ def assemble(self):
}

pyz = ZlibArchiveWriter(self.name, toc, code_dict=self.code_dict, cipher=self.cipher)
logger.info("Building PYZ (ZlibArchive) %s completed successfully.",
self.name)


class PKG(Target):
Expand Down Expand Up @@ -275,6 +277,8 @@ def assemble(self):

for item in trash:
os.remove(item)
logger.info("Building PKG (CArchive) %s completed successfully.",
os.path.basename(self.name))


class EXE(Target):
Expand Down Expand Up @@ -558,8 +562,10 @@ def assemble(self):
'objcopy', '--add-section', 'pydata=%s' % self.pkg.name,
self.name)
logger.debug("objcopy returned %i", retcode)
logger.debug(stdout)
logger.debug(stderr)
if stdout:
logger.debug(stdout)
if stderr:
logger.debug(stderr)
if retcode != 0:
raise SystemError("objcopy Failure: %s" % stderr)
else:
Expand All @@ -584,6 +590,8 @@ def assemble(self):
self.mtm = misc.mtime(self.name)
for item in trash:
os.remove(item)
logger.info("Building EXE from %s completed successfully.",
self.tocbasename)


def _copyfile(self, infile, outfile):
Expand Down Expand Up @@ -680,6 +688,8 @@ def assemble(self):
logger.warn("failed to copy flags of %s", fnm)
if typ in ('EXTENSION', 'BINARY'):
os.chmod(tofnm, 0o755)
logger.info("Building COLLECT %s completed successfully.",
self.tocbasename)


class MERGE(object):
Expand Down Expand Up @@ -763,6 +773,6 @@ def _get_relative_path(self, startpath, topath):

_MISSING_BOOTLOADER_ERRORMSG = """
Fatal error: PyInstaller does not include a pre-compiled bootloader for your
platform. See <http://pythonhosted.org/PyInstaller/#building-the-bootloader>
platform. See <http://pyinstaller.rtfd.io/en/stable/bootloader-building.html>
for more details and instructions how to build the bootloader.
"""
77 changes: 30 additions & 47 deletions PyInstaller/building/datastruct.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,30 +20,23 @@
logger = logging.getLogger(__name__)


class FilenameSet(MutableSet):
def unique_name(entry):
"""
Used by TOC to contain a unique set of filenames, even on case-insensitive systems.
"""
def __init__(self, arg=None):
if arg:
self._set = set(arg)
else:
self._set = set()

def __contains__(self, name):
return os.path.normcase(name) in self._set

def __len__(self):
return len(self._set)
Return the filename used to enforce uniqueness for the given TOC entry
def __iter__(self):
return iter(self._set)
Parameters
----------
entry : tuple
def add(self, name):
self._set.add(os.path.normcase(name))
Returns
-------
unique_name: str
"""
name, path, typecode = entry
if typecode in ('BINARY', 'DATA'):
name = os.path.normcase(name)

def discard(self, name):
self._set.discard(os.path.normcase(name))
return name


class TOC(list):
Expand All @@ -67,7 +60,7 @@ class TOC(list):
"""
def __init__(self, initlist=None):
super(TOC, self).__init__(self)
self.filenames = FilenameSet()
self.filenames = set()
if initlist:
for entry in initlist:
self.append(entry)
Expand All @@ -76,25 +69,22 @@ def append(self, entry):
if not isinstance(entry, tuple):
logger.info("TOC found a %s, not a tuple", entry)
raise TypeError("Expected tuple, not %s." % type(entry).__name__)
name, path, typecode = entry
if name not in self.filenames:
self.filenames.add(name)
super(TOC, self).append((name, path, typecode))
else:
if typecode in ('EXTENSION', 'PYSOURCE', 'PYMODULE') and name != os.path.normcase(name):
logger.warn("Attempted to add Python module twice with different upper/lowercases: %s", name)

unique = unique_name(entry)

if unique not in self.filenames:
self.filenames.add(unique)
super(TOC, self).append(entry)

def insert(self, pos, entry):
if not isinstance(entry, tuple):
logger.info("TOC found a %s, not a tuple", entry)
raise TypeError("Expected tuple, not %s." % type(entry).__name__)
name, path, typecode = entry
if name not in self.filenames:
self.filenames.add(name)
super(TOC, self).insert(pos, (name, path, typecode))
else:
if typecode in ('EXTENSION', 'PYSOURCE', 'PYMODULE') and name != os.path.normcase(name):
logger.warn("Attempted to add Python module twice with different upper/lowercases: %s", name)
unique = unique_name(entry)

if unique not in self.filenames:
self.filenames.add(unique)
super(TOC, self).insert(pos, entry)

def __add__(self, other):
result = TOC(self)
Expand All @@ -116,24 +106,17 @@ def __sub__(self, other):
other = TOC(other)
filenames = self.filenames - other.filenames
result = TOC()
for name, path, typecode in self:
if name in filenames:
super(TOC, result).append((name, path, typecode))
for entry in self:
unique = unique_name(entry)

if unique in filenames:
super(TOC, result).append(entry)
return result

def __rsub__(self, other):
result = TOC(other)
return result.__sub__(self)

def intersect(self, other):
other = TOC(other)
filenames = self.filenames.intersection(other.filenames)
result = TOC()
for name, path, typecode in other:
if name in filenames:
super(TOC, result).append((name, path, typecode))
return result


class Target(object):
invcnum = 0
Expand Down
2 changes: 1 addition & 1 deletion PyInstaller/building/imphook.py
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ def _process_hidden_imports(self):
self.module_name, create_nspkg=False)

# Manually import this hidden import from this module.
self.module_graph.import_hook(import_module_name, caller=caller)
self.module_graph.import_hook(import_module_name, caller)
# If this hidden import is unimportable, print a non-fatal warning.
# Hidden imports often become desynchronized from upstream packages
# and hence are only "soft" recommendations.
Expand Down
83 changes: 68 additions & 15 deletions PyInstaller/building/imphookapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
"""

from .datastruct import TOC
from ..lib.modulegraph.modulegraph import RuntimeModule
from ..lib.modulegraph.modulegraph import RuntimeModule, RuntimePackage


class PreSafeImportModuleAPI(object):
Expand Down Expand Up @@ -105,23 +105,69 @@ def parent_package(self):
return self._parent_package


def add_runtime_module(self, fully_qualified_name):
def add_runtime_module(self, module_name):
"""
Add a node representing a Python module dynamically defined at
runtime.
Add a graph node representing a non-package Python module with the
passed name dynamically defined at runtime.
Most modules are statically defined at creation time in
external Python files. Some modules, however, are dynamically
defined at runtime (e.g., `six.moves`, dynamically defined by
the statically defined `six` module). This method add a node
represents such a module.
Most modules are statically defined on-disk as standard Python files.
Some modules, however, are dynamically defined in-memory at runtime
(e.g., `gi.repository.Gst`, dynamically defined by the statically
defined `gi.repository.__init__` module).
It is typically used like this::
This method adds a graph node representing such a runtime module. Since
this module is _not_ a package, all attempts to import submodules from
this module in `from`-style import statements (e.g., the `queue`
submodule in `from six.moves import queue`) will be silently ignored. To
circumvent this, simply call `add_runtime_package()` instead.
api.add_runtime_module(api.module_name)
Parameters
----------
module_name : str
Fully-qualified name of this module (e.g., `gi.repository.Gst`).
Examples
----------
This method is typically called by `pre_safe_import_module()` hooks:
e.g.,
def pre_safe_import_module(api):
api.add_runtime_module(api.module_name)
"""

self._module_graph.add_module(RuntimeModule(module_name))


def add_runtime_package(self, package_name):
"""
self._module_graph.add_module(RuntimeModule(fully_qualified_name))
Add a graph node representing a non-namespace Python package with the
passed name dynamically defined at runtime.
Most packages are statically defined on-disk as standard subdirectories
containing `__init__.py` files. Some packages, however, are dynamically
defined in-memory at runtime (e.g., `six.moves`, dynamically defined by
the statically defined `six` module).
This method adds a graph node representing such a runtime package. All
attributes imported from this package in `from`-style import statements
that are submodules of this package (e.g., the `queue` submodule in
`from six.moves import queue`) will be imported rather than ignored.
Parameters
----------
package_name : str
Fully-qualified name of this package (e.g., `six.moves`).
Examples
----------
This method is typically called by `pre_safe_import_module()` hooks:
e.g.,
def pre_safe_import_module(api):
api.add_runtime_package(api.module_name)
"""

self._module_graph.add_module(RuntimePackage(package_name))


def add_alias_module(self, real_module_name, alias_module_name):
Expand All @@ -142,18 +188,25 @@ def add_alias_module(self, real_module_name, alias_module_name):
Fully-qualified name of the **non-existent module** (i.e.,
the alias to be created).
"""

self._module_graph.alias_module(real_module_name, alias_module_name)


def append_package_path(self, directory):
"""
Modulegraph does a good job at simulating Python's, but it can not
handle packagepath __path__ modifications packages make at runtime.
Modulegraph does a good job at simulating Python's, but it cannot
handle packagepath `__path__` modifications packages make at runtime.
Therefore there is a mechanism whereby you can register extra paths
in this map for a package, and it will be honored.
:param directory: directory to append to the __path__ attribute.
Parameters
----------
directory : str
Absolute or relative path of the directory to be appended to this
package's `__path__` attribute.
"""

self._module_graph.append_package_path(self._module_name, directory)


Expand Down
Loading

0 comments on commit 5b84a8d

Please sign in to comment.