Skip to content
This repository was archived by the owner on Nov 3, 2023. It is now read-only.

Commit 2674e27

Browse files
committed
Merge pull request #146 from Nurdok/nested-classes
Handle publicity of nested classes
2 parents 349d9cf + 2aa3618 commit 2674e27

File tree

4 files changed

+47
-4
lines changed

4 files changed

+47
-4
lines changed

docs/release_notes.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,11 @@ New Features
99

1010
* Added support for Python 3.5 (#145).
1111

12+
* Classes nested inside classes are no longer considered private. Nested
13+
classes are considered public if their names are not prepended with an
14+
underscore and if their parent class is public, recursively (#13, #146).
15+
16+
1217
Bug Fixes
1318

1419
* Fixed an issue where a `NameError` was raised when parsing complex defintions

src/pep257.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,7 @@ class Definition(Value):
119119
all = property(lambda self: self.module.all)
120120
_slice = property(lambda self: slice(self.start - 1, self.end))
121121
source = property(lambda self: ''.join(self._source[self._slice]))
122+
is_class = False
122123

123124
def __iter__(self):
124125
return chain([self], *self.children)
@@ -185,11 +186,16 @@ class Class(Definition):
185186

186187
_nest = staticmethod(lambda s: {'def': Method, 'class': NestedClass}[s])
187188
is_public = Function.is_public
189+
is_class = True
188190

189191

190192
class NestedClass(Class):
191193

192-
is_public = False
194+
@property
195+
def is_public(self):
196+
return (not self.name.startswith('_') and
197+
self.parent.is_class and
198+
self.parent.is_public)
193199

194200

195201
class Decorator(Value):
@@ -335,9 +341,9 @@ def parse_decorators(self):
335341
Decorator(''.join(name), ''.join(arguments)))
336342

337343
def parse_definitions(self, class_, all=False):
338-
"""Parse multiple defintions and yield them."""
344+
"""Parse multiple definitions and yield them."""
339345
while self.current is not None:
340-
log.debug("parsing defintion list, current token is %r (%s)",
346+
log.debug("parsing definition list, current token is %r (%s)",
341347
self.current.kind, self.current.value)
342348
if all and self.current.value == '__all__':
343349
self.parse_all()

src/tests/test_cases/nested_class.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
"""A valid module docstring."""
2+
3+
from .expected import Expectation
4+
5+
expectation = Expectation()
6+
expect = expectation.expect
7+
8+
expect('PublicClass', 'D101: Missing docstring in public class')
9+
10+
11+
class PublicClass(object):
12+
13+
expect('PublicNestedClass', 'D101: Missing docstring in public class')
14+
15+
class PublicNestedClass(object):
16+
17+
expect('PublicNestedClassInPublicNestedClass',
18+
'D101: Missing docstring in public class')
19+
20+
class PublicNestedClassInPublicNestedClass(object):
21+
pass
22+
23+
class _PrivateNestedClassInPublicNestedClass(object):
24+
pass
25+
26+
class _PrivateNestedClass(object):
27+
28+
class PublicNestedClassInPrivateNestedClass(object):
29+
pass
30+
31+
class _PrivateNestedClassInPrivateNestedClass(object):
32+
pass

src/tests/test_definitions.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ def test_token_stream():
138138

139139
def test_pep257():
140140
"""Run domain-specific tests from test.py file."""
141-
test_cases = ('test', 'unicode_literals')
141+
test_cases = ('test', 'unicode_literals', 'nested_class')
142142
for test_case in test_cases:
143143
case_module = __import__('test_cases.{0}'.format(test_case),
144144
globals=globals(),

0 commit comments

Comments
 (0)