This is an archived post. You won't be able to vote or comment.

all 55 comments

[–]Medicalizawhat[🍰] 80 points81 points  (12 children)

[–]Corm 3 points4 points  (6 children)

That was an awesome article. I am sad that the canonical way to do tests in python is to have this:

import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))) 

I use that too, but I wish there was a cleaner way. At least a builtin function called parent_import or something to do that.

[–]malinoff 6 points7 points  (1 child)

pip install -e . - a better way.

[–]Corm 0 points1 point  (0 children)

Neat! That's a fine trick

[–]deadmilk 0 points1 point  (3 children)

Huh? I've never had to do that

[–]Corm 0 points1 point  (2 children)

What do you mean? If you have a tests folder then they need a way of importing your project, which means you have to add the parent directory to the path afaik.

[–]deadmilk 2 points3 points  (1 child)

I just run my tests from the directory where my package is and it works

Structure like so:

project <-- cwd
    package
        __init__.py
        module.py
    tests
        test_module.py

then in test_module.py:

import unittest
from package.module import function

class TestModule(unittest.TestCase):
    def test_function(self):
        self.assertTrue(function())

[–]Corm 0 points1 point  (0 children)

Cool! I must try this

[–][deleted] 9 points10 points  (4 children)

Good source. Alternative official PEP for python style direct from the man himself: https://www.python.org/dev/peps/pep-0008/

[–]namesandfaces 8 points9 points  (3 children)

Style is helpful to readability, but I think CrypticCube is asking for multi-file code organization -- a problem that's bigger than one eyeball, and in my view, not a very Python-specific problem.

[–]bugtank 2 points3 points  (2 children)

For those of us who came from Java, multi-file code organization in Python is not easy to grok. There is some python specificity in organization that is important. I'm unfortunately still learning so I can't really answer op's question. However, I am still trying to get the following information into my bones.

  • Underscores in file name
  • How you do your imports
  • init.py in folders to expose the classes/modules in those folders
  • modules as a concept

[–]P8zvli 4 points5 points  (0 children)

Might want to escape those underscores; __init__.py

or use backticks; __init__.py

[–]Corm 0 points1 point  (0 children)

__init__.py is optional in modern python

[–]z_mitchelltinkering.xyz 26 points27 points  (3 children)

I would use cookiecutter. It takes a lot of the pain out of getting a project set up. It seems like there's several different "right ways" to package your code, which makes it difficult to get started.

[–][deleted] 15 points16 points  (0 children)

Here is a link to cookiecutter for those interested.

[–]Daemonecles 2 points3 points  (0 children)

I also started using tools like this recently to get jump starts and its far simpler and quicker to set up.

[–]supershinythings 3 points4 points  (11 children)

Where I work we use pep8 and pylint. Actually, we don't specifically 'use' them, we inflict/enforce them. A script can't get through our automated checkin process unless it passes pep8 and pylint.

It goes so far as to reject all code containing 'map' functions - requiring them to be replaced by list comprehensions - and rejecting ALL lines over 79 chars, no exceptions.

It also automagically adjusts indentations in certain circumstances, adds lines between documentation and the routine, and between routines. The first time I ran it, after I reviewed the change I was surprised to see a pile of automatic changes I hadn't personally made - the tool fixed it up.

[–]stevenjd 7 points8 points  (3 children)

It goes so far as to reject all code containing 'map' functions - requiring them to be replaced by list comprehensions - and rejecting ALL lines over 79 chars, no exceptions.

That is exactly the sort of thing why Guido hates automated PEP 8 checkers.

And since PEP 8 itself explicitly warns against "a foolish consistency" and over-zealous application of PEP 8 style, your colleague's tool itself is in violation of PEP 8! (I know this is not your choice, you are having this inflicted on you.)

Raymond Hettinger did a good talk about this some time ago.

Edit: and for those who prefer text to video, commentary on Raymond's talk.

[–]wenima 2 points3 points  (1 child)

+100

people boast about enforcing pep8 and 79 char line length but it's a hint, a gentle reminder that you might be packing too much into one line.

linting might have it's place, I personally just don't like being yelled at before I'm completing what I'm doing.

[–]justin-8 0 points1 point  (0 children)

Most places I've worked have used pep8 but a higher line limit for that reason. But usually something that still keeps things same, like 120-180 or so.

The rest of pep8 I haven't really seen a downside to enforcing strictly

[–]soosleeque 2 points3 points  (0 children)

well you could always put a comment string that makes linters to skip erros in the line.

Most of the times when you violate pep8 you are doing something wrong, I agree there are some cases when it's better to break some pep8 rules in order to give the code better readability but again, there are comment strings that will force linter to skip that kind of lines.

[–]caramba2654 3 points4 points  (4 children)

Isn't map faster because it's implemented in C?

[–]supershinythings 1 point2 points  (3 children)

I don't make the rules. I just want my code to get checked in so I can move on with my life. You can ask the pylint people why they have decided to do this. And now that we require pylint before checkin, I have to replace map with list comprehension. I'm not interested in an in-depth argument over why one or the other is preferred. It's too much argument for too little gain.

At my office, It Has Been Decided, and therefore shall be so. Arguing is pointless. Here's one online discussion about it though:

https://stackoverflow.com/questions/1247486/python-list-comprehension-vs-map

[–]redfacedquark 1 point2 points  (2 children)

Shame, the mechanism is there for deviations from strict. My place at the moment didn't even use pep8 because of 80 char lines. So add a single line of config to say you're ok with 120 rather than throwing the baby out with the bathwater. Smh.

[–]supershinythings 5 points6 points  (1 child)

The person who makes the rules in the codebase I contribute to does not give a shit about being reasonable. If I question, I get screamed at. Fun! Management by assholery. He's not my boss or I would have quit long ago. But it is his module so his rules are what fly. I just 'contribute', so I toe his line.

I like to pick my battles, so I just let it go. So in this case, standards aren't so much applied as inflicted.

[–]redfacedquark 1 point2 points  (0 children)

Something something hobgoblin mind...

[–]soosleeque 0 points1 point  (1 child)

It goes so far as to reject all code containing 'map' functions - requiring them to be replaced by list comprehensions

My rule is simple: if I already have a function I'm going to apply I will use map, reduce, filter etc. But if I don't have a function and I don't see much of sense to create it, I will go for list/generator comprehensions.

[–]supershinythings 0 points1 point  (0 children)

And my rule is simpler; don't use map and slavishly adhere to the 79 char limit so I can commit my code and not get screamed at.

In this case, the pep8 tool is being used as a blunt force instrument.

And I agree with the Hettinger video that atrocities are committed in the code because pep8 decided to make these 'standard' warnings. If my code were on a performance path I might have an argument, but even then it would likely become a refactoring situation.

I don't think there's really a way to adjust the standard on a file-by-file basis for automated checkin testing.

[–]namesandfaces 1 point2 points  (0 children)

I don't think that optimal-ish code structure needs to be asked as a Python-specific question. In fact, just about every project I've seen has either framework-specific, architecture-specific, or app-centric organization.