Skip to content

Commit 85207a0

Browse files
authored
Merge pull request #1862 from JonasT/fix_leftover_constraint_file
Fix various setup.py processing bugs
2 parents 80e4f05 + 6ae074e commit 85207a0

File tree

4 files changed

+131
-106
lines changed

4 files changed

+131
-106
lines changed

pythonforandroid/build.py

Lines changed: 123 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
from __future__ import print_function
22

3-
from os.path import (join, realpath, dirname, expanduser, exists,
4-
split, isdir)
3+
from os.path import (
4+
abspath, join, realpath, dirname, expanduser, exists,
5+
split, isdir
6+
)
57
from os import environ
68
import copy
79
import os
@@ -590,6 +592,120 @@ def project_has_setup_py(project_dir):
590592
return False
591593

592594

595+
def run_setuppy_install(ctx, project_dir, env=None):
596+
if env is None:
597+
env = dict()
598+
599+
with current_directory(project_dir):
600+
info('got setup.py or similar, running project install. ' +
601+
'(disable this behavior with --ignore-setup-py)')
602+
603+
# Compute & output the constraints we will use:
604+
info('Contents that will be used for constraints.txt:')
605+
constraints = subprocess.check_output([
606+
join(
607+
ctx.build_dir, "venv", "bin", "pip"
608+
),
609+
"freeze"
610+
], env=copy.copy(env))
611+
try:
612+
constraints = constraints.decode("utf-8", "replace")
613+
except AttributeError:
614+
pass
615+
info(constraints)
616+
617+
# Make sure all packages found are fixed in version
618+
# by writing a constraint file, to avoid recipes being
619+
# upgraded & reinstalled:
620+
with open('._tmp_p4a_recipe_constraints.txt', 'wb') as fileh:
621+
fileh.write(constraints.encode("utf-8", "replace"))
622+
try:
623+
624+
info('Populating venv\'s site-packages with '
625+
'ctx.get_site_packages_dir()...')
626+
627+
# Copy dist contents into site-packages for discovery.
628+
# Why this is needed:
629+
# --target is somewhat evil and messes with discovery of
630+
# packages in PYTHONPATH if that also includes the target
631+
# folder. So we need to use the regular virtualenv
632+
# site-packages folder instead.
633+
# Reference:
634+
# https://github.com/pypa/pip/issues/6223
635+
ctx_site_packages_dir = os.path.normpath(
636+
os.path.abspath(ctx.get_site_packages_dir())
637+
)
638+
venv_site_packages_dir = os.path.normpath(os.path.join(
639+
ctx.build_dir, "venv", "lib", [
640+
f for f in os.listdir(os.path.join(
641+
ctx.build_dir, "venv", "lib"
642+
)) if f.startswith("python")
643+
][0], "site-packages"
644+
))
645+
copied_over_contents = []
646+
for f in os.listdir(ctx_site_packages_dir):
647+
full_path = os.path.join(ctx_site_packages_dir, f)
648+
if not os.path.exists(os.path.join(
649+
venv_site_packages_dir, f
650+
)):
651+
if os.path.isdir(full_path):
652+
shutil.copytree(full_path, os.path.join(
653+
venv_site_packages_dir, f
654+
))
655+
else:
656+
shutil.copy2(full_path, os.path.join(
657+
venv_site_packages_dir, f
658+
))
659+
copied_over_contents.append(f)
660+
661+
# Get listing of virtualenv's site-packages, to see the
662+
# newly added things afterwards & copy them back into
663+
# the distribution folder / build context site-packages:
664+
previous_venv_contents = os.listdir(
665+
venv_site_packages_dir
666+
)
667+
668+
# Actually run setup.py:
669+
info('Launching package install...')
670+
shprint(sh.bash, '-c', (
671+
"'" + join(
672+
ctx.build_dir, "venv", "bin", "pip"
673+
).replace("'", "'\"'\"'") + "' " +
674+
"install -c ._tmp_p4a_recipe_constraints.txt -v ."
675+
).format(ctx.get_site_packages_dir().
676+
replace("'", "'\"'\"'")),
677+
_env=copy.copy(env))
678+
679+
# Go over all new additions and copy them back:
680+
info('Copying additions resulting from setup.py back '
681+
'into ctx.get_site_packages_dir()...')
682+
new_venv_additions = []
683+
for f in (set(os.listdir(venv_site_packages_dir)) -
684+
set(previous_venv_contents)):
685+
new_venv_additions.append(f)
686+
full_path = os.path.join(venv_site_packages_dir, f)
687+
if os.path.isdir(full_path):
688+
shutil.copytree(full_path, os.path.join(
689+
ctx_site_packages_dir, f
690+
))
691+
else:
692+
shutil.copy2(full_path, os.path.join(
693+
ctx_site_packages_dir, f
694+
))
695+
696+
# Undo all the changes we did to the venv-site packages:
697+
info('Reverting additions to '
698+
'virtualenv\'s site-packages...')
699+
for f in set(copied_over_contents + new_venv_additions):
700+
full_path = os.path.join(venv_site_packages_dir, f)
701+
if os.path.isdir(full_path):
702+
shutil.rmtree(full_path)
703+
else:
704+
os.remove(full_path)
705+
finally:
706+
os.remove("._tmp_p4a_recipe_constraints.txt")
707+
708+
593709
def run_pymodules_install(ctx, modules, project_dir=None,
594710
ignore_setup_py=False):
595711
""" This function will take care of all non-recipe things, by:
@@ -605,6 +721,10 @@ def run_pymodules_install(ctx, modules, project_dir=None,
605721
info('*** PYTHON PACKAGE / PROJECT INSTALL STAGE ***')
606722
modules = list(filter(ctx.not_has_package, modules))
607723

724+
# We change current working directory later, so this
725+
# has to be an absolute path:
726+
project_dir = abspath(project_dir)
727+
608728
# Bail out if no python deps and no setup.py to process:
609729
if not modules and (
610730
ignore_setup_py or
@@ -697,107 +817,7 @@ def run_pymodules_install(ctx, modules, project_dir=None,
697817
if project_dir is not None and (
698818
project_has_setup_py(project_dir) and not ignore_setup_py
699819
):
700-
with current_directory(project_dir):
701-
info('got setup.py or similar, running project install. ' +
702-
'(disable this behavior with --ignore-setup-py)')
703-
704-
# Compute & output the constraints we will use:
705-
info('Contents that will be used for constraints.txt:')
706-
constraints = subprocess.check_output([
707-
join(
708-
ctx.build_dir, "venv", "bin", "pip"
709-
),
710-
"freeze"
711-
], env=copy.copy(env))
712-
try:
713-
constraints = constraints.decode("utf-8", "replace")
714-
except AttributeError:
715-
pass
716-
info(constraints)
717-
718-
# Make sure all packages found are fixed in version
719-
# by writing a constraint file, to avoid recipes being
720-
# upgraded & reinstalled:
721-
with open('constraints.txt', 'wb') as fileh:
722-
fileh.write(constraints.encode("utf-8", "replace"))
723-
724-
info('Populating venv\'s site-packages with '
725-
'ctx.get_site_packages_dir()...')
726-
727-
# Copy dist contents into site-packages for discovery.
728-
# Why this is needed:
729-
# --target is somewhat evil and messes with discovery of
730-
# packages in PYTHONPATH if that also includes the target
731-
# folder. So we need to use the regular virtualenv
732-
# site-packages folder instead.
733-
# Reference:
734-
# https://github.com/pypa/pip/issues/6223
735-
ctx_site_packages_dir = os.path.normpath(
736-
os.path.abspath(ctx.get_site_packages_dir())
737-
)
738-
venv_site_packages_dir = os.path.normpath(os.path.join(
739-
ctx.build_dir, "venv", "lib", [
740-
f for f in os.listdir(os.path.join(
741-
ctx.build_dir, "venv", "lib"
742-
)) if f.startswith("python")
743-
][0], "site-packages"
744-
))
745-
copied_over_contents = []
746-
for f in os.listdir(ctx_site_packages_dir):
747-
full_path = os.path.join(ctx_site_packages_dir, f)
748-
if not os.path.exists(os.path.join(
749-
venv_site_packages_dir, f
750-
)):
751-
if os.path.isdir(full_path):
752-
shutil.copytree(full_path, os.path.join(
753-
venv_site_packages_dir, f
754-
))
755-
else:
756-
shutil.copy2(full_path, os.path.join(
757-
venv_site_packages_dir, f
758-
))
759-
copied_over_contents.append(f)
760-
761-
# Get listing of virtualenv's site-packages, to see the
762-
# newly added things afterwards & copy them back into
763-
# the distribution folder / build context site-packages:
764-
previous_venv_contents = os.listdir(venv_site_packages_dir)
765-
766-
# Actually run setup.py:
767-
info('Launching package install...')
768-
shprint(sh.bash, '-c', (
769-
"'" + join(
770-
ctx.build_dir, "venv", "bin", "pip"
771-
).replace("'", "'\"'\"'") + "' " +
772-
"install -c constraints.txt -v ."
773-
).format(ctx.get_site_packages_dir().replace("'", "'\"'\"'")),
774-
_env=copy.copy(env))
775-
776-
# Go over all new additions and copy them back:
777-
info('Copying additions resulting from setup.py back ' +
778-
'into ctx.get_site_packages_dir()...')
779-
new_venv_additions = []
780-
for f in (set(os.listdir(venv_site_packages_dir)) -
781-
set(previous_venv_contents)):
782-
new_venv_additions.append(f)
783-
full_path = os.path.join(venv_site_packages_dir, f)
784-
if os.path.isdir(full_path):
785-
shutil.copytree(full_path, os.path.join(
786-
ctx_site_packages_dir, f
787-
))
788-
else:
789-
shutil.copy2(full_path, os.path.join(
790-
ctx_site_packages_dir, f
791-
))
792-
793-
# Undo all the changes we did to the venv-site packages:
794-
info('Reverting additions to virtualenv\'s site-packages...')
795-
for f in set(copied_over_contents + new_venv_additions):
796-
full_path = os.path.join(venv_site_packages_dir, f)
797-
if os.path.isdir(full_path):
798-
shutil.rmtree(full_path)
799-
else:
800-
os.remove(full_path)
820+
run_setuppy_install(ctx, project_dir, env)
801821
elif not ignore_setup_py:
802822
info("No setup.py found in project directory: " +
803823
str(project_dir)

pythonforandroid/pythonpackage.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ def parse_as_folder_reference(dep):
559559
# Check if this is either not an url, or a file URL:
560560
if dep.startswith(("/", "file://")) or (
561561
dep.find("/") > 0 and
562-
dep.find("://") < 0):
562+
dep.find("://") < 0) or (dep in ["", "."]):
563563
if dep.startswith("file://"):
564564
dep = urlunquote(urlparse(dep).path)
565565
return dep
@@ -689,7 +689,7 @@ def get_package_dependencies(package,
689689
for package_dep in current_queue:
690690
new_reqs = set()
691691
if verbose:
692-
print("get_package_dependencies: resolving dependecy "
692+
print("get_package_dependencies: resolving dependency "
693693
"to package name: ".format(package_dep))
694694
package = get_package_name(package_dep)
695695
if package.lower() in packages_processed:

pythonforandroid/toolchain.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -631,7 +631,10 @@ def add_parser(subparsers, *args, **kwargs):
631631
args.requirements += u",".join(dependencies)
632632
except ValueError:
633633
# Not a python package, apparently.
634-
pass
634+
warning(
635+
"Processing failed, is this project a valid "
636+
"package? Will continue WITHOUT setup.py deps."
637+
)
635638

636639
# Parse --requirements argument list:
637640
for requirement in split_argument_list(args.requirements):

tests/test_pythonpackage_basic.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,8 @@ def test_is_filesystem_path():
187187
assert not is_filesystem_path("test @ bla")
188188
assert is_filesystem_path("/abc/c@d")
189189
assert not is_filesystem_path("https://user:pw@host/")
190+
assert is_filesystem_path(".")
191+
assert is_filesystem_path("")
190192

191193

192194
def test_parse_as_folder_reference():

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy