1- """Buildpack for git repos with Pipfile.lock or Pipfile within them. `pipenv`
2- will be used to install the dependencies but we will manually install declared
3- Python versions instead of using PyEnv."""
1+ """Buildpack for git repos with Pipfile.lock or Pipfile
42
3+ `pipenv` will be used to install the dependencies
4+ conda will provide the base Python environment,
5+ same as the Python or Conda build packs.
6+ """
7+
8+ import json
59import os
610import re
711
12+ import toml
13+
814from ..conda import CondaBuildPack
915
16+ VERSION_PAT = re .compile (r"\d+(\.\d+)*" )
17+
1018
1119class PipfileBuildPack (CondaBuildPack ):
1220 """Setup Python with pipfile for use with a repository."""
@@ -23,38 +31,39 @@ def python_version(self):
2331 return self ._python_version
2432
2533 files_to_search_in_order = [
26- {
27- "path" : self .binder_path ("Pipfile.lock" ),
28- "pattern" : r"\s*[\",\']python_(?:full_)?version[\",\']: [\",\']?([0-9a-z\.]*)[\",\']?" , # ' "python_version": "3.6"'
29- },
30- {
31- "path" : self .binder_path ("Pipfile" ),
32- "pattern" : r"python_(?:full_)?version\s*=+\s*[\",\']?([0-9a-z\.]*)[\",\']?" , # 'python_version = "3.6"'
33- },
34- {
35- "path" : self .binder_path ("runtime.txt" ),
36- "pattern" : r"\s*python-([0-9a-z\.]*)\s*" , # 'python-3.6'
37- },
34+ self .binder_path ("Pipfile.lock" ),
35+ self .binder_path ("Pipfile" ),
3836 ]
3937
38+ lockfile = self .binder_path ("Pipfile.lock" )
39+ requires_sources = []
40+ if os .path .exists (lockfile ):
41+ with open (lockfile ) as f :
42+ lock_info = json .load (f )
43+ requires_sources .append (lock_info .get ("_meta" , {}).get ("requires" , {}))
44+
45+ pipfile = self .binder_path ("Pipfile" )
46+ if os .path .exists (pipfile ):
47+ with open (pipfile ) as f :
48+ pipfile_info = toml .load (f )
49+ requires_sources .append (pipfile_info .get ("requires" , {}))
50+
4051 py_version = None
41- for file in files_to_search_in_order :
42- try :
43- with open (file ["path" ]) as f :
44- for line in f :
45- match = re .match (file ["pattern" ], line )
46- if not match :
47- continue
48- py_version = match .group (1 )
49- break
50- except FileNotFoundError :
51- pass
52+ for requires in requires_sources :
53+ for key in ("python_full_version" , "python_version" ):
54+ version_str = requires .get (key , None )
55+ if version_str :
56+ match = VERSION_PAT .match (version_str )
57+ if match :
58+ py_version = match .group ()
59+ if py_version :
60+ break
5261 if py_version :
5362 break
5463
5564 # extract major.minor
5665 if py_version :
57- if len (py_version ) == 1 :
66+ if len (py_version . split ( "." ) ) == 1 :
5867 self ._python_version = self .major_pythons .get (py_version [0 ])
5968 else :
6069 # return major.minor
0 commit comments