Syntax-highlighting, declarative and composable pretty printer for Python 3.5+

tommikaikkonen, updated 🕥 2022-12-26 20:28:33

============= PrettyPrinter =============

Documentation_

Syntax-highlighting, declarative and composable pretty printer for Python 3.5+

.. code:: bash

pip install prettyprinter
  • Drop in replacement for the standard library pprint: just rename pprint to prettyprinter in your imports.
  • Uses a modified Wadler-Leijen layout algorithm for optimal formatting
  • Write pretty printers for your own types with a dead simple, declarative interface

.. image:: prettyprinterscreenshot.png :alt:

.. image:: ../prettyprinterscreenshot.png :alt:

.. image:: prettyprinterlightscreenshot.png :alt:

.. image:: ../prettyprinterlightscreenshot.png :alt:

Pretty print common Python values:

.. code:: python

>>> from datetime import datetime
>>> from prettyprinter import pprint
>>> pprint({'beautiful output': datetime.now()})
{
    'beautiful output': datetime.datetime(
        year=2017,
        month=12,
        day=12,
        hour=0,
        minute=43,
        second=4,
        microsecond=752094
    )
}

As well as your own, without any manual string formatting:

.. code:: python

>>> class MyClass:
...     def __init__(self, one, two):
...         self.one = one
...         self.two = two

>>> from prettyprinter import register_pretty, pretty_call

>>> @register_pretty(MyClass)
... def pretty_myclass(value, ctx):
...     return pretty_call(ctx, MyClass, one=value.one, two=value.two)

>>> pprint(MyClass((1, 2, 3), {'a': 1, 'b': 2}))
MyClass(one=(1, 2, 3), two={'a': 1, 'b': 2})

>>> pprint({'beautiful output': datetime.now(), 'beautiful MyClass instance': MyClass((1, 2, 3), {'a': 1, 'b': 2})})
{
    'beautiful MyClass instance': MyClass(
        one=(1, 2, 3),
        two={'a': 1, 'b': 2}
    ),
    'beautiful output': datetime.datetime(
        year=2017,
        month=12,
        day=12,
        hour=0,
        minute=44,
        second=18,
        microsecond=384219
    )
}

Comes packaged with the following pretty printer definitions, which you can enable by calling prettyprinter.install_extras():

  • datetime - (installed by default)
  • enum - (installed by default)
  • pytz - (installed by default)
  • dataclasses - any new class you create will be pretty printed automatically
  • attrs - pretty prints any new class you create with attrs
  • django - pretty prints your Models and QuerySets
  • numpy - pretty prints numpy scalars with explicit types
  • requests - pretty prints Requests, Responses, Sessions, and more from the requests library

  • Free software: MIT license

  • Documentation: Documentation_.

.. _Documentation: https://prettyprinter.readthedocs.io

Issues

Module self-reference makes it impossible to access code in `prettyprinter.py`

opened on 2023-03-06 23:13:04 by macdjord
  • PrettyPrinter version: 0.18.0
  • Python version: 3.11.2
  • Operating System: Win10

Description

I tried to import prettyprinter/prettyprinter.py so that I could properly type-hint the 'context' argument to my custom printer function. However, when I did so, I was informed that prettyprinter.prettyprinter did not contain any attribute PrettyContext.

On investigation, I discovered that prettyprinter (the package corresponding to prettyprinter/) contains, on initial import, already contains a member named prettyprinter, but this member is actually just a circular reference to the package itself. This makes it impossible to import prettyprinter.prettyprinter (the module corresponding to prettyprinter/prettyprinter.py).

What I Did

```python import prettyprinter as _prettyprinter import prettyprinter.doctypes as import prettyprinter.prettyprinter as

class Timestamp: ...

@_prettyprinter.register_pretty(Timestamp) def pretty_timestamp( timestamp: Timestamp, ctx: _prettyprinter.prettyprinter.PrettyContext, ) -> _prettyprinter.doctypes.Doc: ... ```

Output: text Traceback (most recent call last): File "[REDACTED]/test.py", line 13, in <module> ctx: _prettyprinter.prettyprinter.PrettyContext, ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: module 'prettyprinter' has no attribute 'PrettyContext'

python import prettyprinter as _prettyprinter print(f"{_prettyprinter=}") print(f"{_prettyprinter.prettyprinter=}") import prettyprinter.prettyprinter as _pp_pp print(f"{_pp_pp=}") print(f"{_pp_pp.prettyprinter=}")

Output: text _prettyprinter=<module 'prettyprinter' from 'C:\\Python311\\Lib\\site-packages\\prettyprinter\\__init__.py'> _prettyprinter.prettyprinter=<module 'prettyprinter' from 'C:\\Python311\\Lib\\site-packages\\prettyprinter\\__init__.py'> _pp_pp=<module 'prettyprinter' from 'C:\\Python311\\Lib\\site-packages\\prettyprinter\\__init__.py'> _pp_pp.prettyprinter=<module 'prettyprinter' from 'C:\\Python311\\Lib\\site-packages\\prettyprinter\\__init__.py'>

The Fix

This is caused by the following line in prettyprinter/__init__.py: python import prettyprinter.pretty_stdlib As well as actually importing the pretty_stdlib module, this also, as a side-effect, adds a member to package prettyprinter whose value is the package prettyprinter. (Actually, I'm amazed this doesn't cause an import cycle error.)

The fix is to change that line to: python from . import pretty_stdlib Or: python import prettyprinter.pretty_stdlib as __

Workaround

Until this bug is fixed, this is a workaround: python import prettyprinter as _prettyprinter del _prettyprinter.prettyprinter import prettyprinter.prettyprinter as _pp_pp Note that with this workaround you can only access the prettyprinter.py code using _pp_pp; trying to do _prettyprinter.prettyprinter will not work.

Incorrect handling of subtypes of datetime types

opened on 2023-03-06 22:19:07 by macdjord
  • PrettyPrinter version: 0.18.0
  • Python version: 3.11.2
  • Operating System: Win10

Description

If you have a user-created subtype of one of the datetime types, e.g. time, date, or datetime, and you prettyprint an instance of that subtype, the prettyprinted representation will use the class name of the base type, rather than the subtype.

What I Did

```python import datetime as _dt import prettyprinter as _prettyprinter

class Timestamp(_dt.datetime): """Standardized datatype for timestamps, i.e. a datetime which is always UTC"""

def __new__(cls, year, month=None, day=None, hour=0, minute=0, second=0, microsecond=0, tzinfo=_dt.timezone.utc, *, fold=0):
    # Call the parent method to create the object
    self = super().__new__(cls, year, month, day, hour, minute, second, microsecond, tzinfo, fold=fold)

    # Confirm the object is in UTC
    # (We have to do this after creating the object, rather than just checking the `tzinfo` arg,
    # because the parent method handles the case of loading a Pickled object.)
    if self.tzinfo != _dt.timezone.utc:
        raise ValueError(f"Timestamp must have UTC timezone; got {self!r}")
    if self.fold:
        raise ValueError(f"Timestamp are always UTC, so nonzero 'fold' is meaningless; got {self!r}")

    return self

ts = Timestamp(2023, 1, 1) _prettyprinter.pprint(ts) ```

Output: text datetime.datetime( year=2023, month=1, day=1, tzinfo=datetime.timezone.utc )

Expected output: text Timestamp( year=2023, month=1, day=1, tzinfo=datetime.timezone.utc )

The Fix

The fix for this is actually pretty simple. In pretty_stdlib.py there are functions to handle the datetime classes. These functions call pretty_call_alt() and similar functions with hard-coded references to the datetime classes. These hardcoded references should be replaced with the actual type of the passed-in instance. E.g., in def pretty_datetime(dt, ctx):, calls to pretty_call_alt(ctx, datetime, ...) should be changed to pretty_call_alt(ctx, type(dt), ...).

Curiously, it is only the datetime and pytz classes that have this problem; all the other types handled in that file, e.g. UUIDs, defaultdicts, dequeues, etc., all use type(...) already.

Bump wheel from 0.29.0 to 0.38.1

opened on 2022-12-26 20:28:32 by dependabot[bot]

Bumps wheel from 0.29.0 to 0.38.1.

Changelog

Sourced from wheel's changelog.

Release Notes

UNRELEASED

  • Updated vendored packaging to 22.0

0.38.4 (2022-11-09)

  • Fixed PKG-INFO conversion in bdist_wheel mangling UTF-8 header values in METADATA (PR by Anderson Bravalheri)

0.38.3 (2022-11-08)

  • Fixed install failure when used with --no-binary, reported on Ubuntu 20.04, by removing setup_requires from setup.cfg

0.38.2 (2022-11-05)

  • Fixed regression introduced in v0.38.1 which broke parsing of wheel file names with multiple platform tags

0.38.1 (2022-11-04)

  • Removed install dependency on setuptools
  • The future-proof fix in 0.36.0 for converting PyPy's SOABI into a abi tag was faulty. Fixed so that future changes in the SOABI will not change the tag.

0.38.0 (2022-10-21)

  • Dropped support for Python < 3.7
  • Updated vendored packaging to 21.3
  • Replaced all uses of distutils with setuptools
  • The handling of license_files (including glob patterns and default values) is now delegated to setuptools>=57.0.0 (#466). The package dependencies were updated to reflect this change.
  • Fixed potential DoS attack via the WHEEL_INFO_RE regular expression
  • Fixed ValueError: ZIP does not support timestamps before 1980 when using SOURCE_DATE_EPOCH=0 or when on-disk timestamps are earlier than 1980-01-01. Such timestamps are now changed to the minimum value before packaging.

0.37.1 (2021-12-22)

  • Fixed wheel pack duplicating the WHEEL contents when the build number has changed (#415)
  • Fixed parsing of file names containing commas in RECORD (PR by Hood Chatham)

0.37.0 (2021-08-09)

  • Added official Python 3.10 support
  • Updated vendored packaging library to v20.9

... (truncated)

Commits
  • 6f1608d Created a new release
  • cf8f5ef Moved news item from PR #484 to its proper place
  • 9ec2016 Removed install dependency on setuptools (#483)
  • 747e1f6 Fixed PyPy SOABI parsing (#484)
  • 7627548 [pre-commit.ci] pre-commit autoupdate (#480)
  • 7b9e8e1 Test on Python 3.11 final
  • a04dfef Updated the pypi-publish action
  • 94bb62c Fixed docs not building due to code style changes
  • d635664 Updated the codecov action to the latest version
  • fcb94cd Updated version to match the release
  • Additional commits viewable in compare view


Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/tommikaikkonen/prettyprinter/network/alerts).

truncated output

opened on 2022-11-10 17:58:47 by petaflot
  • PrettyPrinter version: 3.10? couldn't find anything more specific
  • Python version: 3.10.8
  • Operating System: Gentoo

Description

pretty printer truncates data ```

dict with PrettyPrinter:

{ 0: defaultdict( at 0x7fcf56d5c940>, { U: defaultdict( at 0x7fcf56d5c940>, { K: defaultdict( at 0x7fcf56d5c940>, { None: defaultdict( at 0x7fcf56d5c940>, {

there clearly is some data missing!

DICT with print():

{0: defaultdict( at 0x7fe9c7c04940>, {U: defaultdict( at 0x7fe9c7c04940>, {K: defaultdict( at 0x7fe9c7c04940>, {None: defaultdict( at 0x7fe9c7c04940>, {'UNKN_V': defaultdict( at 0x7fe9c7c04940>, {}), V0: datetime.datetime(2022, 11, 10, 18, 31, 9, 743503), V1: datetime.datetime(2022, 11, 10, 18, 31, 9, 743503)}), V0: defaultdict( at 0x7fe9c7c04940>, {'UNKN_V': defaultdict( at 0x7fe9c7c04940>, {V0: 'now I know V'})}), V1: defaultdict( at 0x7fe9c7c04940>, {'UNKN_V': defaultdict( at 0x7fe9c7c04940>, {V1: 'now I know V'})})})})})}

manually formatted:

{ 0: defaultdict( at 0x7fe9c7c04940>, { U: defaultdict( at 0x7fe9c7c04940>, { K: defaultdict( at 0x7fe9c7c04940>, {
None: defaultdict( at 0x7fe9c7c04940>, {
'UNKN_V': defaultdict( at 0x7fe9c7c04940>, {}), V0: datetime.datetime(2022, 11, 10, 18, 31, 9, 743503), V1: datetime.datetime(2022, 11, 10, 18, 31, 9, 743503) }), V0: defaultdict( at 0x7fe9c7c04940>, {
'UNKN_V': defaultdict( at 0x7fe9c7c04940>, {
V0: 'now I know V' }) }), V1: defaultdict( at 0x7fe9c7c04940>, {
'UNKN_V': defaultdict( at 0x7fe9c7c04940>, {
V1: 'now I know V' }) }) }) }) }) } ```

What I Did

```python from pprint import PrettyPrinter pprint = PrettyPrinter(indent=4).pprint # also tried with other values for 'indent' from collections import defaultdict dd = lambda: defaultdict(dd) ncache = {0: dd()}

ncache[0]['U']['K']['V0']['UNKN_V']['V0'] = 'now I know V' ncache[0]['U']['K']['V1']['UNKN_V']['V1'] = 'now I know V'

pprint(ncache) print(ncache) ```

`import prettyprinter` empties stdin when stdin reads from file.

opened on 2022-09-09 23:18:37 by Kenny2github
  • PrettyPrinter version: 0.18.0
  • Python version: 3.9.6
  • Operating System: Windows 10 Command Prompt

Description

I was trying to prettyprint the result of operating on sys.stdin.read() when I noticed that the result of that function call was always ''. I isolated the problem to the import of prettyprinter - reading stdin operates correctly before the import, and reads the empty string after. Note: This only happens when a file (not a command's output!) is being redirected to stdin.

What I Did

``` C:\Users\Public>echo test>tmp.txt

C:\Users\Public>echo test | py -c "import sys; from prettyprinter import pprint; pprint(sys.stdin.read())" 'test \n'

C:\Users\Public>py -c "import sys; from prettyprinter import pprint; pprint(sys.stdin.read())" < tmp.txt ''

C:\Users\Public>type tmp.txt | py -c "import sys; from prettyprinter import pprint; pprint(sys.stdin.read())" 'test\n' ```

Bump numpy from 1.16.1 to 1.22.0

opened on 2022-06-21 21:43:51 by dependabot[bot]

Bumps numpy from 1.16.1 to 1.22.0.

Release notes

Sourced from numpy's releases.

v1.22.0

NumPy 1.22.0 Release Notes

NumPy 1.22.0 is a big release featuring the work of 153 contributors spread over 609 pull requests. There have been many improvements, highlights are:

  • Annotations of the main namespace are essentially complete. Upstream is a moving target, so there will likely be further improvements, but the major work is done. This is probably the most user visible enhancement in this release.
  • A preliminary version of the proposed Array-API is provided. This is a step in creating a standard collection of functions that can be used across application such as CuPy and JAX.
  • NumPy now has a DLPack backend. DLPack provides a common interchange format for array (tensor) data.
  • New methods for quantile, percentile, and related functions. The new methods provide a complete set of the methods commonly found in the literature.
  • A new configurable allocator for use by downstream projects.

These are in addition to the ongoing work to provide SIMD support for commonly used functions, improvements to F2PY, and better documentation.

The Python versions supported in this release are 3.8-3.10, Python 3.7 has been dropped. Note that 32 bit wheels are only provided for Python 3.8 and 3.9 on Windows, all other wheels are 64 bits on account of Ubuntu, Fedora, and other Linux distributions dropping 32 bit support. All 64 bit wheels are also linked with 64 bit integer OpenBLAS, which should fix the occasional problems encountered by folks using truly huge arrays.

Expired deprecations

Deprecated numeric style dtype strings have been removed

Using the strings "Bytes0", "Datetime64", "Str0", "Uint32", and "Uint64" as a dtype will now raise a TypeError.

(gh-19539)

Expired deprecations for loads, ndfromtxt, and mafromtxt in npyio

numpy.loads was deprecated in v1.15, with the recommendation that users use pickle.loads instead. ndfromtxt and mafromtxt were both deprecated in v1.17 - users should use numpy.genfromtxt instead with the appropriate value for the usemask parameter.

(gh-19615)

... (truncated)

Commits


Dependabot compatibility score

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


Dependabot commands and options
You can trigger Dependabot actions by commenting on this PR: - `@dependabot rebase` will rebase this PR - `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it - `@dependabot merge` will merge this PR after your CI passes on it - `@dependabot squash and merge` will squash and merge this PR after your CI passes on it - `@dependabot cancel merge` will cancel a previously requested merge and block automerging - `@dependabot reopen` will reopen this PR if it is closed - `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually - `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself) - `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself) - `@dependabot use these labels` will set the current labels as the default for future PRs for this repo and language - `@dependabot use these reviewers` will set the current reviewers as the default for future PRs for this repo and language - `@dependabot use these assignees` will set the current assignees as the default for future PRs for this repo and language - `@dependabot use this milestone` will set the current milestone as the default for future PRs for this repo and language You can disable automated security fix PRs for this repo from the [Security Alerts page](https://github.com/tommikaikkonen/prettyprinter/network/alerts).

pretty print prettyprinter prettyprint