Hello community, here is the log from the commit of package python-dbf for openSUSE:Factory checked in at 2019-03-26 22:31:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-dbf (Old) and /work/SRC/openSUSE:Factory/.python-dbf.new.25356 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-dbf" Tue Mar 26 22:31:27 2019 rev:3 rq:686453 version:0.98.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-dbf/python-dbf.changes 2018-12-13 19:47:43.732756532 +0100 +++ /work/SRC/openSUSE:Factory/.python-dbf.new.25356/python-dbf.changes 2019-03-26 22:31:39.249716909 +0100 @@ -1,0 +2,9 @@ +Tue Mar 19 15:01:20 UTC 2019 - Tomáš Chvátal <[email protected]> + +- Update to 0.98.0: + * fix resize_field to work on empty tables + * fix export to fixed-width by using codecs.open + * allow non-standard characters in field names (with warnings) +- Run tests + +------------------------------------------------------------------- Old: ---- dbf-0.97.11.tar.gz New: ---- dbf-0.98.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-dbf.spec ++++++ --- /var/tmp/diff_new_pack.VqqlpQ/_old 2019-03-26 22:31:41.101716462 +0100 +++ /var/tmp/diff_new_pack.VqqlpQ/_new 2019-03-26 22:31:41.101716462 +0100 @@ -1,7 +1,7 @@ # # spec file for package python-dbf # -# Copyright (c) 2018 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2019 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,16 +18,20 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-dbf -Version: 0.97.11 +Version: 0.98.0 Release: 0 Summary: Pure python package for reading/writing dBase, FoxPro, and Visual FoxPro .dbf License: BSD-3-Clause Group: Development/Languages/Python -URL: https://bitbucket.org/stoneleaf/dbf/src/default/ +URL: https://pypi.org/project/dbf/ Source: https://files.pythonhosted.org/packages/source/d/dbf/dbf-%{version}.tar.gz +BuildRequires: %{python_module aenum} +BuildRequires: %{python_module pytz} BuildRequires: %{python_module setuptools} BuildRequires: fdupes BuildRequires: python-rpm-macros +Requires: python-aenum +Requires: python-pytz BuildArch: noarch %python_subpackages @@ -49,6 +53,9 @@ %python_install %python_expand %fdupes %{buildroot}%{$python_sitelib} +%check +%python_expand PYTHONPATH=%{buildroot}%{$python_sitelib} $python dbf/test.py + %files %{python_files} %license dbf/LICENSE %{python_sitelib}/dbf-%{version}-py*.egg-info ++++++ dbf-0.97.11.tar.gz -> dbf-0.98.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dbf-0.97.11/PKG-INFO new/dbf-0.98.0/PKG-INFO --- old/dbf-0.97.11/PKG-INFO 2018-06-06 03:54:52.000000000 +0200 +++ new/dbf-0.98.0/PKG-INFO 2019-03-16 01:39:55.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: dbf -Version: 0.97.11 +Version: 0.98.0 Summary: Pure python package for reading/writing dBase, FoxPro, and Visual FoxPro .dbf files (including memos) Home-page: https://pypi.python.org/pypi/dbf Author: Ethan Furman diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dbf-0.97.11/dbf/LICENSE new/dbf-0.98.0/dbf/LICENSE --- old/dbf-0.97.11/dbf/LICENSE 2018-06-06 03:38:23.000000000 +0200 +++ new/dbf-0.98.0/dbf/LICENSE 2019-03-16 01:38:25.000000000 +0100 @@ -1,4 +1,4 @@ -Copyright (c) 2008-2018 Ethan Furman +Copyright (c) 2008-2019 Ethan Furman All rights reserved. Redistribution and use in source and binary forms, with or without diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dbf-0.97.11/dbf/WHATSNEW new/dbf-0.98.0/dbf/WHATSNEW --- old/dbf-0.97.11/dbf/WHATSNEW 1970-01-01 01:00:00.000000000 +0100 +++ new/dbf-0.98.0/dbf/WHATSNEW 2019-03-16 01:38:25.000000000 +0100 @@ -0,0 +1,409 @@ +What's New +========== + +0.98.000 +-------- + +fix resize_field to work on empty tables +fix export to fixed-width by using codecs.open +allow non-standard characters in field names (with warnings) + + +0.97.011 +-------- + +allow '00000000' as a null date in dbf files + + +0.97.010 +-------- + +fixed nullable-field access in vfp tables + + +0.97.009 +-------- + +allow tzinfo addition/change in DateTime.combine() +fix strptime for Time +hook into datetime.datetime and .date equality comparisons + + +0.97.008 +-------- + +Marshalling a DateTime now works + + +0.97.007 +-------- + +add pytz support to Time and DateTime +Marshalling a DateTime sends as UTC if possible + + +0.97.004 +-------- + +Fix bug in VFP doubles + + +0.97.003 +-------- + +Fix field creation flag handling +Allow (redundant) "binary" flag on binary type fields + + +0.97.002 +-------- + +Fix fp/FoxBase table header creation + + +0.97.001 +-------- + +Can now open dbf files as read-only when lacking write permissions. + + +0.97.000 +-------- + +Moved to a single 2/3 code base. +Opening a database now defaults to dbf.READ_ONLY; can also use dbf.READ_WRITE; +the corresponding strings are no longer supported. + + +0.96.008 +-------- + +Handle vfp_double with decimal (Foxpro uses it for display purposes) + (thanks, Joshua Adelman!) + + +0.96.007 +-------- + +rev: 168 rename tests to test + + +0.96.006 +-------- + +restore pql + + +0.96.005 +-------- + +fix create_backup to use the active codepage, which may be different from +the table's codepage + + +0.96.004 +-------- + +change duplicate NUMERIC to FLOAT +add Float fields to tests +change from_csv to write directly to disk if to_disk requested +fix erronious access to _dirty in RecordTemplate + + +0.96.003 +-------- + +add 'basestring' to ver_2.py +add 'basestring' to ver_2.py + + +0.96.000 +-------- + +add support for Python 3 +convert from module to package layout +remove pql +fix Time and DateTime signatures: microsec --> microseconds +fix Time and DateTime .now() to truncate microseconds past thousands + + +0.95.014 +-------- + +use a sparse container for the table -- should make very large dbf files usable + + +0.95.013 +-------- + +Null fields properly ignored if table doesn't support it + + +0.95.012 +-------- + +adjust setup.py to require enum34 + +add custom data types to xmlrpclib.Marshaller (marshalled as the underlying +type) + +add support for storing numbers as scientific notation + +fixed DateTime.now() and Time.now() to only return milliseconds + + +0.95.008 +-------- + +fix Period.__contains__ + +add new default_data_type to Table.__init__ of 'enhanced' which selects all +the custom data types (Char, Logical, Date, DateTime) + +add string input type to Date, Time, and DateTime + + +0.95.007 +-------- + +Add .fromfloat() to Time + +Add .tofloat() to Time + +Add Period for matching various time periods + + +0.95.006 +-------- + +Add .format() and .replace() to Date, Time, and DateTime + +Add nesting to Table context manager + +Add enumerations IsoDay, RelativeDay, IsoMonth, RelativeMonth + + +0.95.003 +-------- + +Fixed issue with incorrect memo size in base file (thanks, Glenn!) + +Memo file extensions now have the same casing as the dbf file's, and are +searched for that way (thanks again, Glenn!) + + +0.95.002 +-------- + +Fixed the version number in this file for the last release. :/ + +string slices now work for RecordTemplate + + +0.95.001 +-------- + +Miscellaneous bugs squashed. + +backup tables are created in the same location as the original table if TMP, +TEMP, nor DBF_TEMP are defined in the environment + +delete() and undelete() now support RecordTemplate + +Process() and Templates() now support start, stop, and filter to allow finer +control of which records will be returned. + +Added Relation, which makes linking two tables together on a common field easier. +Not persistent. + +xBase-Compatibility Break: added utf8 codepage (xf0). + +Backwards-Compatibility Break: reverted Logical.__eq__ to return True if Logical +is True, False otherwise; this properly mimics the behavior of using True/False/None +directly. If the previous behavior is desired, use Quantum instead (it uses the +states On/Off/Other), or use `if some_var is Unknown: ... ; elif some_var ... ; else ... `. + +Many thanks to all who have helped with ideas and bug fixes. + + +0.94.004 +-------- + +Templates now use same (custom) data types as table they are created +from. + +Added Index.index_search(match, start=None, stop=None, nearest=False, partial=False) +which returns the index of the first match. If nearest is False and nothing is found +a NotFoundError is raised, otherwise the index of where the match would be is +returned + +Added IndexLocation, which is a subclass of long and is returned by Index.index_search. +Unlike normal numbers where 0 == False and anything else == True, IndexLocation is True if +the number represents a found match, and False if the number represents where a match +should be (a False value will only be returned if nearest == True). + +Backwards-Compatibility Break: memory-only tables are now specified with on_disk=True +instead of bracketing the filename with ':'. Removed dbf.codepage() and dbf.encoding() +as users can directly access dbf.default_codepage and dbf.input_decoding. + +Backwards-Compatibility Break: .use_deleted no longer used (it disappeared sometime +between .90.0 and now). Rationale: the deleted flag is just that: a flag. The record is +still present and still available. If you don't want to use it, either check if the +record has been deleted (dbf.is_deleted(record)) or create an index that doesn't include +the deleted records... or pack the table and actually remove the records for good. + + +0.94.003 +-------- + +Minor bug fixes, more documentation. + + +0.94.001 +-------- + +Added support for Clipper's large Character fields (up to 65,519) + +More code clean-up and slight breakage:: + + - _Dbf* has had '_Dbf' removed (_DbfRecord --> Record) + - DbfTable --> Table (Table factory function removed) + + +0.94.000 +-------- + +Massive backwards incompatible changes. + +export() method removed from Tables and made into a normal function. + +All non-underscore methods removed from the record class and made into +normal functions:: + + - delete_record --> delete + - field_names --> field_names + - gather_records --> gather + - has_been_deleted --> is_deleted + - record_number --> recno + - reset_record --> reset + - scatter_records --> scatter + - undelete_record --> undelete + - write_record --> write + +Transaction methods removed entirely. + +Can use strings as start/stop of slices: `record['name':'age']` + +Record templates now exist, and are much like records except that they are +not directly tied to a table and can be freely modified. They can be created +by either the `dbf.create_template` function or the `table.create_template` method. + +scatter() now returns a RecordTemplate instead of a dict, but the as_type parameter +can be used to get dicts (or tuples, lists, whatever) + + +0.93.020 +-------- + Finished changes so other Python implementations should work (PyPy + definitely does). + + Table signature changed -- `read_only`, `meta_only`, and `keep_memos` + dropped. + + tables now have a `status` attribute which will be one of `closed`, + 'read_only`, or `read_write` + + `.append` no longer returns the newly added record (use table[-1] if you need it) + `.find` method removed (use `.query` instead); + `.sql` method removed (use `.query` instead); + `.size` renamed to `.field_size`; + `.type` renamed to `.field_type` (which returns a FieldType named tuple); + + the way to change records has changed: + + to update any/all fields at once: + record.write_record(field1=..., field2=...) + + or + + record.gather_fields(dict) + + to update one field at a time: + 2.6, 2.7 (2.5 using `from __future__ import with_statement`) + with record: + record.field1 = ... + record.field2 = ... + + or + + for record in dbf.Process(table | records): + record.field1 = ... + record.field2 = ... + + attempting to change a field outside of these two methods will raise a + `DbfError`. + + Changing behavior based on a transaction: + + record.gather_fields() + + if a transaction is not running this will write to disk + (no changes made if error occurs, exception reraised) + + if a transaction is running, and an error occurs, the calling code + is responsible for calling .rollback_transaction() or otherwise + handling the problem (exception is reraised) + + record.reset_record() + + if a transaction is not running the changes are written to disk + + if a transaction is running the changes are not written to disk + + `xxx in table` and `xxx in record` used to be a field-name check - it is + now a record / value check; use `xxx in table.field_names` and + `xxx in record.field_names` to do the field-name check. + + added equality/inequality check for records, which can be compared against + other records / dicts / tuples (field/key order does not matter for + record-record nor record-dict checks). + + +0.93.011 +-------- + `with` will work now. Really. + + Started making changes so dbf will work with the non-CPython + implementations (at this point it is not reliable). + + +0.93.010 +-------- + Table now returns a closed database; .open() must now be called before + accessing the records. + Note: fields, number of records, table type, and other metadata is + available on closed tables. + + Finished adding support for 'F' (aka 'N') field types in dBase III tables; + this is a practicality beats purity issue as the F type is not part of the + db3 standard, but is exactly the same as N and other programs will use it + instead of N when creating db3 tables. + + +0.93.000 +-------- + PEP 8 changes (yo --> self, someMethod --> some_method) + + +0.92.002 +-------- + added more support for the Null type in the other custome data types + + +0.91.001 +-------- + Removed __del__ from dbf records; consequently they no longer autosave when + going out of scope. Either call .write_record() explicitly, or use the new + Write iterator which will call .write_record for you. + + Finished adding Null support (not supported in db3 tables) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dbf-0.97.11/dbf/__init__.py new/dbf-0.98.0/dbf/__init__.py --- old/dbf-0.97.11/dbf/__init__.py 2018-06-06 03:38:23.000000000 +0200 +++ new/dbf-0.98.0/dbf/__init__.py 2019-03-16 01:38:25.000000000 +0100 @@ -41,6 +41,8 @@ import struct import sys import time +import traceback +import warnings import weakref from array import array @@ -72,7 +74,7 @@ long = int xrange = range -version = 0, 97, 11 +version = 0, 98, 0 NoneType = type(None) @@ -841,6 +843,8 @@ def __init__(self): DbfWarning.__init__(self, self.message) +class FieldNameWarning(UserWarning): + message = 'non-standard characters in field name' # wrappers around datetime and logical objects to allow null values @@ -5502,7 +5506,9 @@ meta = self._meta if meta.status != READ_WRITE: raise DbfError('%s not in read/write mode, unable to add fields (%s)' % (meta.filename, meta.status)) - fields = self.structure() + self._list_fields(field_specs, sep=u';') + fields = self.structure() + original_fields = len(fields) + fields += self._list_fields(field_specs, sep=u';') null_fields = any(['null' in f.lower() for f in fields]) if (len(fields) + null_fields) > meta.max_fields: raise DbfError( @@ -5526,7 +5532,7 @@ meta.blankrecord = None null_index = -1 - for field in fields: + for field_seq, field in enumerate(fields): if not field: continue field = field.lower() @@ -5545,8 +5551,15 @@ break except IndexError: raise FieldSpecError('bad field spec: %r' % field) - if name[0] == '_' or name[0].isdigit() or not name.replace('_', '').isalnum(): - raise FieldSpecError("%s invalid: field names must start with a letter, and can only contain letters, digits, and _" % name) + if field_seq >= original_fields and (name[0] == '_' or name[0].isdigit() or not name.replace('_', '').isalnum()): + # find appropriate line to point warning to + for i, frame in enumerate(reversed(traceback.extract_stack()), start=1): + if frame[0] == __file__ and frame[2] == 'resize_field': + # ignore + break + elif frame[0] != __file__ or frame[2] not in ('__init__','add_fields'): + warnings.warn('"%s invalid: field names should start with a letter, and only contain letters, digits, and _' % name, FieldNameWarning, stacklevel=i) + break if name in meta.fields: raise DbfError("Field '%s' already exists" % name) field_type = format @@ -6010,6 +6023,7 @@ raise DbfError("field %s not in table -- resize aborted" % candidate) elif self.field_info(candidate).field_type != FieldType.CHAR: raise DbfError("field %s is not Character -- resize aborted" % candidate) + old_table = None if self: old_table = self.create_backup() self.zap() @@ -8401,7 +8415,7 @@ fields.append(unicode(data)) fd.write('\t'.join(fields) + '\n') else: # format == 'fixed' - with open("%s_layout.txt" % os.path.splitext(filename)[0], 'w', encoding=encoding) as header: + with codecs.open("%s_layout.txt" % os.path.splitext(filename)[0], 'w', encoding=encoding) as header: header.write("%-15s Size\n" % "Field Name") header.write("%-15s ----\n" % ("-" * 15)) sizes = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dbf-0.97.11/dbf/test.py new/dbf-0.98.0/dbf/test.py --- old/dbf-0.97.11/dbf/test.py 2018-06-06 03:38:23.000000000 +0200 +++ new/dbf-0.98.0/dbf/test.py 2019-03-16 01:38:25.000000000 +0100 @@ -2755,6 +2755,22 @@ table.close() +class TestWarnings(TestCase): + + def test_field_name_warning(self): + with warnings.catch_warnings(record=True) as w: + huh = dbf.Table('cloud', 'p^type C(25)', on_disk=False).open(dbf.READ_WRITE) + self.assertEqual(len(w), 1, str(w)) + warning = w[-1] + self.assertTrue(issubclass(warning.category, dbf.FieldNameWarning)) + huh.resize_field('p^type', 30) + self.assertEqual(len(w), 1, 'warning objects\n'+'\n'.join([str(warning) for warning in w])) + huh.add_fields('c^word C(50)') + self.assertEqual(len(w), 2, str(w)) + warning = w[-1] + self.assertTrue(issubclass(warning.category, dbf.FieldNameWarning)) + + class TestIndexLocation(TestCase): def test_false(self): @@ -3695,6 +3711,10 @@ def setUp(self): "create a dbf and vfp table" + self.empty_dbf_table = Table( + os.path.join(tempdir, 'emptytemptable'), + 'name C(25); paid L; qty N(11,5); orderdate D; desc M', dbf_type='db3' + ) self.dbf_table = table = Table( os.path.join(tempdir, 'temptable'), 'name C(25); paid L; qty N(11,5); orderdate D; desc M', dbf_type='db3' @@ -3719,6 +3739,14 @@ table.append({'name':name, 'paid':paid, 'qty':qty, 'orderdate':orderdate, 'desc':desc}) table.close() + self.empty_vfp_table = Table( + os.path.join(tempdir, 'emptytempvfp'), + 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' + ' weight F(18,3); age I; meeting T; misc G; photo P; price Y;' + ' dist B binary; atom I binary; wealth Y binary;' + , + dbf_type='vfp', + ) self.vfp_table = table = Table( os.path.join(tempdir, 'tempvfp'), 'name C(25); paid L; qty N(11,5); orderdate D; desc M; mass B;' @@ -4495,6 +4523,13 @@ for j in index(table.field_names): self.assertEqual(str(table[i][j]).strip(), csvtable[i][j].strip()) + def test_resize_empty(self): + "resize" + table = self.empty_dbf_table + table.open(mode=READ_WRITE) + table.resize_field('name', 40) + table.close() + def test_resize(self): "resize" table = self.dbf_table diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dbf-0.97.11/dbf.egg-info/PKG-INFO new/dbf-0.98.0/dbf.egg-info/PKG-INFO --- old/dbf-0.97.11/dbf.egg-info/PKG-INFO 2018-06-06 03:54:52.000000000 +0200 +++ new/dbf-0.98.0/dbf.egg-info/PKG-INFO 2019-03-16 01:39:55.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: dbf -Version: 0.97.11 +Version: 0.98.0 Summary: Pure python package for reading/writing dBase, FoxPro, and Visual FoxPro .dbf files (including memos) Home-page: https://pypi.python.org/pypi/dbf Author: Ethan Furman diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dbf-0.97.11/dbf.egg-info/SOURCES.txt new/dbf-0.98.0/dbf.egg-info/SOURCES.txt --- old/dbf-0.97.11/dbf.egg-info/SOURCES.txt 2018-06-06 03:54:52.000000000 +0200 +++ new/dbf-0.98.0/dbf.egg-info/SOURCES.txt 2019-03-16 01:39:55.000000000 +0100 @@ -1,6 +1,7 @@ setup.py dbf/LICENSE dbf/README.md +dbf/WHATSNEW dbf/__init__.py dbf/_index.py dbf/test.py diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dbf-0.97.11/setup.py new/dbf-0.98.0/setup.py --- old/dbf-0.97.11/setup.py 2018-06-06 03:38:23.000000000 +0200 +++ new/dbf-0.98.0/setup.py 2019-03-16 01:38:25.000000000 +0100 @@ -21,7 +21,7 @@ data = dict( name='dbf', - version='0.97.11', + version='0.98.0', license='BSD License', description='Pure python package for reading/writing dBase, FoxPro, and Visual FoxPro .dbf files (including memos)', long_description=long_desc, @@ -31,6 +31,7 @@ 'dbf' : [ 'LICENSE', 'README.md', + 'WHATSNEW', ] }, provides=['dbf'],
