Hello community,

here is the log from the commit of package python-openpyxl for openSUSE:Factory 
checked in at 2018-01-10 23:38:14
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-openpyxl (Old)
 and      /work/SRC/openSUSE:Factory/.python-openpyxl.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-openpyxl"

Wed Jan 10 23:38:14 2018 rev:7 rq:563264 version:2.4.9

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-openpyxl/python-openpyxl.changes  
2017-08-28 15:15:00.918851304 +0200
+++ /work/SRC/openSUSE:Factory/.python-openpyxl.new/python-openpyxl.changes     
2018-01-10 23:38:14.823355564 +0100
@@ -1,0 +2,22 @@
+Wed Jan 10 10:13:52 UTC 2018 - [email protected]
+
+- update to 2.4.9:
+  + Bugfixes
+    * #809 Incomplete documentation of copy_worksheet method
+    * #811 Scoped definedNames not removed when worksheet is deleted
+    * #824 Raise an exception if a chart is used in multiple sheets
+    * #842 Non-ASCII table column headings cause an exception in Python 2
+    * #846 Conditional formats not supported in write-only mode
+    * #849 Conditional formats with no sqref cause an exception
+    * #859 Headers that start with a number conflict with font size
+    * #902 TableStyleElements don’t always have a condtional format
+    * #908 Read-only mode sometimes returns too many cells
+  + Pull requests
+    * #179 Cells kept in a set
+    * #180 Support for Workbook protection
+    * #182 Read support for page breaks
+    * #183 Improve documentation of copy_worksheet method
+    * #198 Fix for #908
+- updated summary
+
+-------------------------------------------------------------------
@@ -61 +83 @@
-    * Potential XXE vulerability
+    * Potential XXE vulerability (CVE-2017-5992 boo#1025592)

Old:
----
  openpyxl-2.4.8.tar.gz

New:
----
  openpyxl-2.4.9.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-openpyxl.spec ++++++
--- /var/tmp/diff_new_pack.8CEmUm/_old  2018-01-10 23:38:15.347330982 +0100
+++ /var/tmp/diff_new_pack.8CEmUm/_new  2018-01-10 23:38:15.351330795 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package python-openpyxl
 #
-# Copyright (c) 2017 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -18,9 +18,9 @@
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
 Name:           python-openpyxl
-Version:        2.4.8
+Version:        2.4.9
 Release:        0
-Summary:        A Python library to read/write Excel 2007 xlsx/xlsm files
+Summary:        A Python library to read/write Excel 2010 xlsx/xlsm files
 License:        MIT and Python-2.0
 Group:          Development/Languages/Python
 Url:            http://openpyxl.readthedocs.org

++++++ openpyxl-2.4.8.tar.gz -> openpyxl-2.4.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/AUTHORS.rst 
new/openpyxl-2.4.9/AUTHORS.rst
--- old/openpyxl-2.4.8/AUTHORS.rst      2017-03-16 19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/AUTHORS.rst      2017-10-19 14:24:20.000000000 +0200
@@ -61,6 +61,7 @@
 * James Smagala
 * Wolfgane Scherer
 * Joseph Tate
+* Gar Thompson
 * Dieter Vandenbussche
 * Paul Van Der Linden
 * Gerald Van Huffelen
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/PKG-INFO new/openpyxl-2.4.9/PKG-INFO
--- old/openpyxl-2.4.8/PKG-INFO 2017-05-30 19:33:09.000000000 +0200
+++ new/openpyxl-2.4.9/PKG-INFO 2017-10-19 14:24:46.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: openpyxl
-Version: 2.4.8
+Version: 2.4.9
 Summary: A Python library to read/write Excel 2010 xlsx/xlsm files
 Home-page: https://openpyxl.readthedocs.io
 Author: See AUTHORS
 Author-email: [email protected]
 License: MIT/Expat
+Description-Content-Type: UNKNOWN
 Description: openpyxl
         ========
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/.constants.json 
new/openpyxl-2.4.9/openpyxl/.constants.json
--- old/openpyxl-2.4.8/openpyxl/.constants.json 2017-05-30 19:32:53.000000000 
+0200
+++ new/openpyxl-2.4.9/openpyxl/.constants.json 2017-10-19 14:24:20.000000000 
+0200
@@ -4,5 +4,5 @@
     "__license__": "MIT/Expat",
     "__maintainer_email__": "[email protected]",
     "__url__": "https://openpyxl.readthedocs.io";,
-    "__version__": "2.4.8"
+    "__version__": "2.4.9"
 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/cell/read_only.py 
new/openpyxl-2.4.9/openpyxl/cell/read_only.py
--- old/openpyxl-2.4.8/openpyxl/cell/read_only.py       2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/cell/read_only.py       2017-10-19 
14:24:20.000000000 +0200
@@ -45,6 +45,10 @@
     def __ne__(self, other):
         return not self.__eq__(other)
 
+
+    def __repr__(self):
+        return "<ReadOnlyCell {0!r}.{1}>".format(self.parent.title, 
self.coordinate)
+
     @property
     def shared_strings(self):
         return self.parent.shared_strings
@@ -145,4 +149,7 @@
     data_type = 'n'
 
 
+    def __repr__(self):
+        return "<EmptyCell>"
+
 EMPTY_CELL = EmptyCell()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/formatting/formatting.py 
new/openpyxl-2.4.9/openpyxl/formatting/formatting.py
--- old/openpyxl-2.4.8/openpyxl/formatting/formatting.py        2017-05-30 
19:20:53.000000000 +0200
+++ new/openpyxl-2.4.9/openpyxl/formatting/formatting.py        2017-10-19 
14:24:20.000000000 +0200
@@ -18,7 +18,7 @@
 
     tagname = "conditionalFormatting"
 
-    sqref = String()
+    sqref = String(allow_none=True)
     pivot = Bool(allow_none=True)
     cfRule = Sequence(expected_type=Rule)
     rules = Alias("cfRule")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/packaging/workbook.py 
new/openpyxl-2.4.9/openpyxl/packaging/workbook.py
--- old/openpyxl-2.4.8/openpyxl/packaging/workbook.py   2017-05-30 
19:20:53.000000000 +0200
+++ new/openpyxl-2.4.9/openpyxl/packaging/workbook.py   2017-10-19 
14:24:20.000000000 +0200
@@ -66,6 +66,8 @@
             package.definedNames._cleanup()
             self.wb.defined_names = package.definedNames
 
+        self.wb.security = package.workbookProtection
+
 
     def find_sheets(self):
         """
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/reader/worksheet.py 
new/openpyxl-2.4.9/openpyxl/reader/worksheet.py
--- old/openpyxl-2.4.8/openpyxl/reader/worksheet.py     2017-05-30 
19:20:53.000000000 +0200
+++ new/openpyxl-2.4.9/openpyxl/reader/worksheet.py     2017-10-19 
14:24:20.000000000 +0200
@@ -23,6 +23,7 @@
 from openpyxl.worksheet.hyperlink import Hyperlink
 from openpyxl.worksheet.merge import MergeCells
 from openpyxl.worksheet.page import PageMargins, PrintOptions, PrintPageSetup
+from openpyxl.worksheet.pagebreak import PageBreak
 from openpyxl.worksheet.protection import SheetProtection
 from openpyxl.worksheet.views import SheetViewList
 from openpyxl.worksheet.datavalidation import DataValidationList
@@ -112,7 +113,8 @@
             #'{%s}sheet/{%s}sortState' % (SHEET_MAIN_NS, SHEET_MAIN_NS): 
('sort_state', SortState),
             '{%s}sheetPr' % SHEET_MAIN_NS: ('sheet_properties', 
WorksheetProperties),
             '{%s}sheetViews' % SHEET_MAIN_NS: ('views', SheetViewList),
-            '{%s}sheetFormatPr' % SHEET_MAIN_NS: ('sheet_format', 
SheetFormatProperties)
+            '{%s}sheetFormatPr' % SHEET_MAIN_NS: ('sheet_format', 
SheetFormatProperties),
+            '{%s}rowBreaks' % SHEET_MAIN_NS: ('page_breaks', PageBreak),
         }
 
         tags = dispatcher.keys()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/styles/table.py 
new/openpyxl-2.4.9/openpyxl/styles/table.py
--- old/openpyxl-2.4.8/openpyxl/styles/table.py 2017-05-30 19:14:29.000000000 
+0200
+++ new/openpyxl-2.4.9/openpyxl/styles/table.py 2017-10-19 14:24:20.000000000 
+0200
@@ -15,6 +15,8 @@
 
 class TableStyleElement(Serialisable):
 
+    tagname = "tableStyleElement"
+
     type = Set(values=(['wholeTable', 'headerRow', 'totalRow', 'firstColumn',
                         'lastColumn', 'firstRowStripe', 'secondRowStripe', 
'firstColumnStripe',
                         'secondColumnStripe', 'firstHeaderCell', 
'lastHeaderCell',
@@ -25,7 +27,7 @@
                         'thirdColumnSubheading', 'firstRowSubheading', 
'secondRowSubheading',
                         'thirdRowSubheading', 'pageFieldLabels', 
'pageFieldValues']))
     size = Integer(allow_none=True)
-    dxfId = Integer()
+    dxfId = Integer(allow_none=True)
 
     def __init__(self,
                  type=None,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/utils/cell.py 
new/openpyxl-2.4.9/openpyxl/utils/cell.py
--- old/openpyxl-2.4.8/openpyxl/utils/cell.py   2017-05-30 19:20:53.000000000 
+0200
+++ new/openpyxl-2.4.9/openpyxl/utils/cell.py   2017-10-19 14:24:20.000000000 
+0200
@@ -57,13 +57,19 @@
 def absolute_coordinate(coord_string):
     """Convert a coordinate to an absolute coordinate string (B12 -> $B$12)"""
     m = ABSOLUTE_RE.match(coord_string.upper())
-    if m:
-        if all(m.groups()[-2:]):
-            fmt =  "${0}${1}:${3}${4}"
-        else:
-            fmt = "${0}${1}"
-        return fmt.format(*m.groups())
-    raise ValueError("Value is not a valid coordinate range")
+    if not m:
+        raise ValueError("Value is not a valid coordinate range")
+
+    d = m.groupdict('')
+    for k, v in d.items():
+        if v:
+            d[k] = "${0}".format(v)
+
+    if d['max_col'] or d['max_row']:
+        fmt =  "{min_col}{min_row}:{max_col}{max_row}"
+    else:
+        fmt = "{min_col}{min_row}"
+    return fmt.format(**d)
 
 
 def _get_column_letter(col_idx):
@@ -198,7 +204,10 @@
     """
     Add quotes around sheetnames if they contain spaces.
     """
+    if "'" in sheetname:
+        sheetname = sheetname.replace("'", "''")
     if (" " in sheetname
-        or "-" in sheetname):
+        or "-" in sheetname
+        or "'" in sheetname):
         sheetname = u"'{0}'".format(sheetname)
     return sheetname
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/utils/exceptions.py 
new/openpyxl-2.4.9/openpyxl/utils/exceptions.py
--- old/openpyxl-2.4.8/openpyxl/utils/exceptions.py     2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/utils/exceptions.py     2017-10-19 
14:24:20.000000000 +0200
@@ -8,25 +8,32 @@
 class CellCoordinatesException(Exception):
     """Error for converting between numeric and A1-style cell references."""
 
+
 class IllegalCharacterError(Exception):
     """The data submitted which cannot be used directly in Excel files. It
     must be removed or escaped."""
 
+
 class NamedRangeException(Exception):
     """Error for badly formatted named ranges."""
 
+
 class SheetTitleException(Exception):
     """Error for bad sheet names."""
 
+
 class InsufficientCoordinatesException(Exception):
     """Error for partially specified cell coordinates."""
 
+
 class InvalidFileException(Exception):
     """Error for trying to open a non-ooxml file."""
 
+
 class ReadOnlyWorkbookException(Exception):
     """Error for trying to modify a read-only workbook"""
 
+
 class WorkbookAlreadySaved(Exception):
     """Error when attempting to perform operations on a dump workbook
     while it has already been dumped once"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/utils/protection.py 
new/openpyxl-2.4.9/openpyxl/utils/protection.py
--- old/openpyxl-2.4.8/openpyxl/utils/protection.py     1970-01-01 
01:00:00.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/utils/protection.py     2017-10-19 
14:24:20.000000000 +0200
@@ -0,0 +1,23 @@
+from __future__ import absolute_import
+# Copyright (c) 2010-2017 openpyxl
+
+
+def hash_password(plaintext_password=''):
+    """
+    Create a password hash from a given string for protecting a worksheet
+    only. This will not work for encrypting a workbook.
+
+    This method is based on the algorithm provided by
+    Daniel Rentz of OpenOffice and the PEAR package
+    Spreadsheet_Excel_Writer by Xavier Noguer <[email protected]>.
+    See also 
http://blogs.msdn.com/b/ericwhite/archive/2008/02/23/the-legacy-hashing-algorithm-in-open-xml.aspx
+    """
+    password = 0x0000
+    for idx, char in enumerate(plaintext_password, 1):
+        value = ord(char) << idx
+        rotated_bits = value >> 15
+        value &= 0x7fff
+        password ^= (value | rotated_bits)
+    password ^= len(plaintext_password)
+    password ^= 0xCE4B
+    return str(hex(password)).upper()[2:]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/workbook/defined_name.py 
new/openpyxl-2.4.9/openpyxl/workbook/defined_name.py
--- old/openpyxl-2.4.8/openpyxl/workbook/defined_name.py        2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/workbook/defined_name.py        2017-10-19 
14:24:20.000000000 +0200
@@ -252,3 +252,10 @@
             if defn.name == name and defn.localSheetId == scope:
                 del self.definedName[idx]
                 return True
+
+
+    def localnames(self, scope):
+        """
+        Provide a list of all names for a particular worksheet
+        """
+        return [defn.name for defn in self.definedName if defn.localSheetId == 
scope]
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/workbook/protection.py 
new/openpyxl-2.4.9/openpyxl/workbook/protection.py
--- old/openpyxl-2.4.8/openpyxl/workbook/protection.py  2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/workbook/protection.py  2017-10-19 
14:24:20.000000000 +0200
@@ -19,16 +19,17 @@
     Relation,
     Base64Binary,
 )
+from openpyxl.utils.protection import hash_password
 
 
 class WorkbookProtection(Serialisable):
 
+    _workbook_password, _revisions_password = None, None
+
     tagname = "workbookPr"
 
-    workbookPassword = HexBinary(allow_none=True)
     workbook_password = Alias("workbookPassword")
     workbookPasswordCharacterSet = String(allow_none=True)
-    revisionsPassword = HexBinary(allow_none=True)
     revision_password = Alias("revisionsPassword")
     revisionsPasswordCharacterSet = String(allow_none=True)
     lockStructure = Bool(allow_none=True)
@@ -46,6 +47,12 @@
     workbookSaltValue = Base64Binary(allow_none=True)
     workbookSpinCount = Integer(allow_none=True)
 
+    __attrs__ = ('workbookPassword', 'workbookPasswordCharacterSet', 
'revisionsPassword',
+                 'revisionsPasswordCharacterSet', 'lockStructure', 
'lockWindows', 'lockRevision',
+                 'revisionsAlgorithmName', 'revisionsHashValue', 
'revisionsSaltValue',
+                 'revisionsSpinCount', 'workbookAlgorithmName', 
'workbookHashValue',
+                 'workbookSaltValue', 'workbookSpinCount')
+
     def __init__(self,
                  workbookPassword=None,
                  workbookPasswordCharacterSet=None,
@@ -63,9 +70,11 @@
                  workbookSaltValue=None,
                  workbookSpinCount=None,
                 ):
-        self.workbookPassword = workbookPassword
+        if workbookPassword is not None:
+            self.workbookPassword = workbookPassword
         self.workbookPasswordCharacterSet = workbookPasswordCharacterSet
-        self.revisionsPassword = revisionsPassword
+        if revisionsPassword is not None:
+            self.revisionsPassword = revisionsPassword
         self.revisionsPasswordCharacterSet = revisionsPasswordCharacterSet
         self.lockStructure = lockStructure
         self.lockWindows = lockWindows
@@ -79,6 +88,47 @@
         self.workbookSaltValue = workbookSaltValue
         self.workbookSpinCount = workbookSpinCount
 
+    def set_workbook_password(self, value='', already_hashed=False):
+        """Set a password on this workbook."""
+        if not already_hashed:
+            value = hash_password(value)
+        self._workbook_password = value
+
+    @property
+    def workbookPassword(self):
+        """Return the workbook password value, regardless of hash."""
+        return self._workbook_password
+
+    @workbookPassword.setter
+    def workbookPassword(self, value):
+        """Set a workbook password directly, forcing a hash step."""
+        self.set_workbook_password(value)
+
+    def set_revisions_password(self, value='', already_hashed=False):
+        """Set a revision password on this workbook."""
+        if not already_hashed:
+            value = hash_password(value)
+        self._revisions_password = value
+
+    @property
+    def revisionsPassword(self):
+        """Return the revisions password value, regardless of hash."""
+        return self._revisions_password
+
+    @revisionsPassword.setter
+    def revisionsPassword(self, value):
+        """Set a revisions password directly, forcing a hash step."""
+        self.set_revisions_password(value)
+
+    @classmethod
+    def from_tree(cls, node):
+        """Don't hash passwords when deserialising from XML"""
+        self = super(WorkbookProtection, cls).from_tree(node)
+        if self.workbookPassword:
+            self.set_workbook_password(node.get('workbookPassword'), 
already_hashed=True)
+        if self.revisionsPassword:
+            self.set_revisions_password(node.get('revisionsPassword'), 
already_hashed=True)
+        return self
 
 # Backwards compatibility
 DocumentSecurity = WorkbookProtection
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/workbook/workbook.py 
new/openpyxl-2.4.9/openpyxl/workbook/workbook.py
--- old/openpyxl-2.4.8/openpyxl/workbook/workbook.py    2017-05-30 
19:20:53.000000000 +0200
+++ new/openpyxl-2.4.9/openpyxl/workbook/workbook.py    2017-10-19 
14:24:20.000000000 +0200
@@ -178,6 +178,10 @@
 
     def remove(self, worksheet):
         """Remove a worksheet from this workbook."""
+        idx = self._sheets.index(worksheet)
+        localnames = self.defined_names.localnames(scope=idx)
+        for name in localnames:
+            self.defined_names.delete(name, scope=idx)
         self._sheets.remove(worksheet)
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/worksheet/datavalidation.py 
new/openpyxl-2.4.9/openpyxl/worksheet/datavalidation.py
--- old/openpyxl-2.4.8/openpyxl/worksheet/datavalidation.py     2017-05-30 
19:20:53.000000000 +0200
+++ new/openpyxl-2.4.9/openpyxl/worksheet/datavalidation.py     2017-10-19 
14:24:20.000000000 +0200
@@ -65,7 +65,7 @@
     cells = []
     for rs in range_string.split():
         cells.extend(rows_from_range(rs))
-    return list(chain.from_iterable(cells))
+    return set(chain.from_iterable(cells))
 
 
 class DataValidation(Serialisable):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/worksheet/header_footer.py 
new/openpyxl-2.4.9/openpyxl/worksheet/header_footer.py
--- old/openpyxl-2.4.8/openpyxl/worksheet/header_footer.py      2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/worksheet/header_footer.py      2017-10-19 
14:24:20.000000000 +0200
@@ -24,7 +24,7 @@
 
 FONT_PATTERN = '&"(?P<font>.+)"'
 COLOR_PATTERN  = "&K(?P<color>[A-F0-9]{6})"
-SIZE_REGEX = r"&(?P<size>\d+)"
+SIZE_REGEX = r"&(?P<size>\d+\s?)"
 FORMAT_REGEX = re.compile("{0}|{1}|{2}".format(FONT_PATTERN, COLOR_PATTERN,
                                                SIZE_REGEX)
                           )
@@ -106,7 +106,7 @@
         if self.font:
             fmt.append(u'&"{0}"'.format(self.font))
         if self.size:
-            fmt.append("&{0}".format(self.size))
+            fmt.append("&{0} ".format(self.size))
         if self.color:
             fmt.append("&K{0}".format(self.color))
         return u"".join(fmt + [self.text])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/worksheet/protection.py 
new/openpyxl-2.4.9/openpyxl/worksheet/protection.py
--- old/openpyxl-2.4.8/openpyxl/worksheet/protection.py 2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/worksheet/protection.py 2017-10-19 
14:24:20.000000000 +0200
@@ -12,27 +12,7 @@
     HexBinary,
     Base64Binary,
 )
-
-
-def hash_password(plaintext_password=''):
-    """
-    Create a password hash from a given string for protecting a worksheet
-    only. This will not work for encrypting a workbook.
-
-    This method is based on the algorithm provided by
-    Daniel Rentz of OpenOffice and the PEAR package
-    Spreadsheet_Excel_Writer by Xavier Noguer <[email protected]>.
-    See also 
http://blogs.msdn.com/b/ericwhite/archive/2008/02/23/the-legacy-hashing-algorithm-in-open-xml.aspx
-    """
-    password = 0x0000
-    for idx, char in enumerate(plaintext_password, 1):
-        value = ord(char) << idx
-        rotated_bits = value >> 15
-        value &= 0x7fff
-        password ^= (value | rotated_bits)
-    password ^= len(plaintext_password)
-    password ^= 0xCE4B
-    return str(hex(password)).upper()[2:]
+from openpyxl.utils.protection import hash_password
 
 
 class _Protected(object):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/worksheet/read_only.py 
new/openpyxl-2.4.9/openpyxl/worksheet/read_only.py
--- old/openpyxl-2.4.8/openpyxl/worksheet/read_only.py  2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/worksheet/read_only.py  2017-10-19 
14:24:20.000000000 +0200
@@ -180,7 +180,7 @@
             col_counter = column + 1
 
         if max_col is not None:
-            for _ in range(col_counter, max_col+1):
+            for _ in range(max(min_col, col_counter), max_col+1):
                 yield EMPTY_CELL
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/writer/excel.py 
new/openpyxl-2.4.9/openpyxl/writer/excel.py
--- old/openpyxl-2.4.8/openpyxl/writer/excel.py 2017-05-30 19:20:53.000000000 
+0200
+++ new/openpyxl-2.4.9/openpyxl/writer/excel.py 2017-10-19 14:24:20.000000000 
+0200
@@ -9,6 +9,7 @@
 from zipfile import ZipFile, ZIP_DEFLATED
 
 # package imports
+from openpyxl.utils.exceptions import InvalidFileException
 from openpyxl.xml.constants import (
     ARC_SHARED_STRINGS,
     ARC_CONTENT_TYPES,
@@ -122,6 +123,8 @@
 
     def _write_charts(self):
         # delegate to object
+        if len(self._charts) != len(set(self._charts)):
+            raise InvalidFileException("The same chart cannot be used in more 
than one worksheet")
         for chart in self._charts:
             self._archive.writestr(chart.path[1:], tostring(chart._write()))
             self.manifest.append(chart)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/writer/workbook.py 
new/openpyxl-2.4.9/openpyxl/writer/workbook.py
--- old/openpyxl-2.4.8/openpyxl/writer/workbook.py      2017-05-30 
19:20:53.000000000 +0200
+++ new/openpyxl-2.4.9/openpyxl/writer/workbook.py      2017-10-19 
14:24:20.000000000 +0200
@@ -87,6 +87,9 @@
         props.date1904 = True
     root.workbookPr = props
 
+    # workbook protection
+    root.workbookProtection = wb.security
+
     # book views
     active = get_active_sheet(wb)
     view = BookView(activeTab=active)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/writer/worksheet.py 
new/openpyxl-2.4.9/openpyxl/writer/worksheet.py
--- old/openpyxl-2.4.8/openpyxl/writer/worksheet.py     2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/writer/worksheet.py     2017-10-19 
14:24:20.000000000 +0200
@@ -10,6 +10,7 @@
 # package imports
 from openpyxl.xml.functions import xmlfile
 from openpyxl.xml.constants import SHEET_MAIN_NS
+from openpyxl.compat import unicode
 
 from openpyxl.styles.differential import DifferentialStyle
 from openpyxl.packaging.relationship import Relationship, RelationshipList
@@ -185,7 +186,7 @@
                 for cell, col in zip(row, table.tableColumns):
                     if cell.data_type != "s":
                         warn("File may not be readable: column headings must 
be strings.")
-                    col.name = str(cell.value)
+                    col.name = unicode(cell.value)
         rel = Relationship(type=table._rel_type, Target="")
         ws._rels.append(rel)
         table._rel_id = rel.Id
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl/writer/write_only.py 
new/openpyxl-2.4.9/openpyxl/writer/write_only.py
--- old/openpyxl-2.4.8/openpyxl/writer/write_only.py    2017-03-16 
19:05:43.000000000 +0100
+++ new/openpyxl-2.4.9/openpyxl/writer/write_only.py    2017-10-19 
14:24:20.000000000 +0200
@@ -21,7 +21,7 @@
 
 from .etree_worksheet import write_cell
 from .excel import ExcelWriter
-from .worksheet import write_drawing
+from .worksheet import write_drawing, write_conditional_formatting
 from openpyxl.xml.constants import SHEET_MAIN_NS
 from openpyxl.xml.functions import xmlfile, Element
 
@@ -191,6 +191,11 @@
                 if self.sort_state.ref:
                     xf.write(self.sort_state.to_tree())
 
+                if self.conditional_formatting:
+                    cfs = write_conditional_formatting(self)
+                    for cf in cfs:
+                        xf.write(cf)
+
                 if self.data_validations.count:
                     xf.write(self.data_validations.to_tree())
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl.egg-info/PKG-INFO 
new/openpyxl-2.4.9/openpyxl.egg-info/PKG-INFO
--- old/openpyxl-2.4.8/openpyxl.egg-info/PKG-INFO       2017-05-30 
19:33:08.000000000 +0200
+++ new/openpyxl-2.4.9/openpyxl.egg-info/PKG-INFO       2017-10-19 
14:24:45.000000000 +0200
@@ -1,11 +1,12 @@
 Metadata-Version: 1.1
 Name: openpyxl
-Version: 2.4.8
+Version: 2.4.9
 Summary: A Python library to read/write Excel 2010 xlsx/xlsm files
 Home-page: https://openpyxl.readthedocs.io
 Author: See AUTHORS
 Author-email: [email protected]
 License: MIT/Expat
+Description-Content-Type: UNKNOWN
 Description: openpyxl
         ========
         
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/openpyxl-2.4.8/openpyxl.egg-info/SOURCES.txt 
new/openpyxl-2.4.9/openpyxl.egg-info/SOURCES.txt
--- old/openpyxl-2.4.8/openpyxl.egg-info/SOURCES.txt    2017-05-30 
19:33:08.000000000 +0200
+++ new/openpyxl-2.4.9/openpyxl.egg-info/SOURCES.txt    2017-10-19 
14:24:45.000000000 +0200
@@ -131,6 +131,7 @@
 openpyxl/utils/exceptions.py
 openpyxl/utils/formulas.py
 openpyxl/utils/indexed_list.py
+openpyxl/utils/protection.py
 openpyxl/utils/units.py
 openpyxl/workbook/__init__.py
 openpyxl/workbook/child.py


Reply via email to