mognoengine and bson package not work together - python

I have one project which is depend on mongoengine and I am using one library which was using bson library.
It structure like below.
bsNotify/
├── setup.cfg
├── setup.py
└── src
└── bsnotify
├── __init__.py
└── resources.py
setup.py
$ cat bsNotify/setup.py
"""Base module setup."""
from setuptools import setup
setup(
setup_requires=['pbr'],
pbr=True
)
setup.cfg
$ cat bsNotify/setup.cfg
[metadata]
name = bsNotify
classifiers =
License :: N/A :: N/A
Programming Language :: Python :: 3.7
[options]
zip_safe = False
include_package_data = True
python_requires = >= 3.7
install_requires =
mongoengine
bson
package_dir=
=src
packages=find:
[options.packages.find]
where=src
[tool:wheel]
universal = 1
[flake8]
exclude =
venv,
.tox,
.git,
__pycache__,
*.pyc,
*.egg-info,
.cache,
.eggs,
max-line-length = 80
[tox]
envlist = py37,unittest,lint
[testenv]
basepython=python3.7
deps =
ipython
pylint
pytest
pytest-cov
pytest-xdist
flake8
flake8-docstrings
[testenv:unittest]
commands=
pytest -v -s -n auto -l --cov=bsnotify --cov-report term-missing --cov-report xml --no-cov-on-fail tests/unit
[testenv:lint]
commands=
flake8 src/bsnotify
pylint src/bsnotify
src/bsnotify/__init__.py
$ cat bsNotify/src/bsnotify/__init__.py
src/bsnotify/resources.py
$ cat bsNotify/src/bsnotify/resources.py
Files in src are empty.
When I run the tox command, it create a virtualenv for testing.
$ tox -v -e unittest --notest
using tox.ini: /Users/myuser/bsNotify/setup.cfg (pid 30954)
using tox-3.14.6 from /Users/myuser/.pyenv/versions/3.7.4/lib/python3.7/site-packages/tox/__init__.py (pid 30954)
GLOB sdist-make: /Users/myuser/bsNotify/setup.py
[30956] /Users/myuser/bsNotify$ /Users/myuser/.pyenv/versions/3.7.4/bin/python3.7 setup.py sdist --formats=zip --dist-dir /Users/myuser/bsNotify/.tox/dist >.tox/log/GLOB-0.log
package .tmp/package/1/bsNotify-0.1.2.dev2.zip links to dist/bsNotify-0.1.2.dev2.zip (/Users/myuser/bsNotify/.tox)
unittest cannot reuse: no previous config /Users/myuser/bsNotify/.tox/unittest/.tox-config1
unittest create: /Users/myuser/bsNotify/.tox/unittest
[30992] /Users/myuser/bsNotify/.tox$ /Users/myuser/.pyenv/versions/3.7.4/bin/python3.7 -m virtualenv --no-download --python /Users/myuser/.pyenv/versions/3.7.4/bin/python3.7 unittest >unittest/log/unittest-0.log
unittest installdeps: ipython, pylint, pytest, pytest-cov, pytest-xdist, flake8, flake8-docstrings
[30993] /Users/myuser/bsNotify$ /Users/myuser/bsNotify/.tox/unittest/bin/python -m pip install ipython pylint pytest pytest-cov pytest-xdist flake8 flake8-docstrings >.tox/unittest/log/unittest-1.log
unittest inst: /Users/myuser/bsNotify/.tox/.tmp/package/1/bsNotify-0.1.2.dev2.zip
write config to /Users/myuser/bsNotify/.tox/unittest/.tox-config1 as '7186e9f46c94b6d9f7dde810ce83f8fe46740d9d42f2863cfd063c4c6f4e4a88 /Users/myuser/.pyenv/versions/3.7.4/bin/python3.7\n3.14.6 0 0 0\n00000000000000000000000000000000 ipython\n00000000000000000000000000000000 pylint\n00000000000000000000000000000000 pytest\n00000000000000000000000000000000 pytest-cov\n00000000000000000000000000000000 pytest-xdist\n00000000000000000000000000000000 flake8\n00000000000000000000000000000000 flake8-docstrings'
[31000] /Users/myuser/bsNotify$ /Users/myuser/bsNotify/.tox/unittest/bin/python -m pip install --exists-action w .tox/.tmp/package/1/bsNotify-0.1.2.dev2.zip >.tox/unittest/log/unittest-2.log
[31030] /Users/myuser/bsNotify$ /Users/myuser/bsNotify/.tox/unittest/bin/python -m pip freeze >.tox/unittest/log/unittest-3.log
unittest installed: apipkg==1.5,appnope==0.1.0,astroid==2.4.2,attrs==19.3.0,backcall==0.1.0,bsNotify==0.1.2.dev2,bson==0.5.10,coverage==5.1,decorator==4.4.2,execnet==1.7.1,flake8==3.8.3,flake8-docstrings==1.5.0,importlib-metadata==1.6.1,ipython==7.15.0,ipython-genutils==0.2.0,isort==4.3.21,jedi==0.17.0,lazy-object-proxy==1.4.3,mccabe==0.6.1,mongoengine==0.20.0,more-itertools==8.3.0,packaging==20.4,parso==0.7.0,pexpect==4.8.0,pickleshare==0.7.5,pluggy==0.13.1,prompt-toolkit==3.0.5,ptyprocess==0.6.0,py==1.8.1,pycodestyle==2.6.0,pydocstyle==5.0.2,pyflakes==2.2.0,Pygments==2.6.1,pylint==2.5.3,pymongo==3.10.1,pyparsing==2.4.7,pytest==5.4.3,pytest-cov==2.9.0,pytest-forked==1.1.3,pytest-xdist==1.32.0,python-dateutil==2.8.1,six==1.15.0,snowballstemmer==2.0.0,toml==0.10.1,traitlets==4.3.3,typed-ast==1.4.1,wcwidth==0.2.4,wrapt==1.12.1,zipp==3.1.0
_______________________________________________________ summary _______________________________________________________
unittest: skipped tests
congratulations :)
Then I try to access mongoengine in newly created virtualenv, it gives error.
$ .tox/unittest/bin/python -c "from mongoengine import connection"
Traceback (most recent call last):
File "<string>", line 1, in <module>
File "/Users/myuser/bsNotify/.tox/unittest/lib/python3.7/site-packages/mongoengine/__init__.py", line 2, in <module>
from mongoengine import connection
File "/Users/myuser/bsNotify/.tox/unittest/lib/python3.7/site-packages/mongoengine/connection.py", line 1, in <module>
from pymongo import MongoClient, ReadPreference, uri_parser
File "/Users/myuser/bsNotify/.tox/unittest/lib/python3.7/site-packages/pymongo/__init__.py", line 77, in <module>
from pymongo.collection import ReturnDocument
File "/Users/myuser/bsNotify/.tox/unittest/lib/python3.7/site-packages/pymongo/collection.py", line 20, in <module>
from bson.code import Code
File "/Users/myuser/bsNotify/.tox/unittest/lib/python3.7/site-packages/bson/code.py", line 18, in <module>
from bson.py3compat import abc, string_type, PY3, text_type
ImportError: cannot import name 'abc' from 'bson.py3compat' (/Users/myuser/bsNotify/.tox/unittest/lib/python3.7/site-packages/bson/py3compat.py)
When I was using mongoengine alone with bson, it works fine.
$ python -m venv .venv
$ .venv/bin/pip install mongoengine
Collecting mongoengine
Using cached https://files.pythonhosted.org/packages/7d/bd/9a7239b0032157f948c69febdf71dd82cb54fcd2499077300496a3f076c9/mongoengine-0.20.0-py3-none-any.whl
Collecting pymongo<4.0,>=3.4 (from mongoengine)
Using cached https://files.pythonhosted.org/packages/23/cd/27fbc08f0bd835b4735504a758756e979b42c5bc9ebaac5ed3c2cbffd83f/pymongo-3.10.1-cp37-cp37m-macosx_10_9_x86_64.whl
Installing collected packages: pymongo, mongoengine
Successfully installed mongoengine-0.20.0 pymongo-3.10.1
$ .venv/bin/python -c "from mongoengine import connection"
$ .venv/bin/pip install bson
Collecting bson
Using cached https://files.pythonhosted.org/packages/4d/53/7c534a38850f2252275d7f949aed2219095e90df1e2d180a9c8ed139e499/bson-0.5.10.tar.gz
Collecting python-dateutil>=2.4.0 (from bson)
Using cached https://files.pythonhosted.org/packages/d4/70/d60450c3dd48ef87586924207ae8907090de0b306af2bce5d134d78615cb/python_dateutil-2.8.1-py2.py3-none-any.whl
Collecting six>=1.9.0 (from bson)
Using cached https://files.pythonhosted.org/packages/ee/ff/48bde5c0f013094d729fe4b0316ba2a24774b3ff1c52d924a8a4cb04078a/six-1.15.0-py2.py3-none-any.whl
Installing collected packages: six, python-dateutil, bson
Running setup.py install for bson ... done
Successfully installed bson-0.5.10 python-dateutil-2.8.1 six-1.15.0
You are using pip version 19.0.3, however version 20.2b1 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
$ .venv/bin/python -c "from mongoengine import connection"
It check the pip freeze between both the virtualenv. Only difference I found is in .tox env has bsNotify==0.1.2.dev2 installed which is not exists in .venv env.
What make bson change the file py3compat.py?

change this
install_requires =
mongoengine
bson
to this
install_requires =
mongoengine
pymongo
or remove altogether (mongoengine already requires pymongo
install_requires =
mongoengine
requirements=bson is the same things as
pip install bson
which installs this 3rd party package which does not include all the goodies found in MongoDB's package
https://pypi.org/project/bson/
pymongo (official MongoDB driver) contains a bson package. I'll drop both a pymongo folder and a bson folder into your site-packages.
bson (third party bson implementation) also wants to drop a bson folder into your site packages.
Installing pymongo and installing bson will conflict folders inside your site-packages. PyMongo only knows how to use it's own implementation, which is why you're seeing pymongo looking for py3compat which is not part of the 3rd party bson package.
Based on your install order, it would have installed mongo engine (and pymongo as a dependency) then installed bson (overwriting MongoDB's bson implementation packaged with pymongo). Pymongo called py3compat expecting it to be there, but 3td party did not implement that (as well as several other things).
pip install pymongo
https://pypi.org/project/pymongo/
As noted on the pymongo pypi page
Do not install the “bson” package from pypi. PyMongo comes with its
own bson package; doing “easy_install bson” installs a third-party
package that is incompatible with PyMongo.

Related

tox does not find numpy

I try to run tox in order to automatically test my project. My tox file is very simple:
[tox]
envlist = py3
[testenv]
deps = pytest
commands =
pytest --doctest-modules
I also have a requirements.txt file that defines the required modules:
cmake
osqp
numpy
cvxpy
networkx
matplotlib
and a setup.py file:
from setuptools import setup, find_packages
...
requirements = ["numpy","cvxpy","networkx","matplotlib"]
...
setup(
name='fairpy',
version='1.0',
description=...,
packages=find_packages(),
install_requires=requirements,
...
)
But when I run tox from the terminal, I get an error saying that the module numpy is not found:
GLOB sdist-make: /mnt/d/Dropbox/ariel/fairpy/setup.py
py3 inst-nodeps: /mnt/d/Dropbox/ariel/fairpy/.tox/.tmp/package/1/fairpy-1.0.zip
py3 installed: attrs==19.3.0,fairpy==1.0,more-itertools==8.1.0,packaging==20.1,pluggy==0.13.1,py==1.8.1,pyparsing==2.4.6,pytest==5.3.4,six==1.14.0,wcwidth==0.1.8
py3 run-test-pre: PYTHONHASHSEED='188600482'
py3 run-test: commands[0] | pytest --doctest-modules
========================================================== test session starts ==========================================================
platform linux -- Python 3.8.1, pytest-5.3.4, py-1.8.1, pluggy-0.13.1
cachedir: .tox/py3/.pytest_cache
rootdir: /mnt/d/Dropbox/ariel/fairpy
collected 0 items / 20 errors
================================================================ ERRORS =================================================================
__________________________________________________ ERROR collecting Deng_Qi_Saberi.py ___________________________________________________
Deng_Qi_Saberi.py:13: in <module>
from agents import *
agents.py:10: in <module>
import numpy as np
E ModuleNotFoundError: No module named 'numpy'
...
I have numpy installed - in my python 3.8.1 terminal, I can import numpy with no problem.
What am I doing wrong with tox?
First,
I have numpy installed - in my python 3.8.1 terminal, I can import numpy with no problem.
tox creates a virtual environment when you run it so it doesn't matter if you have numpy installed on your computer original interpreter.
Second,
If you want tox to install the requirements file you must add
deps = -rrequirements.txt to tox.ini.
And you can always add numpy manually as a dependency there as well.
Third,
tox has some dependencies tracking issues in some cases. Try run tox -r to force tox to recreate its environment and make sure that numpy mentioned in the "install_requires" section in the setup.py.

Module gets imported under a syntactically false name space?

I am following along with the O'Riley Head First Python (2nd Edition) Course.
At one point you will create a webapp and deploy it to pythonanywhere (chapter5).
The webapp uses two functions, imported from a module, created earlier.
The module is called vsearch.py. I also created a readme.txt and a setup.py and used setuptools to create a source distribution file using :
python3 setup.py sdist
The code of the setup.py read as follows:
from setuptools import setup
setup(
name = "vsearch",
version = "1.0",
description = "The Head First Python Seach Tools",
author = "HF Python 2e",
author_email = "hfpy2e#gmail.com",
url = "headfirstlabs.com",
py_modules = ["vsearch"],
)
The source distribution file gets created without errors and creates a file called vsearch-1.0.tar.gz
The file then gets uploaded to pythonanywhere and installed via console using:
python3 -m pip install vsearch-1.0.tar.gz --user
Console outputs:
15:36 ~/mysite $ python3 -m pip install vsearch-1.0.tar.gz --user
Looking in links: /usr/share/pip-wheels
Processing ./vsearch-1.0.tar.gz
Building wheels for collected packages: vsearch
Running setup.py bdist_wheel for vsearch ... done
Stored in directory: /home/Mohr/.cache/pip/wheels/85/fd/4e/5302d6f3b92e4057d341443ed5ef0402eb04994663282c12f7
Successfully built vsearch
Installing collected packages: vsearch
Found existing installation: vsearch 1.0
Uninstalling vsearch-1.0:
Successfully uninstalled vsearch-1.0
Successfully installed vsearch-1.0
Now when I try to run my webapp I get the following error:
2020-03-24 16:18:14,592: Error running WSGI application
2020-03-24 16:18:14,592: ModuleNotFoundError: No module named 'vsearch'
2020-03-24 16:18:14,593: File "/var/www/mohr_eu_pythonanywhere_com_wsgi.py", line 16, in <module>
2020-03-24 16:18:14,593: from vsearch4web import app as application # noqa
2020-03-24 16:18:14,593:
2020-03-24 16:18:14,593: File "/home/Mohr/mysite/vsearch4web.py", line 3, in <module>
2020-03-24 16:18:14,593: from vsearch import search4letters
Judging from this error I assume that "vsearch" can not be found because it was installed as "vsearch-1.0". However when I try to change this line to:
from vsearch-1.0 import search4letters
I rightfully get a synthax error since I can not adress modules this way. So what can I do about this? When creating the module in the beginning I added a version number to the setup.py file because according to the lecture it is good practice. Setuptools then automatically creates the source distribution file with the "-1.0" at the end. Also when importing it using the command shown above i automatically gets importet as "vsearch-1.0" which in turn I am unable to reference in my python code because of bad synthax.
Am I doing something wrong? Is there a way to import this under another namespace? Is there a way to reference "vsearch-1.0" in my python code without getting a synthax error?
There are different python3 versions installed on PythonAnywhere. When you install something using python3 -m pip or pip3 you use default python3 that is probably not matching python version setting of your web app. Use python3.7 and pip3.7 or python3.6 and pip3.6 etc. for --user installations to be sure.
pip install --user (with emphasized --user) installed the package into your user directory: /home/Mohr/.local/lib/pythonX.Y/site-packages/.
To run your WSGI application you probably use a virtual environment in which the user-installed modules are not available. To use modules in the venv you have to install everything in the venv. So activate the venv in a terminal and install the module with the venv's pip:
pip install vsearch-1.0.tar.gz

how to require a specific package version in tox?

In my tox.ini file, the dependencies are installed via the requirements.txt file which is also used by setup.py, as follows:
The requirements.txt file contains the acceptable range of django packages, depending on the python version installed, as follows:
Django>=1.11,<2 ; python_version == '2.7'
Django>=1.11,<3 ; python_version > '3'
For python3, I want to make sure the tests run on django 2.0 as well as the latest django 2.1+ that will be installed by default, obeying the version constraints specified in the requirements.txt file. To achieve that, I force the installation of the desired django version with commands, as follows:
[tox]
envlist = {py27,py3}-django111,py3-django{20,21}
[testenv]
deps =
-r{toxinidir}/requirements.txt
commands =
django111: pip install 'Django>=1.11,<1.12'
py3-django20: pip install 'Django>=2.0,<2.1'
py3-django21: pip install 'Django>=2.1'
pytest
Ideally I could just add to the deps variable like so:
[testenv]
deps =
-r{toxinidir}/requirements.txt
django111: Django>=1.11,<1.12
py3-django20: Django>=2.0,<2.1
py3-django21: Django>=2.1
commands =
pytest
But pip does not support double requirements and will throw an error even though there is no conflict in how the version constraints are specified.
The drawback of using commands to override the installation is that it needs to remove the django package version installed via requirements.txt to install the desired one. Is there a way to avoid that extra step?
One trick is to move the requirement from requirements.txt into setup.py - where it's loosely pinned so that all your django versions are possible. For example
# setup.py
from setuptools import setup, find_packages
setup(
...
install_requires=[
"Django>=1.11,<2.1",
]
)
and then use your second suggestion in tox.ini
[testenv]
deps =
-r{toxinidir}/requirements.txt
django111: Django>=1.11,<1.12
py3-django20: Django>=2.0,<2.1
py3-django21: Django>=2.1
commands =
pytest
... so long as the Django requirement isn't listed in requirements.txt.
This works because the pip install is split in two parts, the first from tox:deps where you specify the hard requirement, and the second from the equivalent of pip install -e . where the setup.py has the looser requirement.

Python build CFFI in API mode with Setuptools

I'm trying to learn about creating a CFFI modules, and packaging them with setuptools. When I run the build script build_foo.py I get an API mode library, but when I try to pip install . I get an ABI mode library.
Creates API mode
$> python build_foo.py
$> ls
build_foo.py _one_cffi.cpython-36m-x86_64-linux-gnu.so
_one_cffi.c _one_cffi.o
Creates ABI mode
$> pip install .
$> ls env/bin/site-packages
cffi pkg_resources
cffi-1.11.5.dist-info pkg_resources-0.0.0.dist-info
_cffi_backend.cpython-36m-x86_64-linux-gnu.so __pycache__
easy_install.py pycparser
Foo-0.1.dist-info pycparser-2.19.dist-info
foopkg setuptools
_one_cffi.abi3.so setuptools-40.6.2.dist-info
pip wheel
pip-18.1.dist-info wheel-0.32.3.dist-info
Files
build_foo.py
#!/usr/bin/env python3
import cffi
ffi = cffi.FFI()
ffi.cdef("int get_one();")
ffi.set_source("_one_cffi",
"""
int get_one() {
return 1;
}
"""
)
if __name__ == '__main__':
ffi.compile(verbose=True)
setup.py
from setuptools import setup
setup(
name = 'Foo',
version = '0.1',
packages = ['foopkg'],
cffi_modules=["foopkg/build_foo.py:ffi"],
install_requires = ['cffi']
)
I think that the filename ending with abi3.so has to do with Python's PEP 425 abi tag, not the ABI-mode option for how to use CFFI generated bindings. As far as I can tell the cffi_module install is simply failing to add any platform specific information to the shared object file, but I think that Python code that calls foopkg can still access get_one() in API-mode.

setuptools very simple (one source file module) configuration

I want to use setuptools to create a package consisting of two files: foo.py (script) and foo.conf.
Then I want to publish the package on my devpi-server and then install the package using pip.
Suppose I that initially I have my current working directory clean
$ ls -l
total 0
Then I issue pip install (or download?) command
$ pip install -i http://mydevpi.server foo
And get a dir with my two files created
$ tree
.
|
foo
|
|\_ foo.py
|
\_ foo.conf
So questions are:
what setuptools configuration should I use?
what exact pip command should I use to install the package the way I want? Will pip install -i http://mydevpi.server --target=. do the trick?
First write somethings as setup.py in foo directory like:
import setuptools
setuptools.setup(
name='foo_pip',
version='1',
packages=[''],
url='1',
license='1',
author='1',
author_email='1',
description='1'
)
(You can use distutils or setuptools)
Then python setup.py bdist_wheel -d TARGET and there will be a whl file in target directory, copy the path.
You can now install using pip install the_wheel_file_path --prefix="the_path_to_install"
Something like this
Processing .../TARGET/foo_pip-1-py2-none-any.whl
Installing collected packages: foo-pip
Successfully installed foo-pip-1
Then use it by import foo

Categories