Bytearray expandtabs #729
Bytearray expandtabs #729
Changes from 2 commits
a35fc97
032a197
6a8c3a6
1e623cd
2c2f95f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
package org.python.types; | ||
|
||
import java.io.ByteArrayOutputStream; | ||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
|
@@ -971,10 +972,70 @@ public org.python.Object endswith(org.python.Object suffix, org.python.Object st | |
} | ||
|
||
@org.python.Method( | ||
__doc__ = "B.expandtabs(tabsize=8) -> copy of B\n\nReturn a copy of B where all tab characters are expanded using spaces.\nIf tabsize is not given, a tab size of 8 characters is assumed." | ||
__doc__ = "B.expandtabs(tabsize=8) -> copy of B\n\nReturn a copy of B where all tab characters are expanded using spaces.\nIf tabsize is not given, a tab size of 8 characters is assumed.", | ||
default_args = {"tabsize"} | ||
) | ||
public org.python.Object expandtabs(java.util.List<org.python.Object> args, java.util.Map<java.lang.String, org.python.Object> kwargs, java.util.List<org.python.Object> default_args, java.util.Map<java.lang.String, org.python.Object> default_kwargs) { | ||
throw new org.python.exceptions.NotImplementedError("bytes.expandtabs has not been implemented."); | ||
public org.python.Object expandtabs(org.python.types.Object tabsize) { | ||
// CPython implementation https://github.com/python/cpython/blob/master/Objects/stringlib/transmogrify.h#L21 | ||
// TODO: check overflows | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What exactly is needed checking here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in the C implementation, it checks for integer overflows. I'm not sure if we should check it here There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, tbh I'm having trouble to follow the logic in this implementation. Maybe you got too much inspiration from the C implementation? =) |
||
|
||
if (this.value == null) { | ||
return null; | ||
} | ||
|
||
if (this.value.length == 0) { | ||
return new org.python.types.Bytes(new byte[0]); | ||
} | ||
|
||
int tabsize_int = 8; | ||
|
||
if (tabsize != null) { | ||
tabsize_int = (int) ((org.python.types.Int) tabsize).value; | ||
} | ||
|
||
|
||
int output_size = 0; | ||
for (int i = 0, j = 0; i < this.value.length; i++) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand what this for loop is accomplishing, could you clarify? It looks like it's meant to compute the output_size, but the code below doesn't seem to be using it in a meaningful way. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ah, I'm sorry about that I've forgotten it from an older version of the code, the C implementation first calculates the size of the output then makes a buffer accordingly, we don't need that now. |
||
byte c = this.value[i]; | ||
|
||
if (c == '\t') { | ||
if (tabsize_int > 0) { | ||
j += (tabsize_int - (j % tabsize_int)); | ||
} | ||
} else { | ||
j++; | ||
|
||
if (c == '\n' || c == '\r') { | ||
output_size += j; | ||
j = 0; | ||
} | ||
} | ||
} | ||
|
||
StringBuilder sb = new StringBuilder(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We should probably not use StringBuilder here -- a Bytes object contains only bytes (8 bits) and is backed by a You should probably just use an ArrayList, initializing it with capacity of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the information, I updated it +1 |
||
|
||
for (int i = 0, j = 0; i < this.value.length; i++) { | ||
byte c = this.value[i]; | ||
|
||
if (c == '\t') { | ||
if (tabsize_int > 0) { | ||
output_size = tabsize_int - (j % tabsize_int); | ||
j += output_size; | ||
while (output_size-- > 0) { | ||
sb.append(' '); | ||
} | ||
} | ||
} else { | ||
j++; | ||
sb.append((char)c); | ||
|
||
if (c == '\n' || c == '\r') { | ||
j = 0; | ||
} | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This conversion from There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Where should I place that new method? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can start by just creating a public static method in this same class. |
||
|
||
return new Bytes(sb.toString()); | ||
} | ||
|
||
@org.python.Method( | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a note that this link's
L21
line number will become outdated as themaster
branch changes – it will be better to link it to a tag (v3.6.4
) or a specific commit, either of which won't change.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's a very neat suggestion -never thought about it this way before-, Thanks! I'll fix it