I have docker file with one layer as
RUN python setup.py develop
I am using a mutli-stage build with three stages and this is the stage one all the stages have the same base image, though I don't think this is a problem with dockerfile but seems to be a problem with python and the way it is executed
working on the base image python:3.7-slim
I am building this dockerfile on Travis CI with this below
Version info on Travis:
docker version
Client:
Version: 17.09.0-ce
API version: 1.32
Go version: go1.8.3
Git commit: afdb6d4
Built: Tue Sep 26 22:42:38 2017
OS/Arch: linux/amd64
Server:
Version: 17.09.0-ce
API version: 1.32 (minimum version 1.12)
Go version: go1.8.3
Git commit: afdb6d4
Built: Tue Sep 26 22:41:20 2017
OS/Arch: linux/amd64
Experimental: false
I get this below error as
AttributeError: 'ParsedRequirement' object has no attribute 'req'
Surprisingly I am able to have this working on My mac machine with docker version 19.03.2
Here is my setup.py
file
import os
import shutil
import inspect
import platform
from setuptools import setup
import setuptools
try:
from pip.req import parse_requirements
except ImportError:
from pip._internal.req import parse_requirements
EMAIL_CONF = 'email.conf'
DL_CONF = 'dl.conf'
LINUX_CONFDIR = os.path.expanduser('~') + '/.config/bassa/'
WIN_CONFDIR = os.path.expanduser('~') + '/%app_data%/bassa/'
OSX_CONFDIR = os.path.expanduser('~') + '/.config/bassa/'
# Utility function to read the README file.
def read(file_name):
return open(os.path.join(os.path.dirname(__file__), file_name)).read()
base_dir = os.path.dirname(os.path.abspath(__file__))
requirements_path = os.path.join(base_dir, 'requirements.txt')
install_reqs = parse_requirements(requirements_path, session=False)
requirements = [str(ir.req) for ir in install_reqs]
### Set configs ###
if platform.system() == 'Linux':
configdir = LINUX_CONFDIR
elif platform.system() == 'Windows':
configdir = WIN_CONFDIR
elif platform.system() == 'Darwin':
configdir = OSX_CONFDIR
if not os.path.exists(configdir):
os.makedirs(configdir)
email_conf_location = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + "/" + EMAIL_CONF
dl_conf_location = os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) + "/" + DL_CONF
shutil.copyfile(email_conf_location, configdir + EMAIL_CONF)
shutil.copyfile(dl_conf_location, configdir + DL_CONF)
###/ Set configs ###
setup(
...
)
Please help me with this issue.
I got the fix finally \o/
install_reqs = parse_requirements(requirements_path, session=False)
At first, I have inspected what install_reqs was on Travis by simply logging it and found that it was a list of ParsedRequirement objects. I also found that this class is defined in req_file.py
. I have gone to check the source code for req_file.py
here on GitHub. I found that there was no such attribute called req
but instead it is requirement
. So there were two versions of parse_requirements
function so I handled this using a try and except block.
# Generator must be converted to list, or we will only have one chance to read each element, meaning that the first requirement will be skipped.
requirements = list(requirements)
try:
requirements = [str(ir.req) for ir in install_reqs]
except:
requirements = [str(ir.requirement) for ir in install_reqs]
Now it is compatible with both the versions \0/