otsukare Thoughts after a day of work

Week notes - 2020 w07 - worklog - flask blueprint

A string of secondary issues have been plaguing our restart of anonymous reporting on

new anonymous workflow reporting.

  1. A bug is reported anonymously
  2. We send the data to a private repository (waiting for moderation)
  3. We put a placeholder on the public repository, saying that this will be moderated later on.
  4. In the private repo, the moderators can either:
    • set the milestone to accepted in the private repo and the public moderation placeholder will be replaced with the real issue content.
    • close the issue in the private repo (means it has been rejected) and it will replace the public moderation placeholder by another message saying it was rejected.

Simple! I had forgotten to handle the case of private issue with milestone accepted being closed. This erased a valid moderated issue. Not good. So we fixed it. This is now working.

from string to boolean in python

There was a solution to the issue we had last week about our string which is not a boolean: strtobool. Thanks to rik. Implementation details. Values include on and off. Neat!

coverage and pytest

In the process of trying to improve the project, I looked at the results of coverage on the project. I was pleasantly surprised for some areas of the code. But I also decided to open a couple of issues related to other parts. The more and better tests we have, the more robust the project will be.

While running coverage, I also stumbled upon this sentence in the documentation:

Nose has been unmaintained for a long time. You should seriously consider adopting a different test runner.

So I decided to create an issue specific on switching from nosetests to pytest.

And I started to work on that. It led to an interesting number of new breakages and warnings. First pytest is working better with an installable code.

pip install -e .

So I created a very simple and basic

then I ran to an issue that has bitten me in the past: flask blueprint.

Do NOT name the module, the directory and the blueprint with the same name.

Basically our code has this kind of constructs. subtree to make it simpler.

-- webcompat
   |-- api
   |   |--
   |   |--
   |   |--


so in webcompat/

from webcompat.api.endpoints import api
app = Flask(__name__, static_url_path='')

and in webcompat/api/endpoints/

from webcompat.helpers import cool_feature

api = Blueprint('api', __name__, url_prefix='/api')

def somewhere(foo):
    yeah = cool_feature()

So what is happening here? The module and the blueprint share the same name. So if in a test we need to mock cool_feature:

with patch('webcompat.api.endpoints.cool_feature') as mock_cool:

We need to remember that when mocking, we do not mock the feature where it has been defined (aka webcompat.helpers.cool_feature) but where it has been imported (aka webcompat.api.endpoints.cool_feature). We will not be able to mock in this case because there will be a conflict of names. The error will be:

E    AttributeError: 'Blueprint' object has no attribute 'endpoints'

because the named webcompat.api blueprint has no attribute endpoints while the module webcompat.api has one.

So I will need to fix this next week.

changing circleCI

I also needed to changed CircleCI configuration to be able to run with pytest, even if it breaks for now.

Friday : diagnosis.

Friday I did some diagnosis and I'll do next monday and probably tuesday too.