Skip to content

Commit 7158e31

Browse files
committed
cleanup: Improve style, formatting; use flake8, isort
This is a style cleanup, to increase code clarity and consistency, supported by manual inspection, flake8, and isort. Most, but not all, of these changes are to formatting, or to the way imports are sorted and grouped (including removing unused imports). This adds flake8, which had a configuration in setup.cfg and seems to have previously been used, as well as isort. It configures them for consistency with black and with the overall preexisting style. This includes changing the line length to 88, which black uses. The old pep8 configuration is removed, because pep8 was renamed to pycodestyle, and the old pycodestyle is removed, because it doesn't need to be run directly, since flake8 runs it and passes it an appropriate configuration derived from its own. This commit sets up flake8 and isort for local use, but it does not add them to CI. Although flake8 detects many things black does not, they partially overlap in their detection of overly long lines. The black rule is more nuanced, rightly skipping over long strings in test data that would be less clear if split across multiple lines. However, flake8 detects comments and docstrings that should be wrapped, so I didn't turn off the flake8 rule. (Such long strings in tests are the only cases where an inline "noqa:" suppression was needed.) Besides tool-recommended changes, these other changes are included: - Added the common virtualenv dirs venv and .venv to .gitignore. - Fixed typos in comments. Made a few clarity/consistency tweaks. - Moved a buried module docstring to top-of-file and expanded it. - Turned a docstring that was meant as a comment into a comment. - Made the use of initial and final newlines in and next to docstrings consistent within files, when doing so also made it more consistent with the overall style used in the project. - Moved __all__ above other code (as PEP-8 recommends). - Changed one __all__ from tuple to list. __all__ can be any sequence of strings, but the other, more prominent __all__ was a list (and using a list is a much more common practice). - Replaced a few relative imports with absolute imports, since the overall style in this codebase is to use absolute imports. - Changed "import X.Y as Y" to "from X import Y", which was sometimes also used nearby and which sometimes allowed imports to be consolidated. - When "import X.Y" appeared *in X*, changed to "from X import Y". (Importing a submodule makes it accessible via its parent, so this has a similar effect. The main relevant differences, in this codebase, are to omit the unnecessary X.X bindings, and to make it easier for editors/IDEs and less experienced human programmers to understand what the code is doing.) - In select cases where it seemed to noticeably improve clarity, changed "import X.Y" (outside X) into "from X import Y" and shortened the code using Y accordingly. (Mostly only when other imports "from X" were present and being used similarly to Y.) - Used raw string literals for all regular expressions. - Removed "noqa" (and applied tool-recommended fixes) in cases where "noqa" seems to have been added for expediency or to work around a combination of limitations in the old flake8 configuration and old behavior of black (rather than to express a preference that the code be kept exactly as it was). Notable omissions: - Although flake8 and isort are configured to ignore versioneer.py, black must still be called with "--extend-exclude=versioneer.py". Customizing black's configuration would require a pyproject.toml file to be added, so that is deferred for now. - To limit scope, this does not create any new CI jobs. (Such jobs would also not pass yet, due to the next two omissions.) - No changes are made to conftest.py, since it may make sense to make deprecation-related non-style changes at the same time. - In test_regression_143, the unused "validate" variables are kept, because non-stylistic considerations should determine what changes, if any, are to be made there.
1 parent 2a5aeb2 commit 7158e31

37 files changed

+162
-151
lines changed

.gitignore

+6-1
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,14 @@ __pycache__/
66
# C extensions
77
*.so
88

9+
# Virtual environment
10+
env/
11+
.env/
12+
venv/
13+
.venv/
14+
915
# Distribution / packaging
1016
.Python
11-
env/
1217
build/
1318
develop-eggs/
1419
dist/

development.txt

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
black
22
coverage
3+
flake8
4+
isort
35
pandoc
46
pyandoc
57
pytest

docs/conf.py

-3
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
# All configuration values have a default; values that are commented out
1313
# serve to show the default.
1414

15-
import sys
1615
import os
1716

1817
# If extensions (or modules to document with autodoc) are in another directory,
@@ -177,8 +176,6 @@
177176
# If true, the index is split into individual pages for each letter.
178177
# html_split_index = False
179178

180-
import os
181-
182179
on_rtd = os.environ.get("READTHEDOCS", None) == "True"
183180

184181
if not on_rtd: # only import and set the theme if we're building docs locally

python_jsonschema_objects/__init__.py

+13-16
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
__all__ = ["ObjectBuilder", "markdown_support", "ValidationError"]
2+
13
import codecs
24
import copy
35
import json
@@ -10,16 +12,11 @@
1012
import six
1113
from jsonschema import Draft4Validator
1214

13-
import python_jsonschema_objects.classbuilder as classbuilder
14-
import python_jsonschema_objects.markdown_support
15-
import python_jsonschema_objects.util
15+
from python_jsonschema_objects import classbuilder, markdown_support, util
1616
from python_jsonschema_objects.validators import ValidationError
1717

18-
1918
logger = logging.getLogger(__name__)
2019

21-
__all__ = ["ObjectBuilder", "markdown_support", "ValidationError"]
22-
2320
FILE = __file__
2421

2522
SUPPORTED_VERSIONS = (
@@ -110,17 +107,17 @@ def build_classes(self, strict=False, named_only=False, standardize_names=True):
110107
Class names will be transformed using inflection by default, so names
111108
with spaces in the schema will be camelcased, while names without
112109
spaces will have internal capitalization dropped. Thus "Home Address"
113-
becomes "HomeAddress", while "HomeAddress" becomes "Homeaddress" To
114-
disable this behavior, pass standardize_names=False, but be aware
115-
that accessing names with spaces from the namespace can be
116-
problematic.
110+
becomes "HomeAddress", while "HomeAddress" becomes "Homeaddress". To
111+
disable this behavior, pass standardize_names=False, but be aware that
112+
accessing names with spaces from the namespace can be problematic.
117113
118114
Args:
119115
strict: (bool) use this to validate required fields while creating the class
120-
named_only: (bool) If true, only properties with an actual title attribute will
121-
be included in the resulting namespace (although all will be generated).
122-
standardize_names: (bool) If true (the default), class names will be tranformed
123-
by camel casing
116+
named_only: (bool) If true, only properties with an actual title attribute
117+
will be included in the resulting namespace (although all will be
118+
generated).
119+
standardize_names: (bool) If true (the default), class names will be
120+
transformed by camel casing
124121
125122
Returns:
126123
A namespace containing all the generated classes
@@ -129,7 +126,7 @@ def build_classes(self, strict=False, named_only=False, standardize_names=True):
129126
kw = {"strict": strict}
130127
builder = classbuilder.ClassBuilder(self.resolver)
131128
for nm, defn in six.iteritems(self.schema.get("definitions", {})):
132-
uri = python_jsonschema_objects.util.resolve_ref_uri(
129+
uri = util.resolve_ref_uri(
133130
self.resolver.resolution_scope, "#/definitions/" + nm
134131
)
135132
builder.construct(uri, defn, **kw)
@@ -155,7 +152,7 @@ def build_classes(self, strict=False, named_only=False, standardize_names=True):
155152
elif not named_only:
156153
classes[name_transform(uri.split("/")[-1])] = klass
157154

158-
return python_jsonschema_objects.util.Namespace.from_mapping(classes)
155+
return util.Namespace.from_mapping(classes)
159156

160157

161158
if __name__ == "__main__":

python_jsonschema_objects/_version.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,12 @@
1111
"""Git implementation of _version.py."""
1212

1313
import errno
14+
import functools
1415
import os
1516
import re
1617
import subprocess
1718
import sys
1819
from typing import Any, Callable, Dict, List, Optional, Tuple
19-
import functools
2020

2121

2222
def get_keywords() -> Dict[str, str]:

python_jsonschema_objects/classbuilder.py

+17-18
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,22 @@
1-
import python_jsonschema_objects.util as util
2-
import python_jsonschema_objects.validators as validators
3-
import python_jsonschema_objects.pattern_properties as pattern_properties
4-
from python_jsonschema_objects.literals import LiteralValue
5-
6-
import copy
71
import collections
2+
import copy
83
import itertools
9-
import six
4+
import logging
105
import sys
116

12-
import logging
7+
import six
138

14-
import python_jsonschema_objects.wrapper_types
9+
from python_jsonschema_objects import (
10+
pattern_properties,
11+
util,
12+
validators,
13+
wrapper_types,
14+
)
15+
from python_jsonschema_objects.literals import LiteralValue
1516

1617
logger = logging.getLogger(__name__)
17-
1818
logger.addHandler(logging.NullHandler())
1919

20-
2120
# Long is no longer a thing in python3.x
2221
if sys.version_info > (3,):
2322
long = int
@@ -462,7 +461,9 @@ def expand_references(self, source_uri, iterable):
462461
return pp
463462

464463
def resolve_type(self, ref, source):
465-
"""Return a resolved type for a URI, potentially constructing one if necessary"""
464+
"""Return a resolved type for a URI, potentially constructing one if
465+
necessary.
466+
"""
466467
uri = util.resolve_ref_uri(self.resolver.resolution_scope, ref)
467468
if uri in self.resolved:
468469
return self.resolved[uri]
@@ -556,9 +557,7 @@ def _construct(self, uri, clsdata, parent=(ProtocolBase,), **kw):
556557
elif clsdata.get("type") == "array" and "items" in clsdata:
557558
clsdata_copy = {}
558559
clsdata_copy.update(clsdata)
559-
self.resolved[
560-
uri
561-
] = python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
560+
self.resolved[uri] = wrapper_types.ArrayWrapper.create(
562561
uri,
563562
item_constraint=clsdata_copy.pop("items"),
564563
classbuilder=self,
@@ -684,7 +683,7 @@ def _build_object(self, nm, clsdata, parents, **kw):
684683
constraints["strict"] = kw.get("strict")
685684
propdata = {
686685
"type": "array",
687-
"validator": python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
686+
"validator": wrapper_types.ArrayWrapper.create(
688687
nm, item_constraint=typ, **constraints
689688
),
690689
}
@@ -705,7 +704,7 @@ def _build_object(self, nm, clsdata, parents, **kw):
705704
constraints["strict"] = kw.get("strict")
706705
propdata = {
707706
"type": "array",
708-
"validator": python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
707+
"validator": wrapper_types.ArrayWrapper.create(
709708
uri, item_constraint=typ, **constraints
710709
),
711710
}
@@ -716,7 +715,7 @@ def _build_object(self, nm, clsdata, parents, **kw):
716715
constraints["strict"] = kw.get("strict")
717716
propdata = {
718717
"type": "array",
719-
"validator": python_jsonschema_objects.wrapper_types.ArrayWrapper.create(
718+
"validator": wrapper_types.ArrayWrapper.create(
720719
uri, item_constraint=typ, **constraints
721720
),
722721
}

python_jsonschema_objects/descriptors.py

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
from . import validators, util, wrapper_types
2-
from .classbuilder import ProtocolBase, TypeProxy, TypeRef
1+
from python_jsonschema_objects import util, validators, wrapper_types
2+
from python_jsonschema_objects.classbuilder import ProtocolBase, TypeProxy, TypeRef
33

44

55
class AttributeDescriptor(object):
@@ -58,7 +58,7 @@ def __set__(self, obj, val):
5858
ok = True
5959
break
6060
elif util.safe_issubclass(typ, ProtocolBase):
61-
# force conversion- thus the val rather than validator assignment
61+
# Force conversion- thus the val rather than validator assignment.
6262
try:
6363
val = typ(**util.coerce_for_expansion(val))
6464
val.validate()
@@ -80,8 +80,8 @@ def __set__(self, obj, val):
8080
break
8181
elif isinstance(typ, TypeProxy):
8282
try:
83-
# handle keyword expansion according to expected types
84-
# using keywords like oneOf, value can be an object, array or literal
83+
# Handle keyword expansion according to expected types. Using
84+
# keywords like oneOf, value can be an object, array or literal.
8585
val = util.coerce_for_expansion(val)
8686
if isinstance(val, dict):
8787
val = typ(**val)
@@ -106,7 +106,7 @@ def __set__(self, obj, val):
106106
val.validate()
107107

108108
elif util.safe_issubclass(info["type"], wrapper_types.ArrayWrapper):
109-
# An array type may have already been converted into an ArrayValidator
109+
# An array type may have already been converted into an ArrayValidator.
110110
val = info["type"](val)
111111
val.validate()
112112

@@ -115,7 +115,7 @@ def __set__(self, obj, val):
115115
validator = info["type"](val)
116116
validator.validate()
117117
if validator._value is not None:
118-
# This allows setting of default Literal values
118+
# This allows setting of default Literal values.
119119
val = validator
120120

121121
elif util.safe_issubclass(info["type"], ProtocolBase):

python_jsonschema_objects/literals.py

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
from python_jsonschema_objects import util
2-
from python_jsonschema_objects import validators
31
import functools
4-
import logging
5-
import six
62
import operator
73

4+
import six
5+
6+
from python_jsonschema_objects import util, validators
7+
88

99
def MakeLiteral(name, typ, value, **properties):
1010
properties.update({"type": typ})
@@ -76,7 +76,8 @@ def __str__(self):
7676
def validate(self):
7777
info = self.propinfo("__literal__")
7878

79-
# TODO: this duplicates logic in validators.ArrayValidator.check_items; unify it.
79+
# TODO: this duplicates logic in validators.ArrayValidator.check_items;
80+
# unify it.
8081
for param, paramval in sorted(
8182
six.iteritems(info), key=lambda x: x[0].lower() != "type"
8283
):

python_jsonschema_objects/markdown_support.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1+
import re
2+
13
import markdown
24
from markdown.extensions import Extension
35
from markdown.preprocessors import Preprocessor
4-
import re
5-
import json
66

77
try:
88
from markdown import __version_info__ as markdown_version_info

python_jsonschema_objects/pattern_properties.py

+6-11
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
import six
2-
import re
3-
import python_jsonschema_objects.validators as validators
4-
import python_jsonschema_objects.util as util
5-
from python_jsonschema_objects.literals import MakeLiteral
6-
71
import collections
8-
92
import logging
3+
import re
4+
5+
import six
106

11-
import python_jsonschema_objects.wrapper_types
7+
from python_jsonschema_objects import util, validators, wrapper_types
8+
from python_jsonschema_objects.literals import MakeLiteral
129

1310
logger = logging.getLogger(__name__)
1411

@@ -66,9 +63,7 @@ def _make_type(self, typ, val):
6663
if util.safe_issubclass(typ, cb.ProtocolBase):
6764
return typ(**util.coerce_for_expansion(val))
6865

69-
if util.safe_issubclass(
70-
typ, python_jsonschema_objects.wrapper_types.ArrayWrapper
71-
):
66+
if util.safe_issubclass(typ, wrapper_types.ArrayWrapper):
7267
return typ(val)
7368

7469
if isinstance(typ, cb.TypeProxy):

python_jsonschema_objects/util.py

+12-14
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
1-
import six
1+
"""Utility and namespace module."""
2+
3+
__all__ = ["Namespace", "as_namespace"]
4+
25
import copy
36
import json
7+
from collections.abc import Mapping, Sequence
8+
9+
import six
410

511

612
class lazy_format(object):
@@ -22,7 +28,8 @@ def safe_issubclass(x, y):
2228
in the underlying implementation throwing TypeError's from trying to
2329
memoize the result- 'object' isn't a usable weakref target at that level.
2430
Unfortunately this gets exposed all the way up to our code; thus a
25-
'safe' version of the function."""
31+
'safe' version of the function.
32+
"""
2633
try:
2734
return issubclass(x, y)
2835
except TypeError:
@@ -34,16 +41,16 @@ def coerce_for_expansion(mapping):
3441
3542
In py2.7, the value must be a dictionary- thus a as_dict() method
3643
will be invoked if available. In py3k, the raw mapping is returned
37-
unmodified."""
44+
unmodified.
45+
"""
3846
if six.PY2 and hasattr(mapping, "as_dict"):
3947
return mapping.as_dict()
4048
return mapping
4149

4250

4351
class ProtocolJSONEncoder(json.JSONEncoder):
4452
def default(self, obj):
45-
from python_jsonschema_objects import classbuilder
46-
from python_jsonschema_objects import wrapper_types
53+
from python_jsonschema_objects import classbuilder, wrapper_types
4754

4855
if isinstance(obj, classbuilder.LiteralValue):
4956
return obj._value
@@ -112,13 +119,6 @@ def resolve_ref_uri(base, ref):
112119
return uri
113120

114121

115-
"""namespace module"""
116-
117-
__all__ = ("Namespace", "as_namespace")
118-
119-
from collections.abc import Mapping, Sequence
120-
121-
122122
class _Dummy:
123123
pass
124124

@@ -129,12 +129,10 @@ class _Dummy:
129129

130130

131131
class Namespace(dict):
132-
133132
"""A dict subclass that exposes its items as attributes.
134133
135134
Warning: Namespace instances do not have direct access to the
136135
dict methods.
137-
138136
"""
139137

140138
def __init__(self, obj={}):

0 commit comments

Comments
 (0)