diff --git a/.travis.yml b/.travis.yml index 4ab9805..b0eb60e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,34 +1,29 @@ language: python -sudo: false + python: -- '2.7' -- '3.5' -before_install: -- if [[ "$TRAVIS_PYTHON_VERSION" == "2.7" ]]; then wget http://repo.continuum.io/miniconda/Miniconda-latest-Linux-x86_64.sh - -O miniconda.sh; else wget http://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh - -O miniconda.sh; fi -- bash miniconda.sh -b -p $HOME/miniconda -- export PATH="$HOME/miniconda/bin:$PATH" -- hash -r -- conda config --set always_yes yes --set changeps1 no -- conda update -q conda -- conda info -a -- | - conda create -q -n test-environment python=$TRAVIS_PYTHON_VERSION cytoolz flask pandas pip pygments pytables pytest six -- source activate test-environment -- pip install pytest-cov coveralls pycodestyle -- bin/build_js_bundle.sh complete + - '2.7' + - '3.5' + - '3.6' + - '3.7' + # - '3.8' broken because PyTables binaries aren't available yet + install: -- pip install . + - pip install . + - pip install pytest-cov coveralls pycodestyle + - pip install flask pygments # for server component tests + - bin/build_js_bundle.sh complete + - pip install numpydoc sphinx sphinx_rtd_theme # for building docs + - pip list + - pip show orca + script: -- pycodestyle orca -- py.test --cov orca --cov-report term-missing + - pycodestyle orca + - py.test --cov orca --cov-report term-missing + after_success: -- coveralls -- bin/build_docs.sh -notifications: - slack: - secure: c4s/7CYpc0qaPdjEUXrX3b04gKfbpHcGz3JV8wEGOZAIvBSILGQTsQ/JD9i8b8r/MKH7Ofj8ZEvgi7TZoa40rv6GFo3beUJezeHd98B5JIVa3mKIvtzZ9BJZFpIs/tUobsuZpOH3eHh/D1HaX3mcg87ys0qB7UeIiEJqltrUMv0= + - coveralls + - bin/build_docs.sh + env: global: secure: DMQgAnged8quDKf3pTLG6RZVMKhrhZfYSRKaPFJrERXEOuRPJjC4QYG24pdyCV2aOQbSOiF16vSctpDmMfjLDARkhNm8FvYYCOKLkE+4ijQ4vE/uQaHsnosGS/1LOOFGjK0h2dvm4CNJqV1JUhCKeOVe/87GGY2JVBy+NJnsl70= diff --git a/HISTORY.rst b/HISTORY.rst index 1792656..4396744 100644 --- a/HISTORY.rst +++ b/HISTORY.rst @@ -1,3 +1,8 @@ +v1.5.2 +====== + +* Updated requirements to streamline installation. + v1.5.1 ====== diff --git a/LICENSE b/LICENSE.txt similarity index 96% rename from LICENSE rename to LICENSE.txt index 88f4515..8842884 100644 --- a/LICENSE +++ b/LICENSE.txt @@ -1,4 +1,4 @@ -Copyright (c) 2016, UrbanSim Inc. All rights reserved. +Copyright (c) 2019, UrbanSim Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: diff --git a/README.rst b/README.rst index f5f9e11..9959222 100644 --- a/README.rst +++ b/README.rst @@ -5,10 +5,6 @@ Orca :target: https://pypi.python.org/pypi/orca/ :alt: PyPI Latest Version -.. image:: https://img.shields.io/pypi/pyversions/orca.svg - :target: https://pypi.python.org/pypi/orca/ - :alt: Supported Python versions - .. image:: https://travis-ci.org/UDST/orca.svg?branch=master :target: https://travis-ci.org/UDST/orca :alt: Build Status diff --git a/appveyor.yml b/appveyor.yml deleted file mode 100644 index 0e1f32d..0000000 --- a/appveyor.yml +++ /dev/null @@ -1,26 +0,0 @@ -build: false - -environment: - matrix: - - PYTHON_VERSION: 2.7 - MINICONDA: C:\Miniconda - - PYTHON_VERSION: 3.5 - MINICONDA: C:\Miniconda3 - - -init: - - "ECHO %PYTHON_VERSION% %MINICONDA%" - -install: - - "set PATH=%MINICONDA%;%MINICONDA%\\Scripts;%PATH%" - - conda config --set always_yes yes --set changeps1 no - - conda update -q conda - - conda info -a - - "conda create -q -n test-environment python=%PYTHON_VERSION% cytoolz flask pandas pip pygments pytables pytest six" - - activate test-environment - - pip install pycodestyle - - pip install . - -test_script: - - pycodestyle orca - - pytest orca \ No newline at end of file diff --git a/bin/build_docs.sh b/bin/build_docs.sh index 8c894e8..b0e9d08 100755 --- a/bin/build_docs.sh +++ b/bin/build_docs.sh @@ -33,10 +33,6 @@ if [ "$TRAVIS_REPO_SLUG" == "UDST/orca" ] && \ [ "$TRAVIS_PULL_REQUEST" == "false" ] && \ [ "$ACTUAL_TRAVIS_JOB_NUMBER" == "1" ]; then - echo "Installing dependencies" - conda install --yes --quiet sphinx numpydoc - pip install sphinx_rtd_theme - echo "Building docs" cd docs make clean diff --git a/docs/conf.py b/docs/conf.py index de6bb27..64c24cf 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -51,7 +51,7 @@ # General information about the project. project = 'Orca' -copyright = '2017, UrbanSim Inc' +copyright = '2019, UrbanSim Inc' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -60,7 +60,7 @@ # The short X.Y version. version = '1.5' # The full version, including alpha/beta/rc tags. -release = '1.5.1' +release = '1.5.2' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/ez_setup.py b/ez_setup.py deleted file mode 100644 index a34fa80..0000000 --- a/ez_setup.py +++ /dev/null @@ -1,332 +0,0 @@ -#!/usr/bin/env python -"""Bootstrap setuptools installation - -To use setuptools in your package's setup.py, include this -file in the same directory and add this to the top of your setup.py:: - - from ez_setup import use_setuptools - use_setuptools() - -To require a specific version of setuptools, set a download -mirror, or use an alternate download directory, simply supply -the appropriate options to ``use_setuptools()``. - -This file can also be run as a script to install or upgrade setuptools. -""" -import os -import shutil -import sys -import tempfile -import zipfile -import optparse -import subprocess -import platform -import textwrap -import contextlib - -from distutils import log - -try: - from urllib.request import urlopen -except ImportError: - from urllib2 import urlopen - -try: - from site import USER_SITE -except ImportError: - USER_SITE = None - -DEFAULT_VERSION = "5.7" -DEFAULT_URL = "https://pypi.python.org/packages/source/s/setuptools/" - -def _python_cmd(*args): - """ - Return True if the command succeeded. - """ - args = (sys.executable,) + args - return subprocess.call(args) == 0 - - -def _install(archive_filename, install_args=()): - with archive_context(archive_filename): - # installing - log.warn('Installing Setuptools') - if not _python_cmd('setup.py', 'install', *install_args): - log.warn('Something went wrong during the installation.') - log.warn('See the error message above.') - # exitcode will be 2 - return 2 - - -def _build_egg(egg, archive_filename, to_dir): - with archive_context(archive_filename): - # building an egg - log.warn('Building a Setuptools egg in %s', to_dir) - _python_cmd('setup.py', '-q', 'bdist_egg', '--dist-dir', to_dir) - # returning the result - log.warn(egg) - if not os.path.exists(egg): - raise IOError('Could not build the egg.') - - -class ContextualZipFile(zipfile.ZipFile): - """ - Supplement ZipFile class to support context manager for Python 2.6 - """ - - def __enter__(self): - return self - - def __exit__(self, type, value, traceback): - self.close() - - def __new__(cls, *args, **kwargs): - """ - Construct a ZipFile or ContextualZipFile as appropriate - """ - if hasattr(zipfile.ZipFile, '__exit__'): - return zipfile.ZipFile(*args, **kwargs) - return super(ContextualZipFile, cls).__new__(cls) - - -@contextlib.contextmanager -def archive_context(filename): - # extracting the archive - tmpdir = tempfile.mkdtemp() - log.warn('Extracting in %s', tmpdir) - old_wd = os.getcwd() - try: - os.chdir(tmpdir) - with ContextualZipFile(filename) as archive: - archive.extractall() - - # going in the directory - subdir = os.path.join(tmpdir, os.listdir(tmpdir)[0]) - os.chdir(subdir) - log.warn('Now working in %s', subdir) - yield - - finally: - os.chdir(old_wd) - shutil.rmtree(tmpdir) - - -def _do_download(version, download_base, to_dir, download_delay): - egg = os.path.join(to_dir, 'setuptools-%s-py%d.%d.egg' - % (version, sys.version_info[0], sys.version_info[1])) - if not os.path.exists(egg): - archive = download_setuptools(version, download_base, - to_dir, download_delay) - _build_egg(egg, archive, to_dir) - sys.path.insert(0, egg) - - # Remove previously-imported pkg_resources if present (see - # https://bitbucket.org/pypa/setuptools/pull-request/7/ for details). - if 'pkg_resources' in sys.modules: - del sys.modules['pkg_resources'] - - import setuptools - setuptools.bootstrap_install_from = egg - - -def use_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, - to_dir=os.curdir, download_delay=15): - to_dir = os.path.abspath(to_dir) - rep_modules = 'pkg_resources', 'setuptools' - imported = set(sys.modules).intersection(rep_modules) - try: - import pkg_resources - except ImportError: - return _do_download(version, download_base, to_dir, download_delay) - try: - pkg_resources.require("setuptools>=" + version) - return - except pkg_resources.DistributionNotFound: - return _do_download(version, download_base, to_dir, download_delay) - except pkg_resources.VersionConflict as VC_err: - if imported: - msg = textwrap.dedent(""" - The required version of setuptools (>={version}) is not available, - and can't be installed while this script is running. Please - install a more recent version first, using - 'easy_install -U setuptools'. - - (Currently using {VC_err.args[0]!r}) - """).format(VC_err=VC_err, version=version) - sys.stderr.write(msg) - sys.exit(2) - - # otherwise, reload ok - del pkg_resources, sys.modules['pkg_resources'] - return _do_download(version, download_base, to_dir, download_delay) - -def _clean_check(cmd, target): - """ - Run the command to download target. If the command fails, clean up before - re-raising the error. - """ - try: - subprocess.check_call(cmd) - except subprocess.CalledProcessError: - if os.access(target, os.F_OK): - os.unlink(target) - raise - -def download_file_powershell(url, target): - """ - Download the file at url to target using Powershell (which will validate - trust). Raise an exception if the command cannot complete. - """ - target = os.path.abspath(target) - ps_cmd = ( - "[System.Net.WebRequest]::DefaultWebProxy.Credentials = " - "[System.Net.CredentialCache]::DefaultCredentials; " - "(new-object System.Net.WebClient).DownloadFile(%(url)r, %(target)r)" - % vars() - ) - cmd = [ - 'powershell', - '-Command', - ps_cmd, - ] - _clean_check(cmd, target) - -def has_powershell(): - if platform.system() != 'Windows': - return False - cmd = ['powershell', '-Command', 'echo test'] - with open(os.path.devnull, 'wb') as devnull: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except Exception: - return False - return True - -download_file_powershell.viable = has_powershell - -def download_file_curl(url, target): - cmd = ['curl', url, '--silent', '--output', target] - _clean_check(cmd, target) - -def has_curl(): - cmd = ['curl', '--version'] - with open(os.path.devnull, 'wb') as devnull: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except Exception: - return False - return True - -download_file_curl.viable = has_curl - -def download_file_wget(url, target): - cmd = ['wget', url, '--quiet', '--output-document', target] - _clean_check(cmd, target) - -def has_wget(): - cmd = ['wget', '--version'] - with open(os.path.devnull, 'wb') as devnull: - try: - subprocess.check_call(cmd, stdout=devnull, stderr=devnull) - except Exception: - return False - return True - -download_file_wget.viable = has_wget - -def download_file_insecure(url, target): - """ - Use Python to download the file, even though it cannot authenticate the - connection. - """ - src = urlopen(url) - try: - # Read all the data in one block. - data = src.read() - finally: - src.close() - - # Write all the data in one block to avoid creating a partial file. - with open(target, "wb") as dst: - dst.write(data) - -download_file_insecure.viable = lambda: True - -def get_best_downloader(): - downloaders = ( - download_file_powershell, - download_file_curl, - download_file_wget, - download_file_insecure, - ) - viable_downloaders = (dl for dl in downloaders if dl.viable()) - return next(viable_downloaders, None) - -def download_setuptools(version=DEFAULT_VERSION, download_base=DEFAULT_URL, - to_dir=os.curdir, delay=15, downloader_factory=get_best_downloader): - """ - Download setuptools from a specified location and return its filename - - `version` should be a valid setuptools version number that is available - as an sdist for download under the `download_base` URL (which should end - with a '/'). `to_dir` is the directory where the egg will be downloaded. - `delay` is the number of seconds to pause before an actual download - attempt. - - ``downloader_factory`` should be a function taking no arguments and - returning a function for downloading a URL to a target. - """ - # making sure we use the absolute path - to_dir = os.path.abspath(to_dir) - zip_name = "setuptools-%s.zip" % version - url = download_base + zip_name - saveto = os.path.join(to_dir, zip_name) - if not os.path.exists(saveto): # Avoid repeated downloads - log.warn("Downloading %s", url) - downloader = downloader_factory() - downloader(url, saveto) - return os.path.realpath(saveto) - -def _build_install_args(options): - """ - Build the arguments to 'python setup.py install' on the setuptools package - """ - return ['--user'] if options.user_install else [] - -def _parse_args(): - """ - Parse the command line for options - """ - parser = optparse.OptionParser() - parser.add_option( - '--user', dest='user_install', action='store_true', default=False, - help='install in user site package (requires Python 2.6 or later)') - parser.add_option( - '--download-base', dest='download_base', metavar="URL", - default=DEFAULT_URL, - help='alternative URL from where to download the setuptools package') - parser.add_option( - '--insecure', dest='downloader_factory', action='store_const', - const=lambda: download_file_insecure, default=get_best_downloader, - help='Use internal, non-validating downloader' - ) - parser.add_option( - '--version', help="Specify which version to download", - default=DEFAULT_VERSION, - ) - options, args = parser.parse_args() - # positional arguments are ignored - return options - -def main(): - """Install or upgrade setuptools and EasyInstall""" - options = _parse_args() - archive = download_setuptools( - version=options.version, - download_base=options.download_base, - downloader_factory=options.downloader_factory, - ) - return _install(archive, _build_install_args(options)) - -if __name__ == '__main__': - sys.exit(main()) diff --git a/orca/__init__.py b/orca/__init__.py index a4e55ef..3677eab 100644 --- a/orca/__init__.py +++ b/orca/__init__.py @@ -4,4 +4,4 @@ from .orca import * -version = __version__ = '1.5.1' +version = __version__ = '1.5.2' diff --git a/orca/server/static/package.json b/orca/server/static/package.json index ae1be06..47db5dd 100644 --- a/orca/server/static/package.json +++ b/orca/server/static/package.json @@ -5,7 +5,7 @@ "URIjs": "^1.15.2", "classnames": "^2.1.3", "grapnel": "^0.5.9", - "lodash": "^3.10.0", + "lodash": "^4.17.13", "react": "^0.13.3" }, "devDependencies": { diff --git a/setup.cfg b/setup.cfg index b71e189..e13865d 100644 --- a/setup.cfg +++ b/setup.cfg @@ -1,4 +1,4 @@ -[pep8] +[pycodestyle] max-line-length = 100 [bdist_wheel] diff --git a/setup.py b/setup.py index d346f72..b8436db 100644 --- a/setup.py +++ b/setup.py @@ -1,14 +1,6 @@ from __future__ import print_function import subprocess - -# Install setuptools if not installed. -try: - import setuptools -except ImportError: - from ez_setup import use_setuptools - use_setuptools() - from setuptools import setup, find_packages from setuptools.command.sdist import sdist @@ -46,7 +38,7 @@ def run(self): setup( name='orca', - version='1.5.1', + version='1.5.2', description='A pipeline orchestration tool with Pandas support', long_description=long_description, author='UrbanSim Inc.', @@ -57,6 +49,9 @@ def run(self): 'Development Status :: 4 - Beta', 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.5', + 'Programming Language :: Python :: 3.6', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', 'License :: OSI Approved :: BSD License' ], packages=find_packages(exclude=['*.tests']), @@ -66,9 +61,12 @@ def run(self): 'server/static/js/dist/*', 'server/templates/*'] }, + # New versions of PyTables ("tables" on pypi) often fail to install correctly, so we + # are being conservative here and disallowing them until tested install_requires=[ 'pandas >= 0.15.0', - 'tables >= 3.1.0', + 'tables >=3.1, <3.6; python_version <"3.6"', + 'tables >=3.1, <3.7; python_version >="3.6"', 'toolz >= 0.8.1' ], extras_require={