* Remove unnecessary win_install.ps1. * Add appveyor version update to release script. * Make setup.py's pure Python fallback code less intrusive.tags/v0.4.1
@@ -12,6 +12,8 @@ environment: | |||
global: | |||
# See: http://stackoverflow.com/a/13751649/163740 | |||
WRAPPER: "cmd /E:ON /V:ON /C .\\scripts\\win_wrapper.cmd" | |||
PIP: "%WRAPPER% %PYTHON%\\Scripts\\pip.exe" | |||
SETUPPY: "%WRAPPER% %PYTHON%\\python setup.py --with-extension" | |||
matrix: | |||
- PYTHON: "C:\\Python27" | |||
@@ -39,16 +41,16 @@ environment: | |||
PYTHON_ARCH: "64" | |||
install: | |||
- "powershell scripts\\win_install.ps1" | |||
- "%PIP% install wheel" | |||
build_script: | |||
- "%WRAPPER% %PYTHON%\\python setup.py build" | |||
- "%SETUPPY% build" | |||
test_script: | |||
- "%WRAPPER% %PYTHON%\\python setup.py -q test" | |||
- "%SETUPPY% -q test" | |||
after_test: | |||
- "%WRAPPER% %PYTHON%\\python setup.py bdist_wheel" | |||
- "%SETUPPY% bdist_wheel" | |||
artifacts: | |||
- path: dist\* | |||
@@ -31,7 +31,12 @@ update_version() { | |||
echo " done." | |||
} | |||
# TODO: update appveyor version! | |||
update_appveyor() { | |||
filename="appveyor.yml" | |||
echo -n "Updating $filename..." | |||
sed -e "s/version: .*/version: $VERSION-b{build}/" -i "" $filename | |||
echo " done." | |||
} | |||
update_changelog() { | |||
filename="CHANGELOG" | |||
@@ -154,6 +159,7 @@ cd "$SCRIPT_DIR/.." | |||
check_git | |||
update_version | |||
update_appveyor | |||
update_changelog | |||
update_docs_changelog | |||
do_git_stuff | |||
@@ -1,85 +0,0 @@ | |||
# Sample script to install Python and pip under Windows | |||
# Authors: Olivier Grisel and Kyle Kastner | |||
# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ | |||
$BASE_URL = "https://www.python.org/ftp/python/" | |||
$GET_PIP_URL = "https://bootstrap.pypa.io/get-pip.py" | |||
$GET_PIP_PATH = "C:\get-pip.py" | |||
function DownloadPython ($python_version, $platform_suffix) { | |||
$webclient = New-Object System.Net.WebClient | |||
$filename = "python-" + $python_version + $platform_suffix + ".msi" | |||
$url = $BASE_URL + $python_version + "/" + $filename | |||
$basedir = $pwd.Path + "\" | |||
$filepath = $basedir + $filename | |||
if (Test-Path $filename) { | |||
Write-Host "Reusing" $filepath | |||
return $filepath | |||
} | |||
# Download and retry up to 3 times in case of network transient errors. | |||
Write-Host "Downloading" $filename "from" $url | |||
$retry_attempts = 3 | |||
for($i=0; $i -lt $retry_attempts; $i++){ | |||
try { | |||
$webclient.DownloadFile($url, $filepath) | |||
break | |||
} | |||
Catch [Exception]{ | |||
Start-Sleep 1 | |||
} | |||
} | |||
Write-Host "File saved at" $filepath | |||
return $filepath | |||
} | |||
function InstallPython ($python_version, $architecture, $python_home) { | |||
Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home | |||
if (Test-Path $python_home) { | |||
Write-Host $python_home "already exists, skipping." | |||
return $false | |||
} | |||
if ($architecture -eq "32") { | |||
$platform_suffix = "" | |||
} else { | |||
$platform_suffix = ".amd64" | |||
} | |||
$filepath = DownloadPython $python_version $platform_suffix | |||
Write-Host "Installing" $filepath "to" $python_home | |||
$args = "/qn /i $filepath TARGETDIR=$python_home" | |||
Write-Host "msiexec.exe" $args | |||
Start-Process -FilePath "msiexec.exe" -ArgumentList $args -Wait -Passthru | |||
Write-Host "Python $python_version ($architecture) installation complete" | |||
return $true | |||
} | |||
function InstallPip ($python_home) { | |||
$pip_path = $python_home + "/Scripts/pip.exe" | |||
$python_path = $python_home + "/python.exe" | |||
if (-not(Test-Path $pip_path)) { | |||
Write-Host "Installing pip..." | |||
$webclient = New-Object System.Net.WebClient | |||
$webclient.DownloadFile($GET_PIP_URL, $GET_PIP_PATH) | |||
Write-Host "Executing:" $python_path $GET_PIP_PATH | |||
Start-Process -FilePath "$python_path" -ArgumentList "$GET_PIP_PATH" -Wait -Passthru | |||
} else { | |||
Write-Host "pip already installed." | |||
} | |||
} | |||
function InstallPackage ($python_home, $pkg) { | |||
$pip_path = $python_home + "/Scripts/pip.exe" | |||
& $pip_path install $pkg | |||
} | |||
function main () { | |||
InstallPython $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON | |||
InstallPip $env:PYTHON | |||
InstallPackage $env:PYTHON wheel | |||
} | |||
main |
@@ -21,17 +21,17 @@ | |||
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | |||
# SOFTWARE. | |||
import os | |||
from __future__ import print_function | |||
from distutils.errors import DistutilsError, CCompilerError | |||
from os import environ | |||
import sys | |||
if (sys.version_info[0] == 2 and sys.version_info[1] < 6) or \ | |||
(sys.version_info[1] == 3 and sys.version_info[1] < 2): | |||
raise Exception("mwparserfromhell needs Python 2.6+ or 3.2+") | |||
if sys.version_info >= (3, 0): | |||
basestring = (str, ) | |||
if ((sys.version_info[0] == 2 and sys.version_info[1] < 6) or | |||
(sys.version_info[1] == 3 and sys.version_info[1] < 2)): | |||
raise RuntimeError("mwparserfromhell needs Python 2.6+ or 3.2+") | |||
from setuptools import setup, find_packages, Extension | |||
from setuptools.command.build_ext import build_ext | |||
from mwparserfromhell import __version__ | |||
from mwparserfromhell.compat import py26, py3k | |||
@@ -44,65 +44,41 @@ tokenizer = Extension("mwparserfromhell.parser._tokenizer", | |||
depends=["mwparserfromhell/parser/tokenizer.h"]) | |||
use_extension = True | |||
fallback = True | |||
# Allow env var WITHOUT_EXTENSION and args --with[out]-extension | |||
if '--without-extension' in sys.argv: | |||
use_extension = False | |||
elif '--with-extension' in sys.argv: | |||
pass | |||
elif os.environ.get('WITHOUT_EXTENSION', '0') == '1': | |||
use_extension = False | |||
# Remove the command line argument as it isn't understood by | |||
# setuptools/distutils | |||
sys.argv = [arg for arg in sys.argv | |||
if not arg.startswith('--with') | |||
and not arg.endswith('-extension')] | |||
def optional_compile_setup(func=setup, use_ext=use_extension, | |||
*args, **kwargs): | |||
""" | |||
Wrap setup to allow optional compilation of extensions. | |||
Falls back to pure python mode (no extensions) | |||
if compilation of extensions fails. | |||
""" | |||
extensions = kwargs.get('ext_modules', None) | |||
# Allow env var WITHOUT_EXTENSION and args --with[out]-extension: | |||
if use_ext and extensions: | |||
try: | |||
func(*args, **kwargs) | |||
return | |||
except SystemExit as e: | |||
assert(e.args) | |||
if e.args[0] is False: | |||
raise | |||
elif isinstance(e.args[0], basestring): | |||
if e.args[0].startswith('usage: '): | |||
raise | |||
else: | |||
# Fallback to pure python mode | |||
print('setup with extension failed: %s' % repr(e)) | |||
pass | |||
except Exception as e: | |||
print('setup with extension failed: %s' % repr(e)) | |||
env_var = environ.get("WITHOUT_EXTENSION") | |||
if "--without-extension" in sys.argv: | |||
use_extension = False | |||
elif "--with-extension" in sys.argv: | |||
fallback = False | |||
elif env_var is not None: | |||
if env_var == "1": | |||
use_extension = False | |||
elif env_var == "0": | |||
fallback = False | |||
if extensions: | |||
if use_ext: | |||
print('Falling back to pure python mode.') | |||
else: | |||
print('Using pure python mode.') | |||
# Remove the command line argument as it isn't understood by setuptools: | |||
del kwargs['ext_modules'] | |||
sys.argv = [arg for arg in sys.argv | |||
if arg != "--without-extension" and arg != "--with-extension"] | |||
func(*args, **kwargs) | |||
def build_ext_patched(self): | |||
try: | |||
build_ext_original(self) | |||
except (DistutilsError, CCompilerError) as exc: | |||
print("error: " + str(exc)) | |||
print("Falling back to pure Python mode.") | |||
del self.extensions[:] | |||
if fallback: | |||
build_ext.run, build_ext_original = build_ext_patched, build_ext.run | |||
optional_compile_setup( | |||
setup( | |||
name = "mwparserfromhell", | |||
packages = find_packages(exclude=("tests",)), | |||
ext_modules = [tokenizer], | |||
ext_modules = [tokenizer] if use_extension else [], | |||
tests_require = ["unittest2"] if py26 else [], | |||
test_suite = "tests.discover", | |||
version = __version__, | |||