Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Spring cleaning #788

Merged
merged 62 commits into from
Apr 30, 2018
Merged

Spring cleaning #788

merged 62 commits into from
Apr 30, 2018

Conversation

obestwalter
Copy link
Member

@obestwalter obestwalter commented Apr 14, 2018

see commit messages for details. This might grow a bit more over the next days, as I have some time at my hands and want to tidy up the code base a bit.

closes #797
closes #798
closes #799
closes #800
closes #801
closes #754

Also (no extra issues for that):

  • removed all experimental markers from docstrings (most of them have been there for a few years already). If they turn out wrong/bad, we just have to deprecate them and remove them in a major release
  • hookimpl is instantiated twice - mark one of them as deprecated and get rid of it later
  • moved hookimpl to __init__.py - having a hookimpl object in the hookspecs module is unnecessary and confusing. Access to hookimpl should happen as module attribute of tox (clearer where it comes from) - also kept a deprecated reference there for compatibilty.
  • removed some redundant rst references in hookspecs. If they are initialized once in any namespace they are defined globally (I don't like it either but that is how it works in restructuredText and ignoring that and defining the same things several times is confusing)
  • move _dummy object to only class where it is needed and name it like the constant that it is
  • use six for py2/3 compatibility where noticed it and where it is cheap to do
  • remove dead code
  • move exception related code into its own module rather than having it hang around in a class looking like a module in __init__.py
  • there is no need to have an intermediate run_main - that is used everywhere only under the name tox.cmdline rename function and use it directly, just like client code is using it
  • add a fixture for working in a clean tmpdir

* add reference to new cookiecutter
* add a little tutorial with a concrete plugin to explain minimal reqs
* add some explanations regarding naming
Sorry, this is a lot and it will get even more. I have some large chunks of time to spent with tox and I am going through with the big brush. I want to move towards a big clean up which will result in a tox 4 not to far into the future. These are the first steps. Part of this is getting stuff sorted for plugins to be more like 1. class citizens and stabilizing the API. A lot of things have been marked as experimental for many years now and it is time to let this go and rather deprecate things, if they should go away, instead of letting them hang around as experimental for ages.

Start hookimpl/hookspec objects deprecation

They are used in some places by importing direclty from tox. This might have been the right way a loing time ago, but now pluggy has an API to create those objects via pluggy.HookImplMarker and pluggy.HookSpecMarker without the need of importing them.

hookimpl needs to be initiated for internal use and should be marked that way. Plugin writers
should use the official API instead of importing it from tox.

* removed all experimental markers from docstrings. If they turn out wrong/bad,
  we just have to deprecate them and remove them in a major release
* also hookimpl is instantiated twice - mark these objects as deprecated and
  get rid of one of them later
* especially having a hookimpl object in the hookspecs module is unnecessary and confusing
* access hookimpl as module attribute of tox (clearer where it comes from)
* removed some redundant rst references. If they are initialized once in any
  namespace they are defined globally (I don't like it either but that is how it
  works in restructuredText and ignroring that and defining the same things
  several times is confusing)

tox-quickstart script and tests overhaul

* never overwrite existing files - even if the user tries
* make py36 the default environment rather than py27 if 1 is chosen
* do not refer to the configuration as tox.ini as it might not be tox.ini but something else
* refactor tests for readability and maintainability
* adapt tests to new behaviour
* refine some code having to do with usere input that turns into lists
* remove unused flags from main
* naming things (like, too terse or shadowing builtins, etc.)
* whitespace (try to make it more consistent)
* remove some redundant internal tests. Going through main is perfectly adequate and makes the tests more resilient to internal changes

Other stuff

* tox has an API already although this was never really planned - add comment to __all__ to make clear that this is the only 'official' API and that hookimpl and hookspec are not part of it
* tidy up imports (prefer module imports to make clear where stuff comes from)
* move _dummy object to only class where it is needed and name it like the constant that it is
* use six for py2/3 compatibility where I notice it and where it is cheap to do
* remove dead code
* move exception related code into its own module rather than having it hang around in __init__.py
* there is no need to have an intermediate run_main - that is used everywhere only under the name tox.cmdline rename function and use it directly, just like client code is using it
* add a fixture for working in a clean tmpdir
It is used by plugin tests for tox-venv and it should not be marked private then.

Added a note in the docstring about coordinating if this has to change
Added a simple compat layer to tox-venv - this should be released soonish to be ready for that change in tox
@obestwalter
Copy link
Member Author

obestwalter commented Apr 14, 2018

[removed obsolete content. Relevant points are now in first post.]

Copy link
Contributor

@asottile asottile left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

reviewed commit-by-commit -- looks good! 👍

@@ -34,6 +34,15 @@ def pytest_report_header():
return "tox comes from: {}".format(repr(tox.__file__))


@pytest.fixture
def work_in_clean_dir(tmpdir):
old = tmpdir.chdir()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's tmpdir.as_cwd() ctx for this

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cool - thanks :)

@codecov
Copy link

codecov bot commented Apr 14, 2018

Codecov Report

Merging #788 into master will decrease coverage by <.01%.
The diff coverage is 92.62%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #788      +/-   ##
==========================================
- Coverage   94.85%   94.84%   -0.01%     
==========================================
  Files          11       13       +2     
  Lines        2408     2404       -4     
==========================================
- Hits         2284     2280       -4     
  Misses        124      124
Impacted Files Coverage Δ
tox/_verlib.py 83.15% <ø> (ø) ⬆️
tox/__main__.py 0% <0%> (ø) ⬆️
tox/exception.py 100% <100%> (ø)
tox/interpreters.py 92.85% <100%> (ø) ⬆️
tox/_pytestplugin.py 95.53% <100%> (-0.02%) ⬇️
tox/venv.py 96.55% <100%> (-0.02%) ⬇️
tox/constants.py 100% <100%> (ø)
tox/config.py 97.75% <100%> (-0.02%) ⬇️
tox/hookspecs.py 100% <100%> (ø) ⬆️
tox/session.py 94.75% <100%> (-0.02%) ⬇️
... and 5 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update e603f78...e59afae. Read the comment docs.

Copy link
Member

@rpkilby rpkilby left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey. I just did a quick once-over and haven't reviewed the code in depth. Just a few minor documentation suggestions.

doc/plugins.rst Outdated
If you have a ``tox_MYPLUGIN.py`` module you could use the following
rough ``setup.py`` to make it into a package which you can upload to the
Python packaging index:
You can create a new tox plugin with all bells and whistles via `Cookiecutter`_ (see `cookiecutter-tox-plugin <https://github.com/tox-dev/cookiecutter-tox-plugin>`_):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

with all bells should be with all the bells

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fixed.

doc/plugins.rst Outdated
If installed, the ``entry_points`` part will make tox see and integrate
your plugin during startup.
This will create a complete pypi-releasable, documented project with license, documentation,
CI builds and other bells and whistles.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

documented project with license, documentation,

Is a little redundant. "bells and whistles" has also been used recently Maybe...

This will create a complete, PyPI-ready package with a license, documentation, tests, and CI via Travis and Appveyor.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Definitely too many bells and whistles :)

doc/plugins.rst Outdated
.. code-block:: console

$ cd </path/to/tox-fireworks>
$ python setup.py sdist register upload
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  • The register command has been disabled and rolled into the upload command.
  • Should the instructions also include wheel & twine?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added bdist_wheell, threw out the register thingy and added a hint to the Python Packaging Guide.

' - nosetests package.module\n'
' - trial package.module\n')
do_prompt(map_, 'commands', 'Type the command to run your tests',
default='pytest', modificator=list_modificator)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally prefer to keep defaults/recommendations to the standard library. Maybe python -m unittest discover?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea - I also thought that nose is not really alive and well anymore for a long time, so I will replace it with your suggested unittest call.

doc/plugins.rst Outdated
@@ -85,8 +85,10 @@ it like:
.. code-block:: console

$ cd </path/to/tox-fireworks>
$ python setup.py sdist register upload
$ python setup.py sdist bdist_wheel upload

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there's a typo in this commit message, can be left as it is if you do a squash merge, otherwise I suggest a reword 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imprve definitely needs improving :)

@@ -8,6 +8,7 @@
import pytest

import tox
import tox.exc
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not too happy with this exc, can we make it something more descriptive?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yep - we can have a module with the full name instead I think.

Copy link
Member

@gaborbernat gaborbernat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another thing we might want to consider, now we have everything public here, if we make an official API should we maybe move to the private module approach of pytest? and have a root level __init__.py where we expose explicitly whatever we consider public?

tox/__init__.py Outdated
from pkg_resources import DistributionNotFound
from pkg_resources import get_distribution

from .hookspecs import hookimpl
from .exc import exception # noqa
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is the noqa needed here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dunno, might not be necessary at all, but given that I will do some work on exception now I'll check.

tox/__init__.py Outdated

"""

# DEPRECATED - will go away in tox 4
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can we add some proxy thing for this to emit deprecation warning if imported instead of the deprecated comments? https://docs.python.org/2/library/exceptions.html#exceptions.DeprecationWarning

that way people using it will get some runtime noise to notify them 😄

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had the same idea already, but was not immediately sure how to accomplish that given a module level object. I will definitely look into that. I want to wait first though for input from @RonnyPfannschmidt as he made a comment that needs further clarification (tox-dev/detox#12 (comment)). It might be that I got this part completely wrong and it needs a rework and undoing of a lot of PRs I opened - I really hope not, but life is unfair sometimes :D

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so found out https://www.python.org/dev/peps/pep-0562/ is for this, also shows a workaround for python 2 compatibility: Typical workarounds are assigning __class__ of a module object to a custom subclass of types.ModuleType or replacing the sys.modules item with a custom wrapper instance.

tox/exc.py Outdated
return str_


class exception:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we use this as a namespace, wouldn't be nicer to make it a module, and use it as a file instead? this class thingy breaks PEP-8 and seems un-pythonic

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is definitely much saner than what I did. Then we would have an exception module and the naming thing is also sorted.

tox/result.py Outdated
dict = {}
self.dict = dict
self.dict.update({"reportversion": "1", "toxversion": toxver})
def __init__(self, result_dict=None):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we have some pep-8 analyser to the project, how this gets through? (according to that really should be an empty line here)

Copy link
Member Author

@obestwalter obestwalter Apr 15, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

having an empty line between class statement and first method or docstring is optional and in fact most classes do not have that space in tox (48 vs 0 to be exact in main code - spaces are only in test classes). I prefer not having it also - I am a bit stingy with my vertical whitespace. I also avoid it inside methods and functions and rather split functionality out if for some reason I feel the need to have blocks)).

I will fix the classes in the tests still containing classes for consistency.

Copy link
Member

@gaborbernat gaborbernat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

another thing we might want to consider, now we have everything public here, if we make an official API should we maybe move to the private module approach of pytest? and have a root level __init__.py where we expose explicitly whatever we consider public?

@obestwalter
Copy link
Member Author

obestwalter commented Apr 15, 2018

Thanks @gaborbernat! There are a lot of good points you made. I will address them over the course of today.

Regarding individual commit messages: I think there is going to be a lot of back and forth until things are right and I have to admit, when I am in this kind of mode I tend to do a lot of things at the same time, which shows in the cleanliness or rather lack of cleanliness of the commits. So I think once this is tidy we should definitely squash it. I will keep an extensive log of the changes and why we made them. Before merging, I will also have a look at the complete diff and make sure all important changes are explained.

* add another layer of testing that checks the generated config
* naming things
* replace nose example and test with unittest
* simplify actual test and do more work in test helpers
* add another function to be used by code and test to unify generated output
@gaborbernat
Copy link
Member

Sure works for me 👌

@obestwalter
Copy link
Member Author

Created some issues and changelog entries that will be closed as a side effect of this cleaning session. This should be it for this time I'd say.

@obestwalter
Copy link
Member Author

There. I think I will merge this on monday and push it out as an rc right away, so that we can start merging and releasing "real" PRs soon again :)

@obestwalter obestwalter mentioned this pull request Apr 28, 2018
Copy link
Member

@gaborbernat gaborbernat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re-commented on few of the unaddressed issues; definitely this became a monster PR, content wise seems mostly okay though!

@@ -781,7 +781,7 @@ Improved Documentation
location ({envtmpdir}/pseudo-home). If an index url was specified
a .pydistutils.cfg file will be written with an index_url setting
so that packages defining ``setup_requires`` dependencies will not
silently use your HOME-directory settings or https://pypi.python.org/pypi.
silently use your HOME-directory settings or PyPi.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed a link here?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

broken.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my point was maybe we should have replaced it with http://pypi.org instead of removing it.

@@ -6,3 +6,6 @@ include setup.py
include tox.ini
graft doc
graft tests

global-exclude __pycache__
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still unsure why we need these includes?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are excludes :) because otherwise it is possible to pollute a release package with these files.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see my point in #754 (comment)

@@ -6,3 +6,6 @@ include setup.py
include tox.ini
graft doc
graft tests
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graft?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@@ -20,8 +20,8 @@ def has_environment_marker_support():
try:
v = pkg_resources.parse_version(setuptools.__version__)
return v >= pkg_resources.parse_version('0.7.2')
except Exception as exc:
sys.stderr.write("Could not test setuptool's version: %s\n" % exc)
except Exception as e:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

any thoughts on this?


@pytest.fixture
def interpreters():
from tox.interpreters import (
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ping again on this :-)

def test_test_hashseed_is_in_output(newmocksession, monkeypatch):
seed = '123456789'
monkeypatch.setattr('tox.config.make_hashseed', lambda: seed)
mocksession = newmocksession([], "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I beg to differ, given @hpk42 is not actively maintaining this anymore I would prefer us to have Pythonic names now, and yes that involves changing some conventions here and there.

commands = sphinx-build -d "{toxworkdir}/docs_doctree" doc "{toxworkdir}/docs_out" --color -W -bhtml
sphinx-build -d "{toxworkdir}/docs_doctree" doc "{toxworkdir}/docs_out" --color -W -blinkcheck
commands =
sphinx-build -d "{toxworkdir}/docs_doctree" doc "{toxworkdir}/docs_out" --color -W -bhtml
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems to me like adds no value, other than increasing the number of lines and changes in this file; and makes it inconsistent with other lines aligning content left to the =

Copy link
Member

@gaborbernat gaborbernat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re-commented on few of the unaddressed issues; definitely this became a monster PR, content wise seems mostly okay though!

@obestwalter
Copy link
Member Author

obestwalter commented Apr 30, 2018

HI @gaborbernat there are a few other comments that I can't answer on directly (don't know why, I just don't have a reply window there).

About the currently dominating no-case naming convention: I have no problem with it. Also: If you grep the code base for mocksession you have 418 hits, so I am not starting to use a different name when I touch this. Renaming them all to mock_session just adds another character, so why bother?

FWIW In my own projects I actually intentionally break the slug case naming convention for names (I use camelCase for everything that behaves like data (including properties) and slug_case for everything that behaves like a function).

About that import stuff: we should really automate this soonish with a pre-commit setting that does not create 10 lines of code for 10 imports from the same module and use it consistently. Hope some hero will finish that patch that is in the works for this. I am usually a friend of minimizing vertical space without impairing legibility, so this is why I format imports like this until some automatic formatter comes along - this way of formatting also works with automatic imports in PyCharm btw. Formatting with 4 spaces indent on next line instead of along wherever the first import starts on the import line looks more consistent to me and yields longer lines for the actual imports, so it usually needs the same amount of vertical space. I use parentheses instead of backslashes because I only use backslashes as line breaks if I really absoutely have to, which is AFAIK only with assert statement messages:

assert something, \
    "some looooooooooooooooooooooooooooooooooooong message"

@obestwalter
Copy link
Member Author

obestwalter commented Apr 30, 2018

And the last thing:

I prefer

deps = 
    foo
    bar
    baz

over

deps = foo
       bar
       baz

for the same reason I prefer

from bla import (
    bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, 
    bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, 
    bla, bla, bla, bla, bla, bla, bla, bla)

over

from bla import (bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, 
                 bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, 
                 bla, bla, bla, bla, bla, bla, bla, bla, bla, bla, 
                 bla, bla, bla, bla)

When I adjust code working towards making it more consistent, then my muscle memory does these things, because that is how I am doing it for many years now. In the long run things like this should be auto formatted anyway and if this happens I don't really care either way as long as it is consistent and does not waste space like e.g.:

from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 
from bla import bla 

Copy link
Member

@gaborbernat gaborbernat left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I really-really-really don't like the way import look with parenthesis, or the line breaks, or the snake case breaking. But I see your hate towards the \ char, and can understand muscle memory so I suppose ok.

As for why bother with snake case renaming? cause it makes the code more readable.

@obestwalter obestwalter merged commit ff7143e into tox-dev:master Apr 30, 2018
@obestwalter obestwalter deleted the spring-cleaning branch April 30, 2018 12:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
4 participants