Skip to content


Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?

Latest commit


Git stats


Failed to load latest commit information.
Latest commit message
Commit time

EO principles respected here We recommend IntelliJ IDEA

Build Status codecov Maintainability Rating Quality Gate Status Vulnerabilities Duplicated Lines (%) Code Smells Security Rating Technical Debt Hits-of-Code License: MIT

PEON (In development now)

Table of contents


What is that?

"Python Elegant Objects Naive" linter allows you to check your code for conditions of "Elegant objects" OOP architecture, proposed by yegor256

This repo works only for python code.

What eo principles i can check?

Priciple Yes/No
No null ✔️
No code in constructors ✔️
No getters and setters ✔️
No mutable objects ✔️
No readers, parsers, controllers, sorters, and so on ✔️
No static methods, not even private ones ✔️
No instanceof, type casting, or reflection ✔️
No public methods without a contract
No statements in test methods except assertThat ✔️
No ORM or ActiveRecord
No implementation inheritance ✔️

✔️ - realized

⁉️ - so-so (not sure)

- not done yet

- will never be done, i think

Python versions compability

Version Yes/No Why
3.6 ✔️
3.7 ✔️
3.8 ✔️
3.9 ✔️


From shell

Simply you should run something like this (dont forget to python3 install)

peon ./path/to/code

or not recommended way

python3 ./peon/

Add linter to pre-commit hooks

You can use this linter by adding it to pre-commit configuration file.

For example (for check all project):

  - repo:
    rev: '0.13'
      - id: peon
          - commit
          - ./peon

or (for check only changed files):

  - repo:
    rev: '0.13'
      - id: peon
          - commit

Some theoretical nuances

Why naive?

Because it checks only "plain definitions".

For example:

  • good, linter check that:
def some_function(some_arg):
   some_var = some_arg
  • bad, linter skip that (definition inside definiton - discourage and decrease code quality):
def some_function(some_arg):
   def some_another_function(some_arg):
       return some_arg
   some_var = some_another_function(some_arg)
  • good, linter check that:
class SomeClass:
  • bad, linter skip that (definition inside definiton - discourage and decrease code quality):
class SomeClass:
   class SomeAnotherClass:



After you clone repo:

  • create virtual env

python3 -m venv /path/to/new/virtual/environment

  • install requirements

pip3 install - r ./peon/requirements.txt

  • install pre-commit hooks

pre-commit install

  • setup PYTHONPATH

export PYTHONPATH=$PWD/peon

And then feel free to make a changes.


You can start local test:

make tests

this instruction starts - unit, mutual and security tests.

You can test pre-commit integration:

make local-run

Show results of mutual tests:

mutmut results

Show result of concrete mutual test:

mutmut show <test_id:int>


Easiest way is:

  • fork
  • make changes at your branch
  • commit and create PR to dev branch of this repo

If all check would be passed - I check your changes so fast, as i can.

P.S.: falling of mutual tests - is normal now (in development, as you remember)

Commit naming conventions

Every commit should start with keyword with colon:

  • feature: (if you add new functionality)
  • fix: (if you fix bug or invalid behaviour)
  • chore: (if you fix something, that you were not going to fix)

Then, after keyword you should shortly describe your changes: feature: add sec test step to travis

Pull request naming conventions

Every pull request to dev should start with keyword pr-dev and issue number: pr-dev: 123

Every pull request to master should start with keyword pr and issue number: pr: 123