Hacktoberfest #4 - View.py Linting and Static Type Checking
Published: 2023-10-28 23:10:34

### Quick Links
Project I contributed to: https://github.com/ZeroIntensity/view.py
Issue I worked on: https://github.com/ZeroIntensity/view.py/issues/34
My Pull Request: https://github.com/ZeroIntensity/view.py/pull/73

<hr>

### My Final Hacktoberfest 2023 Contribution
Hacktoberfest 2023 is nearing it's end. In the past weeks I've contributed to awesome projects written in C++ and TypeScript. For my final contribution I wanted to work on something new. In my search for another cool project I found [View.py](https://github.com/ZeroIntensity/view.py) by [ZeroIntensity](https://github.com/ZeroIntensity).

### The View.py Web Framework
[View.py](https://view.zintensity.dev/) is a web framework. Web frameworks are used for developing web applications. Popular web frameworks include Angular, Express, and Django. Like Django, View.py is a web framework for Python and written in Python. In the past I've worked on web apps, but never a web framework. At the time of writing, View.py is in it's pre-alpha stage, and working on it at this stage gave me an idea of how one might go about starting out a project like this.

### My Contribution - Linting and Static Type Checking Support
The [Issue](https://github.com/ZeroIntensity/view.py/issues/34) I worked on was a feature request to add a Linting and Static Type Checking library.

#### Linting
Linting describes the process in which code is analyzed or scanned for programming errors, bugs, style errors and other suspicious code. Linting is useful in software development as it helps enforce a project's style guide.

#### Static Type Checking
Along a similar vein is static type checking, which verifies a program's type safety (how well type errors are avoided) based on written code. Static type checkers can be considered a minor form of program verification, as they help ensure that variables and functions in a program are used correctly.

Both linting and static type checking are good to use when developing a program, but can be difficult to implement from scratch. Luckily, many libraries for [linting](https://github.com/caramelomartins/awesome-linters) and [static type checking](https://github.com/analysis-tools-dev/static-analysis) exist for developers to add to their projects.

### My Pull Request and What I've Learned
The following describes how I went about working on my contribution, my [Pull Request](https://github.com/ZeroIntensity/view.py/pull/73) and some things I learned along the way.

#### Package Management in Node JS vs. Python
For those familiar with development in NodeJS, production and development dependencies are managed by npm through the [package.json](https://nodesource.com/blog/the-basics-of-package-json/#:~:text=The%20package.,modules%2C%20packages%2C%20and%20more.) file. When working on this issue, I was searching for the equivalent system in Python. I have limited experience with Python, and the Python programs I have written were all written in one Python file each. Due to this, I was initially confused as to how a Python program would support project management. After a few minutes reading through the codebase, I noticed one file at root of the project: `pyproject.toml`

#### Python Package Management with `pyproject.toml`
The filename `pyproject.toml` stood out to me. I learned about TOML-formatted files when working on my Open Source class, and remembered these files are primary used for configuration purposes.
Based on what I observed in `pyproject.toml` and reading a related [Python Enhancement Proposal](https://peps.python.org/pep-0621/#dependencies-optional-dependencies) (PEP), it looks like `pyproject.toml` is one Python equivalent to NodeJS's `package.json` and can be used to specify project dependencies.
From these observations I figured this would be the appropriate place to add the linting and static type checking dependencies.

#### Python Linting and Static Type Checker Libraries
In the issue, the author requested [mypy](https://mypy-lang.org/) to be added as the Static Type Checker, but I had a choice between two Linting libraries: [flake8](https://flake8.pycqa.org/en/latest/) and [ruff](https://docs.astral.sh/ruff/). Both are popular Python linting libraries, but I decided on ruff. ruff is 10-100 times faster than other Python linters like flake8 (at least, according to the [ruff website](https://docs.astral.sh/ruff/):

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ju08lrgexnd256mhh21r.png)

I also chose ruff over flake8 due to its `pyproject.toml` configuration support. Some Python libraries can be configured through the `pyproject.toml` file. ruff supports [configuration through pyproject.toml](https://docs.astral.sh/ruff/configuration/), but [flake8 currently does not](https://pypi.org/project/Flake8-pyproject/). It is important to note that `flake8` has other configuration methods, and that `pyproject.toml` is not the only configuration location for `ruff`, I think current and future maintainers might appreciate the option to configure linting rules in `pyproject.toml`.

After deciding on the linter library, I added the packages names to `pyproject.toml` in an [optional dependency group](https://peps.python.org/pep-0631/#optional-dependencies) called "dev":
```
[project.optional-dependencies]
dev = [
  "ruff",
  "mypy"
]
```
Optional dependencies will not be installed when installing a Python project from scratch (using `pip install .`). My justification for adding `ruff` and `mypy` as optional dependencies is that they appear to be developer dependencies (useful for development) that aren't required for production.

With the above code, `View.py` can be built with these dependencies also included by running `pip install .[dev]` from the project root

#### Discord as a Communication Channel
In the past projects I've contributed to for Hacktoberest, I only used communicated with project authors and maintainers through the associated Issues and Pull Requests. For this project I was able to reach out to the author and other contributors on the project's Discord server.

### Conclusion
Contributing to `View.py` was a good first exposure to working on a Python project. Adding dependencies for linting and static type checking required me to research and learn about setting up a Python project, package management using `pyproject.toml`, optional dependency placement, weighing the pros and cons between similar libraries, and how to reach out to project maintainers outside of the repository page. What at first seemed like a simple task intimidated me as I was learning some of these things for the first time, but after working on this task I am more confident contributing to Python projects like this.